diff options
830 files changed, 19427 insertions, 49402 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1 index e2d9f88..d4fb4e9 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -15,7 +15,7 @@ # -DNO_PORTSUPDATE do not update ports in ${MAKE} update # -DNO_ROOT install without using root privilege # -DNO_DOCUPDATE do not update doc in ${MAKE} update -# -DNO_CTF do not run the DTrace CTF conversion tools on built objects +# -DWITHOUT_CTF do not run the DTrace CTF conversion tools on built objects # LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list # LOCAL_LIB_DIRS="list of dirs" to add additional dirs to libraries target # LOCAL_MTREE="list of mtree files" to process to allow local directories @@ -58,6 +58,7 @@ # use that new version. And the new (dynamically-linked) /bin/sh # will expect to find appropriate libraries in /lib and /libexec. # +SRCDIR?= ${.CURDIR} .if defined(SUBDIR_OVERRIDE) SUBDIR= ${SUBDIR_OVERRIDE} .else @@ -84,6 +85,9 @@ SUBDIR+=secure SUBDIR+=share .endif SUBDIR+=sys usr.bin usr.sbin +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif .if ${MK_OFED} != "no" SUBDIR+=contrib/ofed .endif @@ -128,11 +132,14 @@ OSRELDATE= 0 .endif .if !defined(VERSION) -VERSION!= uname -srp -VERSION+= ${OSRELDATE} +REVISION!= ${MAKE} -C ${SRCDIR}/release -V REVISION +BRANCH!= ${MAKE} -C ${SRCDIR}/release -V BRANCH +SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ + ${SRCDIR}/sys/sys/param.h +VERSION= FreeBSD ${REVISION}-${BRANCH:C/-p[0-9]+$//} ${TARGET_ARCH} ${SRCRELDATE} .endif -KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64 +KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm armv6hf/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64 .if ${TARGET} == ${TARGET_ARCH} _t= ${TARGET} .else @@ -224,22 +231,24 @@ CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \ GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \ GROFF_TMAC_PATH=${WORLDTMP}/legacy/usr/share/tmac .endif +.if defined(TARGET_CFLAGS) +CROSSENV+= ${TARGET_CFLAGS} +.endif # bootstrap-tools stage BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} \ VERSION="${VERSION}" \ - MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ - COMPILER_TYPE=${COMPILER_TYPE} + MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ - -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \ - -DNO_PIC -DNO_PROFILE -DNO_SHARED \ - -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD + MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \ + -DNO_PIC MK_PROFILE=no -DNO_SHARED \ + -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ @@ -249,12 +258,26 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DNO_LINT \ - -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD + -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ - -DWITHOUT_GDB + MK_GDB=no MK_TESTS=no + +# kernel-tools stage +KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ + PATH=${BPATH}:${PATH} \ + WORLDTMP=${WORLDTMP} \ + VERSION="${VERSION}" +KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ + ${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ + DESTDIR= \ + BOOTSTRAPPING=${OSRELDATE} \ + SSP_CFLAGS= \ + MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \ + -DNO_PIC MK_PROFILE=no -DNO_SHARED \ + -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD # world stage WMAKEENV= ${CROSSENV} \ @@ -271,7 +294,7 @@ HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT .endif .if ${MK_CDDL} == "no" -WMAKEENV+= NO_CTF=1 +WMAKEENV+= MK_CTF=no .endif .if defined(CROSS_TOOLCHAIN_PREFIX) @@ -299,17 +322,6 @@ WMAKEENV+= CC="${XCC} ${XFLAGS}" CXX="${XCXX} ${XFLAGS}" \ AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \ OBJDUMP=${XOBJDUMP} RANLIB=${XRANLIB} STRINGS=${XSTRINGS} -.if ${XCC:T:Mgcc} == "gcc" -WMAKE_COMPILER_TYPE= gcc -.elif ${XCC:T:Mclang} == "clang" -WMAKE_COMPILER_TYPE= clang -.elif ${MK_CLANG_IS_CC} == "no" -WMAKE_COMPILER_TYPE= gcc -.else -WMAKE_COMPILER_TYPE= clang -.endif -IMAKE_COMPILER_TYPE= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} - .if ${XCC:M/*} XFLAGS= --sysroot=${WORLDTMP} .if defined(CROSS_BINUTILS_PREFIX) @@ -322,19 +334,18 @@ XFLAGS+= -B${CROSS_BINUTILS_PREFIX} .else XFLAGS+= -B${WORLDTMP}/usr/bin .endif -.if ${TARGET_ARCH} != ${MACHINE_ARCH} && ${WMAKE_COMPILER_TYPE} == "clang" -.if (${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "armv6") && \ -${MK_ARM_EABI} != "no" +.if ${TARGET} == "arm" && ${MK_ARM_EABI} != "no" +.if ${TARGET_ARCH:M*eb*} == "" TARGET_ABI= gnueabi -.else -TARGET_ABI= unknown +.elif ${TARGET_ARCH} == "armv6hf" +TARGET_ABI= gnueabihf .endif +.endif +TARGET_ABI?= unknown TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd11.0 XFLAGS+= -target ${TARGET_TRIPLE} .endif -.endif -WMAKEENV+= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP} .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" @@ -382,27 +393,26 @@ LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \ PATH=${TMPPATH} \ LIBDIR=/usr/lib32 \ SHLIBDIR=/usr/lib32 \ - LIBPRIVATEDIR=/usr/lib32/private \ - COMPILER_TYPE=${WMAKE_COMPILER_TYPE} -LIB32WMAKEFLAGS+= \ - CC="${XCC} ${LIB32FLAGS}" \ + LIBPRIVATEDIR=/usr/lib32/private +LIB32WMAKEFLAGS+= CC="${XCC} ${LIB32FLAGS}" \ CXX="${XCXX} ${LIB32FLAGS}" \ DESTDIR=${LIB32TMP} \ -DCOMPAT_32BIT \ -DLIBRARIES_ONLY \ -DNO_CPU_CFLAGS \ - -DNO_CTF \ - -DNO_LINT + MK_CTF=no \ + -DNO_LINT \ + MK_TESTS=no LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \ - -DWITHOUT_MAN -DWITHOUT_INFO -DWITHOUT_HTML -LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} -DNO_INCS \ - ${IMAKE_INSTALL} + MK_MAN=no MK_INFO=no MK_HTML=no +LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} \ + MK_TOOLCHAIN=no ${IMAKE_INSTALL} .endif IMAKEENV= ${CROSSENV:N_LDSCRIPTROOT=*} IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \ - ${IMAKE_INSTALL} ${IMAKE_MTREE} ${IMAKE_COMPILER_TYPE} + ${IMAKE_INSTALL} ${IMAKE_MTREE} .if empty(.MAKEFLAGS:M-n) IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \ LD_LIBRARY_PATH=${INSTALLTMP} \ @@ -425,7 +435,7 @@ MTREEFLAGS+= -W .endif .if defined(DB_FROM_SRC) || defined(NO_ROOT) IMAKE_INSTALL= INSTALL="install ${INSTALLFLAGS}" -IMAKE_MTREE= MTREE_CMD="nmtree ${MTREEFLAGS}" +IMAKE_MTREE= MTREE_CMD="mtree ${MTREEFLAGS}" .endif # kernel stage @@ -485,6 +495,10 @@ _worldtmp: mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/usr/lib >/dev/null .endif +.if ${MK_TESTS} != "no" + mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ + -p ${WORLDTMP}/usr >/dev/null +.endif .for _mtree in ${LOCAL_MTREE} mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null .endfor @@ -529,6 +543,7 @@ _cross-tools: @echo ">>> stage 3: cross tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools + ${_+_}cd ${.CURDIR}; ${XMAKE} kernel-tools _includes: @echo @echo "--------------------------------------------------------------" @@ -541,8 +556,8 @@ _libraries: @echo ">>> stage 4.2: building libraries" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; \ - ${WMAKE} -DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \ - -DWITHOUT_MAN -DNO_PROFILE libraries + ${WMAKE} -DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \ + MK_PROFILE=no MK_TESTS=no libraries _depend: @echo @echo "--------------------------------------------------------------" @@ -594,7 +609,7 @@ build32: WORLDTMP=${WORLDTMP} \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \ - DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF \ + DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no \ -DEARLY_BUILD build-tools .endfor cd ${.CURDIR}; \ @@ -737,14 +752,10 @@ _install-info= install-info _zoneinfo= zic tzsetup .endif -.if exists(/usr/sbin/nmtree) -_nmtree_itools= nmtree -.endif - ITOOLS= [ awk cap_mkdb cat chflags chmod chown \ date echo egrep find grep id install ${_install-info} \ - ln lockf make mkdir mtree ${_nmtree_itools} mv pwd_mkdb \ - rm sed sh sysctl test true uname wc ${_zoneinfo} + ln lockf make mkdir mtree mv pwd_mkdb \ + rm sed services_mkdb sh sysctl test true uname wc ${_zoneinfo} # # distributeworld @@ -806,11 +817,11 @@ distributeworld installworld: _installcheck_world -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null .endif .if defined(NO_ROOT) - ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \ + ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \ sed -e 's#^\./#./${dist}/#' >> ${METALOG} - ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \ + ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \ sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG} - ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \ + ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \ sed -e 's#^\./#./${dist}/usr/include/#' >> ${METALOG} .endif .endfor @@ -963,6 +974,8 @@ INSTALLKERNEL= ${_kernel} .endif .endfor +buildkernel ${WMAKE_TGTS} ${.ALLTARGETS:M_*}: .MAKE + # # buildkernel # @@ -988,7 +1001,7 @@ buildkernel: cd ${KRNLCONFDIR}; \ PATH=${TMPPATH} \ config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} \ - ${KERNCONFDIR}/${_kernel} + -I ${KERNCONFDIR} ${KERNCONFDIR}/${_kernel} .endif .if !defined(NO_CLEAN) && !defined(NO_KERNELCLEAN) @echo @@ -1008,20 +1021,7 @@ buildkernel: @echo "--------------------------------------------------------------" @echo ">>> stage 2.3: build tools" @echo "--------------------------------------------------------------" - cd ${KRNLOBJDIR}/${_kernel}; \ - PATH=${BPATH}:${PATH} \ - MAKESRCPATH=${KERNSRCDIR}/dev/aic7xxx/aicasm \ - ${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS -DNO_CTF -DEARLY_BUILD \ - -f ${KERNSRCDIR}/dev/aic7xxx/aicasm/Makefile -# XXX - Gratuitously builds aicasm in the ``makeoptions NO_MODULES'' case. -.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists(${KERNSRCDIR}/modules) -.for target in obj depend all - cd ${KERNSRCDIR}/modules/aic7xxx/aicasm; \ - PATH=${BPATH}:${PATH} \ - MAKEOBJDIRPREFIX=${KRNLOBJDIR}/${_kernel}/modules \ - ${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS -DNO_CTF -DEARLY_BUILD ${target} -.endfor -.endif + ${_+_}cd ${.CURDIR}; ${KTMAKE} kernel-tools .if !defined(NO_KERNELDEPEND) @echo @echo "--------------------------------------------------------------" @@ -1159,8 +1159,8 @@ update: # legacy: Build compatibility shims for the next three targets # legacy: -.if ${BOOTSTRAPPING} < 700055 && ${BOOTSTRAPPING} != 0 - @echo "ERROR: Source upgrades from versions prior to 7.0 not supported."; \ +.if ${BOOTSTRAPPING} < 800107 && ${BOOTSTRAPPING} != 0 + @echo "ERROR: Source upgrades from versions prior to 8.0 not supported."; \ false .endif .for _tool in tools/build @@ -1188,14 +1188,6 @@ _gperf= gnu/usr.bin/gperf _groff= gnu/usr.bin/groff .endif -.if ${BOOTSTRAPPING} < 800022 -_ar= usr.bin/ar -.endif - -.if ${BOOTSTRAPPING} < 800013 -_mklocale= usr.bin/mklocale -.endif - .if ${BOOTSTRAPPING} < 900002 _sed= usr.bin/sed .endif @@ -1234,7 +1226,9 @@ _awk= usr.bin/awk _gensnmptree= usr.sbin/bsnmpd/gensnmptree .endif -.if ${MK_CLANG} != "no" +# We need to build tlbgen 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= \ lib/clang/libllvmsupport \ lib/clang/libllvmtablegen \ @@ -1251,7 +1245,7 @@ _dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf lib/libelf \ lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge .endif -# Default to building the BSDL DTC, but build the GPL one if users explicitly +# Default to building the GPL DTC, but build the BSDL one if users explicitly # request it. _dtc= usr.bin/dtc .if ${MK_GPL_DTC} != "no" @@ -1279,13 +1273,11 @@ bootstrap-tools: .MAKE ${_strfile} \ ${_gperf} \ ${_groff} \ - ${_ar} \ ${_dtc} \ ${_awk} \ ${_cat} \ usr.bin/lorder \ usr.bin/makewhatis \ - ${_mklocale} \ usr.bin/rpcgen \ ${_sed} \ ${_yacc} \ @@ -1308,10 +1300,6 @@ bootstrap-tools: .MAKE # # build-tools: Build special purpose build tools # -.if defined(MODULES_WITH_WORLD) && exists(${KERNSRCDIR}/modules) -_aicasm= sys/modules/aic7xxx/aicasm -.endif - .if !defined(NO_SHARE) _share= share/syscons/scrnmaps .endif @@ -1333,7 +1321,6 @@ build-tools: .MAKE lib/ncurses/ncurses \ lib/ncurses/ncursesw \ ${_share} \ - ${_aicasm} \ usr.bin/awk \ lib/libmagic \ usr.bin/mkesdb_static \ @@ -1354,9 +1341,20 @@ build-tools: .MAKE .endfor # +# kernel-tools: Build kernel-building tools +# +kernel-tools: .MAKE + mkdir -p ${MAKEOBJDIRPREFIX}/usr + mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ + -p ${MAKEOBJDIRPREFIX}/usr >/dev/null + +# # cross-tools: Build cross-building tools # -.if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${BOOTSTRAPPING} < 800035 +.if !defined(TARGET_ARCH) && defined(XDEV_ARCH) +TARGET_ARCH= ${XDEV_ARCH} +.endif +.if ${TARGET_ARCH} != ${MACHINE_ARCH} .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" _btxld= usr.sbin/btxld .endif @@ -1370,19 +1368,19 @@ _kgzip= usr.sbin/kgzip .endif .endif -.if ${XAS:M/*} == "" && ${MK_BINUTILS} != "no" +# If we're given an XAS, don't build binutils. +.if ${XAS:M/*} == "" && ${MK_BINUTILS_BOOTSTRAP} != "no" _binutils= gnu/usr.bin/binutils .endif # If an full path to an external cross compiler is given, don't build # a cross compiler. .if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no" -.if ${MK_CLANG} != "no" && (${MK_CLANG_IS_CC} != "no" || ${CC:T:Mclang} == "clang") +.if ${MK_CLANG_BOOTSTRAP} != "no" _clang= usr.bin/clang _clang_libs= lib/clang .endif - -.if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98") +.if ${MK_GCC_BOOTSTRAP} != "no" _cc= gnu/usr.bin/cc .endif .endif @@ -1446,11 +1444,13 @@ _startup_libs+= lib/csu/${MACHINE_CPUARCH} _startup_libs+= gnu/lib/libgcc _startup_libs+= lib/libcompiler_rt _startup_libs+= lib/libc +_startup_libs+= lib/libc_nonshared .if ${MK_LIBCPLUSPLUS} != "no" _startup_libs+= lib/libcxxrt .endif gnu/lib/libgcc__L: lib/libc__L +gnu/lib/libgcc__L: lib/libc_nonshared__L .if ${MK_LIBCPLUSPLUS} != "no" lib/libcxxrt__L: gnu/lib/libgcc__L .endif @@ -1464,22 +1464,31 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \ ${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \ ${_kerberos5_lib_libroken} \ ${_kerberos5_lib_libwind} \ - ${_lib_atf_libatf_c} \ + ${_lib_atf} \ lib/libbz2 ${_libcom_err} lib/libcrypt \ lib/libelf lib/libexpat \ - ${_lib_libgssapi} ${_lib_libipx} \ - lib/libkiconv lib/libkvm lib/liblzma lib/libmd \ + ${_lib_libgssapi} \ + lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \ + ${_lib_libcapsicum} \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam ${_lib_libthr} \ lib/libradius lib/libsbuf lib/libtacplus \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ ${_cddl_lib_libzfs_core} \ - lib/libutil ${_lib_libypclnt} lib/libz lib/msun \ + lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_lib_libldns} \ ${_secure_lib_libssh} ${_secure_lib_libssl} +.if ${MK_GNUCXX} != "no" && ${MK_CXX} != "no" +_prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++ +.endif -.if ${MK_ATF} != "no" -_lib_atf_libatf_c= lib/atf/libatf-c +.if defined(WITH_ATF) || ${MK_TESTS} != "no" +.if !defined(WITH_ATF) +# Ensure that the ATF libraries will be built during make libraries, even +# though they will have WITHOUT_TESTS +MAKE+= -DWITH_ATF +.endif +_lib_atf= lib/atf .endif .if ${MK_LIBTHR} != "no" @@ -1490,6 +1499,13 @@ _lib_libthr= lib/libthr _ofed_lib= contrib/ofed/usr.lib/ .endif +.if ${MK_CASPER} != "no" +_lib_libcapsicum=lib/libcapsicum +.endif + +lib/libcapsicum__L: lib/libnv__L +lib/libpjdlog__L: lib/libutil__L + _generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib} .for _DIR in ${LOCAL_LIB_DIRS} .if exists(${.CURDIR}/${_DIR}/Makefile) @@ -1556,10 +1572,6 @@ kerberos5/lib/libheimsqlite__L: lib/libthr__L _lib_libgssapi= lib/libgssapi .endif -.if ${MK_IPX} != "no" -_lib_libipx= lib/libipx -.endif - .if ${MK_KERBEROS} != "no" _kerberos5_lib= kerberos5/lib _kerberos5_lib_libasn1= kerberos5/lib/libasn1 @@ -1588,10 +1600,12 @@ ${_lib}__PL: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_lib} && \ - ${MAKE} DIRPRFX=${_lib}/ obj && \ - ${MAKE} DIRPRFX=${_lib}/ depend && \ - ${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ all && \ - ${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ install + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj && \ + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ depend && \ + ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ + DIRPRFX=${_lib}/ all && \ + ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ + DIRPRFX=${_lib}/ install .endif .endfor @@ -1600,10 +1614,10 @@ ${_lib}__L: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_lib} && \ - ${MAKE} DIRPRFX=${_lib}/ obj && \ - ${MAKE} DIRPRFX=${_lib}/ depend && \ - ${MAKE} DIRPRFX=${_lib}/ all && \ - ${MAKE} DIRPRFX=${_lib}/ install + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj && \ + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ depend && \ + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ all && \ + ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ install .endif .endfor @@ -1613,10 +1627,12 @@ ${_lib}__L: .PHONY .MAKE lib/libpam__L: .PHONY .MAKE ${_+_}@${ECHODIR} "===> lib/libpam (obj,depend,all,install)"; \ cd ${.CURDIR}/lib/libpam && \ - ${MAKE} DIRPRFX=lib/libpam/ obj && \ - ${MAKE} DIRPRFX=lib/libpam/ depend && \ - ${MAKE} DIRPRFX=lib/libpam/ -D_NO_LIBPAM_SO_YET all && \ - ${MAKE} DIRPRFX=lib/libpam/ -D_NO_LIBPAM_SO_YET install + ${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ obj && \ + ${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ depend && \ + ${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \ + -D_NO_LIBPAM_SO_YET all && \ + ${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \ + -D_NO_LIBPAM_SO_YET install _prereq_libs: ${_prereq_libs:S/$/__PL/} _startup_libs: ${_startup_libs:S/$/__L/} @@ -1672,6 +1688,7 @@ delete-old-files: # argument list will get too long. Using .for/.endfor make "loops" will make # the Makefile parser segfault. @exec 3<&0; \ + cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ @@ -1694,7 +1711,8 @@ delete-old-files: check-old-files: @echo ">>> Checking for old files" - @${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ + @cd ${.CURDIR}; \ + ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ @@ -1715,6 +1733,7 @@ delete-old-libs: @echo ">>> Removing old libraries" @echo "${OLD_LIBS_MESSAGE}" | fmt @exec 3<&0; \ + cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ @@ -1722,22 +1741,36 @@ delete-old-libs: chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ rm ${RM_I} "${DESTDIR}/$${file}" <&3; \ fi; \ + for ext in debug symbols; do \ + if ! [ -e "${DESTDIR}/$${file}" ] && [ -f \ + "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ + rm ${RM_I} "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" \ + <&3; \ + fi; \ + done; \ done @echo ">>> Old libraries removed" check-old-libs: @echo ">>> Checking for old libraries" - @${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ + @cd ${.CURDIR}; \ + ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ echo "${DESTDIR}/$${file}"; \ fi; \ + for ext in debug symbols; do \ + if [ -f "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ + echo "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}"; \ + fi; \ + done; \ done delete-old-dirs: @echo ">>> Removing old directories" - @${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ + @cd ${.CURDIR}; \ + ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | sort -r | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ @@ -1750,7 +1783,8 @@ delete-old-dirs: check-old-dirs: @echo ">>> Checking for old directories" - @${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ + @cd ${.CURDIR}; \ + ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ @@ -1799,7 +1833,7 @@ builddtb: echo "ERROR: FDT_DTS_FILE must be specified!"; \ exit 1; \ fi; \ - if [ ! -f ${.CURDIR}/sys/boot/fdt/dts/${FDT_DTS_FILE} ]; then \ + if [ ! -f ${.CURDIR}/sys/boot/fdt/dts/${MACHINE}/${FDT_DTS_FILE} ]; then \ echo "ERROR: Specified DTS file (${FDT_DTS_FILE}) does not \ exist!"; \ exit 1; \ @@ -1809,9 +1843,9 @@ builddtb: directory"; \ fi @PATH=${TMPPATH} \ - dtc -O dtb -o \ - ${DTBOUTPUTPATH}/`echo ${FDT_DTS_FILE} | cut -d. -f1`.dtb -b 0 \ - -p 1024 ${.CURDIR}/sys/boot/fdt/dts/${FDT_DTS_FILE} + ${.CURDIR}/sys/tools/fdt/make_dtb.sh ${.CURDIR}/sys \ + ${FDT_DTS_FILE} \ + ${DTBOUTPUTPATH}/`basename ${FDT_DTS_FILE} .dts` ############### @@ -1823,28 +1857,34 @@ XDEV_CPUTYPE?=${CPUTYPE} XDEV_CPUTYPE?=${TARGET_CPUTYPE} .endif -NOFUN=-DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \ - -DWITHOUT_MAN -DWITHOUT_NLS -DNO_PROFILE \ - -DWITHOUT_KERBEROS -DWITHOUT_RESCUE -DNO_WARNS \ +NOFUN=-DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT \ + MK_MAN=no MK_NLS=no MK_PROFILE=no \ + MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no -DNO_WARNS \ TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \ CPUTYPE=${XDEV_CPUTYPE} XDDIR=${XDEV_ARCH}-freebsd -XDTP=/usr/${XDDIR} +XDTP?=/usr/${XDDIR} +.if ${XDTP:N/*} +.error XDTP variable should be an absolute path +.endif + CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \ INSTALL="sh ${.CURDIR}/tools/install.sh" CDENV= ${CDBENV} \ _SHLIBDIRPREFIX=${XDDESTDIR} \ - TOOLS_PREFIX=${XDDESTDIR} + TOOLS_PREFIX=${XDTP} CD2CFLAGS=-isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib \ - -B${XDDESTDIR}/usr/lib -CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" \ + --sysroot=${XDDESTDIR}/ -B${XDDESTDIR}/usr/libexec \ + -B${XDDESTDIR}/usr/bin -B${XDDESTDIR}/usr/lib +CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" CXX="${CXX} ${CD2CFLAGS}" \ + CPP="${CPP} ${CD2CFLAGS}" \ MACHINE=${XDEV} MACHINE_ARCH=${XDEV_ARCH} CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN} -CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDTP}/usr/bin:${PATH} ${MAKE} ${NOFUN} -XDDESTDIR=${DESTDIR}${XDTP} +CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} ${MAKE} ${NOFUN} +XDDESTDIR=${DESTDIR}/${XDTP} .if !defined(OSREL) OSREL!= uname -r | sed -e 's/[-(].*//' .endif @@ -1877,11 +1917,11 @@ _xb-build-tools: _xb-cross-tools: .for _tool in \ - gnu/usr.bin/binutils \ - gnu/usr.bin/cc \ + ${_binutils} \ usr.bin/ar \ ${_clang_libs} \ - ${_clang} + ${_clang} \ + ${_cc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,depend,all)"; \ cd ${.CURDIR}/${_tool} && \ ${CDMAKE} DIRPRFX=${_tool}/ obj && \ @@ -1905,10 +1945,11 @@ xdev-install: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries _x _xi-cross-tools: @echo "_xi-cross-tools" .for _tool in \ - gnu/usr.bin/binutils \ - gnu/usr.bin/cc \ + ${_binutils} \ usr.bin/ar \ - ${_clang} + ${_clang_libs} \ + ${_clang} \ + ${_cc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \ cd ${.CURDIR}/${_tool}; \ ${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR} @@ -1924,6 +1965,7 @@ _xi-libraries: _xi-links: ${_+_}cd ${XDDESTDIR}/usr/bin; \ + mkdir -p ../../../../usr/bin; \ for i in *; do \ ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}-$$i; \ @@ -1934,5 +1976,3 @@ _xi-links: xdev xdev-build xdev-install: @echo "*** Error: Both XDEV and XDEV_ARCH must be defined for \"${.TARGET}\" target" .endif - -buildkernel ${WMAKE_TGTS} ${.ALLTARGETS:M_*}: .MAKE diff --git a/cddl/Makefile b/cddl/Makefile index 801d9cf..2a9b6f8 100644 --- a/cddl/Makefile +++ b/cddl/Makefile @@ -1,5 +1,11 @@ # $FreeBSD$ +.include <bsd.own.mk> + SUBDIR= lib sbin usr.bin usr.sbin +.if ${MK_TESTS} != "no" +SUBDIR+=tests +.endif + .include <bsd.subdir.mk> diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d index 396a808..ca8ad44 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: * Checks that setting "bufresize" to "auto" will cause buffer @@ -34,14 +32,8 @@ * SECTION: Buffers and Buffering/Buffer Resizing Policy; * Options and Tunables/bufsize; * Options and Tunables/bufresize - * - * NOTES: - * We use the undocumented "preallocate" option to make sure dtrace(1M) - * has enough space in its heap to allocate a buffer as large as the - * kernel's trace buffer. */ -#pragma D option preallocate=100t #pragma D option bufresize=auto #pragma D option bufsize=100t diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d index 50b814b..ddb97c8 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: * Checks that setting "bufresize" to "auto" will cause buffer @@ -34,14 +32,8 @@ * SECTION: Buffers and Buffering/Buffer Resizing Policy; * Options and Tunables/aggsize; * Options and Tunables/bufresize - * - * NOTES: - * We use the undocumented "preallocate" option to make sure dtrace(1M) - * has enough space in its heap to allocate a buffer as large as the - * kernel's trace buffer. */ -#pragma D option preallocate=100t #pragma D option bufresize=auto #pragma D option aggsize=100t diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dofmax.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dofmax.ksh new file mode 100644 index 0000000..22c267d --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dofmax.ksh @@ -0,0 +1,97 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# + +let j=8 + +enable() +{ + prog=/var/tmp/dtest.$$.d + err=/var/tmp/dtest.$$.err + + nawk -v nprobes=$1 'BEGIN { \ + for (i = 0; i < nprobes - 1; i++) { \ + printf("dtrace:::BEGIN,\n"); \ + } \ + \ + printf("dtrace:::BEGIN { exit(0); }\n"); \ + }' /dev/null > $prog + + dtrace -qs $prog > /dev/null 2> $err + + if [[ "$?" -eq 0 ]]; then + return 0 + else + if ! grep "DIF program exceeds maximum program size" $err \ + 1> /dev/null 2>&1 ; then + echo "failed to enable $prog: `cat $err`" + exit 1 + fi + + return 1 + fi +} + +# +# First, establish an upper bound +# +let upper=1 + +while enable $upper ; do + let lower=upper + let upper=upper+upper + echo success at $lower, raised to $upper +done + +# +# Now search for the highest value that can be enabled +# +while [[ "$lower" -lt "$upper" ]]; do + let guess=$(((lower + upper) / 2)) + echo "lower is $lower; upper is $upper; guess is $guess\c" + + if enable $guess ; then + if [[ $((upper - lower)) -le 2 ]]; then + let upper=guess + fi + + echo " (success)" + let lower=guess + else + echo " (failure)" + let upper=guess + fi +done + +let expected=10000 + +if [[ "$lower" -lt "$expected" ]]; then + echo "expected support for enablings of at least $expected probes; \c" + echo "found $lower" + exit 1 +fi + +echo "maximum supported enabled probes found to be $lower" +exit 0 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d index 8d4bb81..10dc61d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d @@ -44,7 +44,7 @@ BEGIN printf("\n"); - printf("%%a = %a\n", &`kmem_alloc); + printf("%%a = %a\n", &`malloc); printf("%%c = %c\n", i); printf("%%d = %d\n", i); printf("%%hd = %hd\n", (short)i); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out index 55c1222..1d27405 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out @@ -1,5 +1,5 @@ -%a = genunix`kmem_alloc +%a = kernel`malloc %c = a %d = 97 %hd = 97 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d index a740413..67d7749 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d @@ -36,6 +36,6 @@ BEGIN { - printf("sysname = %s", `utsname.sysname); + printf("sysname = %s", `ostype); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out index ba31981..82d597b 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out @@ -1 +1 @@ -sysname = SunOS +sysname = FreeBSD diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d index 32bc682..c2cf77d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d @@ -38,6 +38,6 @@ BEGIN { - printf("symbol = %a", &`kmem_alloc); + printf("symbol = %a", &`malloc); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out index 5ed9d8e..7f645e1 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out @@ -1 +1 @@ -symbol = kernel`kmem_alloc +symbol = kernel`malloc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh index 69c0f84..d2afbed 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh @@ -64,7 +64,7 @@ child=$! # ksh doing work. (This actually goes one step further and assumes that we # catch some non-static function in ksh.) # -script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null +script | tee /dev/fd/2 | egrep 'ksh(93)?`[a-zA-Z_]' > /dev/null status=$? kill $child diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh index 6ca823f..8be34ec 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh @@ -62,7 +62,7 @@ child=$! # # The only thing we can be sure of here is that ksh is doing some work. # -script | tee /dev/fd/2 | grep -w ksh > /dev/null +script | tee /dev/fd/2 | egrep -w 'ksh(93)?' > /dev/null status=$? kill $child diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh index b1a3ab9..8842d2b 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh @@ -63,7 +63,7 @@ child=$! # This test is essentially the same as that in the ufunc test; see that # test for the rationale. # -script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null +script | tee /dev/fd/2 | egrep 'ksh(93)?`[a-zA-Z_]' > /dev/null status=$? kill $child diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 index f3fc8e6..b634d45 100644 --- a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 +++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 @@ -2,7 +2,7 @@ .\" CDDL HEADER START .\" .\" The contents of this file are subject to the terms of the -.\" Common Development and Distribution License (the "License"). +.\" Common Development and Distribution License (the "License"). .\" You may not use this file except in compliance with the License. .\" .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE @@ -18,858 +18,382 @@ .\" .\" CDDL HEADER END .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved. -.TH lockstat 1M "28 Feb 2008" "SunOS 5.11" "System Administration Commands" -.SH NAME -lockstat \- report kernel lock and profiling statistics -.SH SYNOPSIS -.LP -.nf -\fBlockstat\fR [\fB-ACEHI\fR] [\fB-e\fR \fIevent_list\fR] [\fB-i\fR \fIrate\fR] - [\fB-b\fR | \fB-t\fR | \fB-h\fR | \fB-s\fR \fIdepth\fR] [\fB-n\fR \fInrecords\fR] - [\fB-l\fR \fIlock\fR [, \fIsize\fR]] [\fB-d\fR \fIduration\fR] - [\fB-f\fR \fIfunction\fR [, \fIsize\fR]] [\fB-T\fR] [\fB-ckgwWRpP\fR] [\fB-D\fR \fIcount\fR] - [\fB-o\fR \fIfilename\fR] [\fB-x\fR \fIopt\fR [=val]] \fIcommand\fR [\fIargs\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBlockstat\fR utility gathers and displays kernel locking and profiling statistics. \fBlockstat\fR allows you to specify which events to watch (for example, spin on adaptive mutex, block on read access to rwlock due to waiting writers, and so forth) how much -data to gather for each event, and how to display the data. By default, \fBlockstat\fR monitors all lock contention events, gathers frequency and timing data about those events, and displays the data in decreasing frequency order, so that the most common events appear first. -.sp -.LP -\fBlockstat\fR gathers data until the specified command completes. For example, to gather statistics for a fixed-time interval, use \fBsleep\fR(1) as -the command, as follows: -.sp -.LP -\fBexample#\fR \fBlockstat\fR \fBsleep\fR \fB5\fR -.sp -.LP -When the \fB-I\fR option is specified, \fBlockstat\fR establishes a per-processor high-level periodic interrupt source to gather profiling data. The interrupt handler simply generates a \fBlockstat\fR event whose caller is the interrupted PC (program counter). -The profiling event is just like any other \fBlockstat\fR event, so all of the normal \fBlockstat\fR options are applicable. -.sp -.LP -\fBlockstat\fR relies on DTrace to modify the running kernel's text to intercept events of interest. This imposes a small but measurable overhead on all system activity, so access to \fBlockstat\fR is restricted to super-user by default. The system administrator -can permit other users to use \fBlockstat\fR by granting them additional DTrace privileges. Refer to the \fISolaris Dynamic Tracing Guide\fR for more information about DTrace security features. -.SH OPTIONS -.sp -.LP -The following options are supported: -.SS "Event Selection" -.sp -.LP -If no event selection options are specified, the default is \fB-C\fR. -.sp -.ne 2 -.mk -.na -\fB\fB-A\fR\fR -.ad -.sp .6 -.RS 4n -Watch all lock events. \fB-A\fR is equivalent to \fB-CH\fR. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-C\fR\fR -.ad -.sp .6 -.RS 4n -Watch contention events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-E\fR\fR -.ad -.sp .6 -.RS 4n +.\" +.\" $FreeBSD$ +.\" +.Dd October 24, 2013 +.Dt LOCKSTAT 1 +.Os +.Sh NAME +.Nm lockstat +.Nd report kernel lock and profiling statistics +.Sh SYNOPSIS +.Nm +.Op Fl ACEHI +.Op Fl e Ar event-list +.Op Fl i Ar rate +.Op Fl b | t | h | s Ar depth +.Op Fl n Ar num-records +.Op Fl l Ar lock Oo Ns , Ns Ar size Oc +.Op Fl d Ar duration +.Op Fl f Ar function Oo Ns , Ns Ar size Oc +.Op Fl T +.Op Fl ckgwWRpP +.Op Fl D Ar count +.Op Fl o filename +.Op Fl x Ar opt Oo Ns = Ns Ar val Oc +.Ar command +.Op Oo Ar args Oc +.Sh DESCRIPTION +The +.Nm +utility gathers and displays kernel locking and profiling statistics. +.Nm +allows you to specify which events to watch (for example, spin on adaptive +mutex, block on read access to rwlock due to waiting writers, and so forth), how +much data to gather for each event, and how to display the data. +By default, +.Nm +monitors all lock contention events, gathers frequency and timing data about +those events, and displays the data in decreasing frequency order, so that the +most common events appear first. +.Pp +.Nm +gathers data until the specified command completes. +For example, to gather statistics for a fixed-time interval, use +.Xr sleep 1 +as the command, as follows: +.Pp +.Dl # lockstat sleep 5 +.Pp +When the +.Fl I +option is specified, +.Nm lockstat +establishes a per-processor high-level periodic interrupt source to gather +profiling data. +The interrupt handler simply generates a +.Nm +event whose caller is the interrupted PC (program counter). +The profiling event is just like any other +.Nm lockstat +event, so all of the normal +.Nm lockstat +options are applicable. +.Pp +.Nm +relies on DTrace to modify the running kernel's text to intercept events of +interest. +This imposes a small but measurable overhead on all system activity, so access +to +.Nm +is restricted to super-user by default. +.Sh OPTIONS +The following options are supported: +.Ss Event Selection +If no event selection options are specified, the default is +.Fl C . +.Bl -tag -width indent +.It Fl A +Watch all lock events. +.Fl A +is equivalent to +.Fl CH . +.It Fl C +Watch contention events. +.It Fl E Watch error events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-e\fR \fIevent_list\fR\fR -.ad -.sp .6 -.RS 4n -Only watch the specified events. \fIevent\fR \fIlist\fR is a comma-separated list of events or ranges of events such as 1,4-7,35. Run \fBlockstat\fR with no arguments to get a brief description of all events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-H\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl e Ar event-list +Only watch the specified events. +.Ar event-list +is a comma-separated list of events or ranges of events such as 1,4-7,35. +Run +.Nm +with no arguments to get a brief description of all events. +.It Fl H Watch hold events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-I\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl I Watch profiling interrupt events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-i\fR \fIrate\fR\fR -.ad -.sp .6 -.RS 4n -Interrupt rate (per second) for \fB-I\fR. The default is 97 Hz, so that profiling doesn't run in lockstep with the clock interrupt (which runs at 100 Hz). -.RE - -.SS "Data Gathering" -.sp -.ne 2 -.mk -.na -\fB\fB-x\fR \fIarg\fR[=\fIval\fR]\fR -.ad -.sp .6 -.RS 4n -Enable or modify a DTrace runtime option or D compiler option. The list of options is found in the \fI\fR. Boolean options are enabled by specifying their name. Options with values are set by separating the option name and -value with an equals sign (=). -.RE - -.SS "Data Gathering (Mutually Exclusive)" -.sp -.ne 2 -.mk -.na -\fB\fB-b\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl i Ar rate +Interrupt rate (per second) for +.Fl I . +The default is 97 Hz, so that profiling doesn't run in lockstep with the clock +interrupt (which runs at 100 Hz). +.El +.Ss Data Gathering +.Bl -tag -width indent +.It Fl x Ar arg Oo Ns = Ns Ar val Oc +Enable or modify a +.Xr dtrace 1 +runtime option or D compiler option. +Boolean options are enabled by specifying their name. +Options with values are set by separating the option name and value with an +equals sign. +.El +.Ss "Data Gathering (Mutually Exclusive)" +.Bl -tag -width indent +.It Fl b Basic statistics: lock, caller, number of events. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-h\fR\fR -.ad -.sp .6 -.RS 4n -Histogram: Timing plus time-distribution histograms. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-s\fR \fIdepth\fR\fR -.ad -.sp .6 -.RS 4n -Stack trace: Histogram plus stack traces up to \fIdepth\fR frames deep. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-t\fR\fR -.ad -.sp .6 -.RS 4n -Timing: Basic plus timing for all events [default]. -.RE - -.SS "Data Filtering" -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-d\fR \fIduration\fR\fR -.ad -.sp .6 -.RS 4n -Only watch events longer than \fIduration\fR. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-f\fR \fIfunc[,size]\fR\fR -.ad -.sp .6 -.RS 4n -Only watch events generated by \fIfunc\fR, which can be specified as a symbolic name or hex address. \fIsize\fR defaults to the \fBELF\fR symbol size if available, or \fB1\fR if not. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-l\fR \fIlock[,size]\fR\fR -.ad -.sp .6 -.RS 4n -Only watch \fIlock\fR, which can be specified as a symbolic name or hex address. \fBsize\fR defaults to the \fBELF\fR symbol size or \fB1\fR if the symbol size is not available. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-n\fR \fInrecords\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl h +Histogram: timing plus time-distribution histograms. +.It Fl s Ar depth +Stack trace: histogram plus stack traces up to +.Ar depth +frames deep. +.It Fl t +Timing: Basic plus timing for all events (default). +.El +.Ss "Data Filtering" +.Bl -tag -width indent +.It Fl d Ar duration +Only watch events longer than +.Ar duration . +.It Fl f Ar func Ns Oo Ns , Ns Ar size Oc Ns +Only watch events generated by +.Ar func , +which can be specified as a symbolic name or hex address. +.Ar size +defaults to the ELF symbol size if available, or 1 if not. +.It Fl l Ar lock Ns Oo Ns , Ns Ar size Oc Ns +Only watch +.Ar lock , +which can be specified as a symbolic name or hex address. +.Ar size +defaults to the ELF symbol size or 1 if the symbol size is not available. +.It Fl n Ar num-records Maximum number of data records. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-T\fR\fR -.ad -.sp .6 -.RS 4n -Trace (rather than sample) events [off by default]. -.RE - -.SS "Data Reporting" -.sp -.ne 2 -.mk -.na -\fB\fB-c\fR\fR -.ad -.sp .6 -.RS 4n -Coalesce lock data for lock arrays (for example, \fBpse_mutex[]\fR). -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-D\fR \fIcount\fR\fR -.ad -.sp .6 -.RS 4n -Only display the top \fIcount\fR events of each type. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-g\fR\fR -.ad -.sp .6 -.RS 4n -Show total events generated by function. For example, if \fBfoo()\fR calls \fBbar()\fR in a loop, the work done by \fBbar()\fR counts as work generated by \fBfoo()\fR (along with any work done by \fBfoo()\fR itself). -The \fB-g\fR option works by counting the total number of stack frames in which each function appears. This implies two things: (1) the data reported by \fB-g\fR can be misleading if the stack traces are not deep enough, and (2) functions that are called recursively might show -greater than 100% activity. In light of issue (1), the default data gathering mode when using \fB-g\fR is \fB-s\fR \fB50\fR. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-k\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl T +Trace (rather than sample) events. +This is off by default. +.El +.Ss Data Reporting +.Bl -tag -width indent +.It Fl c +Coalesce lock data for lock arrays. +.It Fl D Ar count +Only display the top +.Ar count +events of each type. +.It Fl g +Show total events generated by function. +For example, if +.Fn foo +calls +.Fn bar +in a loop, the work done by +.Fn bar +counts as work generated by +.Fn foo +(along with any work done by +.Fn foo +itself). +The +.Fl g +option works by counting the total number of stack frames in which each function +appears. +This implies two things: (1) the data reported by +.Fl g +can be misleading if the stack traces are not deep enough, and (2) functions +that are called recursively might show greater than 100% activity. +In light of issue (1), the default data gathering mode when using +.Fl g +is +.Fl s 50 . +.It Fl k Coalesce PCs within functions. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB\fR\fB-o\fR \fIfilename\fR\fR -.ad -.sp .6 -.RS 4n -Direct output to \fIfilename\fR. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-P\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl o Ar filename +Direct output to +.Ar filename . +.It Fl P Sort data by (\fIcount * time\fR) product. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-p\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl p Parsable output format. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-R\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl R Display rates (events per second) rather than counts. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-W\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl W Whichever: distinguish events only by caller, not by lock. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fB-w\fR\fR -.ad -.sp .6 -.RS 4n +.It Fl w Wherever: distinguish events only by lock, not by caller. -.RE - -.SH DISPLAY FORMATS -.sp -.LP +.El +.Sh DISPLAY FORMATS The following headers appear over various columns of data. -.sp -.ne 2 -.mk -.na -\fB\fBCount\fR or \fBops/s\fR\fR -.ad -.sp .6 -.RS 4n -Number of times this event occurred, or the rate (times per second) if \fB-R\fR was specified. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBindv\fR\fR -.ad -.sp .6 -.RS 4n +.Bl -tag -width indent +.It Count or ops/s +Number of times this event occurred, or the rate (times per second) if +.Fl R +was specified. +.It indv Percentage of all events represented by this individual event. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBgenr\fR\fR -.ad -.sp .6 -.RS 4n +.It genr Percentage of all events generated by this function. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBcuml\fR\fR -.ad -.sp .6 -.RS 4n +.It cuml Cumulative percentage; a running total of the individuals. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBrcnt\fR\fR -.ad -.sp .6 -.RS 4n -Average reference count. This will always be \fB1\fR for exclusive locks (mutexes, spin locks, rwlocks held as writer) but can be greater than \fB1\fR for shared locks (rwlocks held as reader). -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBnsec\fR\fR -.ad -.sp .6 -.RS 4n -Average duration of the events in nanoseconds, as appropriate for the event. For the profiling event, duration means interrupt latency. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBLock\fR\fR -.ad -.sp .6 -.RS 4n +.It rcnt +Average reference count. +This will always be 1 for exclusive locks (mutexes, +spin locks, rwlocks held as writer) but can be greater than 1 for shared locks +(rwlocks held as reader). +.It nsec +Average duration of the events in nanoseconds, as appropriate for the event. +For the profiling event, duration means interrupt latency. +.It Lock Address of the lock; displayed symbolically if possible. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBCPU+PIL\fR\fR -.ad -.sp .6 -.RS 4n -\fBCPU\fR plus processor interrupt level (\fBPIL\fR). For example, if \fBCPU\fR 4 is interrupted while at \fBPIL\fR 6, this will be reported as \fBcpu[4]+6\fR. -.RE - -.sp -.ne 2 -.mk -.na -\fB\fBCaller\fR\fR -.ad -.sp .6 -.RS 4n +.It CPU+PIL +CPU plus processor interrupt level (PIL). +For example, if CPU 4 is interrupted while at PIL 6, this will be reported as +cpu[4]+6. +.It Caller Address of the caller; displayed symbolically if possible. -.RE - -.SH EXAMPLES -.LP -\fBExample 1 \fRMeasuring Kernel Lock Contention -.sp -.in +2 -.nf -example# \fBlockstat sleep 5\fR -Adaptive mutex spin: 2210 events in 5.055 seconds (437 events/sec) -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------- - 269 12% 12% 1.00 2160 service_queue background+0xdc - 249 11% 23% 1.00 86 service_queue qenable_locked+0x64 - 228 10% 34% 1.00 131 service_queue background+0x15c - 68 3% 37% 1.00 79 0x30000024070 untimeout+0x1c - 59 3% 40% 1.00 384 0x300066fa8e0 background+0xb0 - 43 2% 41% 1.00 30 rqcred_lock svc_getreq+0x3c - 42 2% 43% 1.00 341 0x30006834eb8 background+0xb0 - 41 2% 45% 1.00 135 0x30000021058 untimeout+0x1c - 40 2% 47% 1.00 39 rqcred_lock svc_getreq+0x260 - 37 2% 49% 1.00 2372 0x300068e83d0 hmestart+0x1c4 - 36 2% 50% 1.00 77 0x30000021058 timeout_common+0x4 - 36 2% 52% 1.00 354 0x300066fa120 background+0xb0 - 32 1% 53% 1.00 97 0x30000024070 timeout_common+0x4 - 31 1% 55% 1.00 2923 0x300069883d0 hmestart+0x1c4 - 29 1% 56% 1.00 366 0x300066fb290 background+0xb0 - 28 1% 57% 1.00 117 0x3000001e040 untimeout+0x1c - 25 1% 59% 1.00 93 0x3000001e040 timeout_common+0x4 - 22 1% 60% 1.00 25 0x30005161110 sync_stream_buf+0xdc - 21 1% 60% 1.00 291 0x30006834eb8 putq+0xa4 - 19 1% 61% 1.00 43 0x3000515dcb0 mdf_alloc+0xc - 18 1% 62% 1.00 456 0x30006834eb8 qenable+0x8 - 18 1% 63% 1.00 61 service_queue queuerun+0x168 - 17 1% 64% 1.00 268 0x30005418ee8 vmem_free+0x3c -[...] - -R/W reader blocked by writer: 76 events in 5.055 seconds (15 events/sec) +.El +.Sh EXAMPLES +.Bl -tag -width 0n +.It Example 1 Measuring Kernel Lock Contention +.Pp +.Li # lockstat sleep 5 +.Bd -literal +Adaptive mutex spin: 41411 events in 5.011 seconds (8263 events/sec) -Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------- - 23 30% 30% 1.00 22590137 0x300098ba358 ufs_dirlook+0xd0 - 17 22% 53% 1.00 5820995 0x3000ad815e8 find_bp+0x10 - 13 17% 70% 1.00 2639918 0x300098ba360 ufs_iget+0x198 - 4 5% 75% 1.00 3193015 0x300098ba360 ufs_getattr+0x54 - 3 4% 79% 1.00 7953418 0x3000ad817c0 find_bp+0x10 - 3 4% 83% 1.00 935211 0x3000ad815e8 find_read_lof+0x14 - 2 3% 86% 1.00 16357310 0x300073a4720 find_bp+0x10 - 2 3% 88% 1.00 2072433 0x300073a4720 find_read_lof+0x14 - 2 3% 91% 1.00 1606153 0x300073a4370 find_bp+0x10 - 1 1% 92% 1.00 2656909 0x300107e7400 ufs_iget+0x198 -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 2 \fRMeasuring Hold Times -.sp -.in +2 -.nf -example# \fBlockstat -H -D 10 sleep 1\fR -Adaptive mutex spin: 513 events -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -Count indv cuml rcnt nsec Lock Caller -------------------------------------------------------------------------- - 480 5% 5% 1.00 1136 0x300007718e8 putnext+0x40 - 286 3% 9% 1.00 666 0x3000077b430 getf+0xd8 - 271 3% 12% 1.00 537 0x3000077b430 msgio32+0x2fc - 270 3% 15% 1.00 3670 0x300007718e8 strgetmsg+0x3d4 - 270 3% 18% 1.00 1016 0x300007c38b0 getq_noenab+0x200 - 264 3% 20% 1.00 1649 0x300007718e8 strgetmsg+0xa70 - 216 2% 23% 1.00 6251 tcp_mi_lock tcp_snmp_get+0xfc - 206 2% 25% 1.00 602 thread_free_lock clock+0x250 - 138 2% 27% 1.00 485 0x300007c3998 putnext+0xb8 - 138 2% 28% 1.00 3706 0x300007718e8 strrput+0x5b8 -------------------------------------------------------------------------- +Count indv cuml rcnt nsec Lock Caller +------------------------------------------------------------------------------- +13750 33% 33% 0.00 72 vm_page_queue_free_mtx vm_page_free_toq+0x12e +13648 33% 66% 0.00 66 vm_page_queue_free_mtx vm_page_alloc+0x138 + 4023 10% 76% 0.00 51 vm_dom+0x80 vm_page_dequeue+0x68 + 2672 6% 82% 0.00 186 vm_dom+0x80 vm_page_enqueue+0x63 + 618 1% 84% 0.00 31 0xfffff8000cd83a88 qsyncvp+0x37 + 506 1% 85% 0.00 164 0xfffff8000cb3f098 vputx+0x5a + 477 1% 86% 0.00 69 0xfffff8000c7eb180 uma_dbg_getslab+0x5b + 288 1% 87% 0.00 77 0xfffff8000cd8b000 vn_finished_write+0x29 + 263 1% 88% 0.00 103 0xfffff8000cbad448 vinactive+0xdc + 259 1% 88% 0.00 53 0xfffff8000cd8b000 vfs_ref+0x24 + 237 1% 89% 0.00 20 0xfffff8000cbad448 vfs_hash_get+0xcc + 233 1% 89% 0.00 22 0xfffff8000bfd9480 uma_dbg_getslab+0x5b + 223 1% 90% 0.00 20 0xfffff8000cb3f098 cache_lookup+0x561 + 193 0% 90% 0.00 16 0xfffff8000cb40ba8 vref+0x27 + 175 0% 91% 0.00 34 0xfffff8000cbad448 vputx+0x5a + 169 0% 91% 0.00 51 0xfffff8000cd8b000 vfs_unbusy+0x27 + 164 0% 92% 0.00 31 0xfffff8000cb40ba8 vputx+0x5a [...] -.fi -.in -2 -.sp -.LP -\fBExample 3 \fRMeasuring Hold Times for Stack Traces Containing a Specific Function -.sp -.in +2 -.nf -example# \fBlockstat -H -f tcp_rput_data -s 50 -D 10 sleep 1\fR -Adaptive mutex spin: 11 events in 1.023 seconds (11 -events/sec) -.fi -.in -2 -.sp +Adaptive mutex block: 10 events in 5.011 seconds (2 events/sec) -.sp -.in +2 -.nf -------------------------------------------------------------------------- Count indv cuml rcnt nsec Lock Caller - 9 82% 82% 1.00 2540 0x30000031380 tcp_rput_data+0x2b90 - - nsec ------ Time Distribution ------ count Stack - 256 |@@@@@@@@@@@@@@@@ 5 tcp_rput_data+0x2b90 - 512 |@@@@@@ 2 putnext+0x78 - 1024 |@@@ 1 ip_rput+0xec4 - 2048 | 0 _c_putnext+0x148 - 4096 | 0 hmeread+0x31c - 8192 | 0 hmeintr+0x36c - 16384 |@@@ 1 -sbus_intr_wrapper+0x30 +------------------------------------------------------------------------------- + 3 30% 30% 0.00 17592 vm_page_queue_free_mtx vm_page_alloc+0x138 + 2 20% 50% 0.00 20528 vm_dom+0x80 vm_page_enqueue+0x63 + 2 20% 70% 0.00 55502 0xfffff8000cb40ba8 vputx+0x5a + 1 10% 80% 0.00 12007 vm_page_queue_free_mtx vm_page_free_toq+0x12e + 1 10% 90% 0.00 9125 0xfffff8000cbad448 vfs_hash_get+0xcc + 1 10% 100% 0.00 7864 0xfffff8000cd83a88 qsyncvp+0x37 +------------------------------------------------------------------------------- [...] +.Ed +.It Example 2 Measuring Hold Times +.Pp +.Li # lockstat -H -D 10 sleep 1 +.Bd -literal +Adaptive mutex hold: 109589 events in 1.039 seconds (105526 events/sec) Count indv cuml rcnt nsec Lock Caller - 1 9% 91% 1.00 1036 0x30000055380 freemsg+0x44 - - nsec ------ Time Distribution ------ count Stack - 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 freemsg+0x44 - tcp_rput_data+0x2fd0 - putnext+0x78 - ip_rput+0xec4 - _c_putnext+0x148 - hmeread+0x31c - hmeintr+0x36c - -sbus_intr_wrapper+0x30 -------------------------------------------------------------------------- -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 4 \fRBasic Kernel Profiling -.sp -.LP -For basic profiling, we don't care whether the profiling interrupt sampled \fBfoo()\fR\fB+0x4c\fR or \fBfoo()\fR\fB+0x78\fR; we care only that it sampled somewhere in \fBfoo()\fR, so we use \fB-k\fR. The \fBCPU\fR and \fBPIL\fR aren't relevant to basic profiling because we are measuring the system as a whole, not a particular \fBCPU\fR or interrupt level, so we use \fB-W\fR. - -.sp -.in +2 -.nf -example# \fBlockstat -kIW -D 20 ./polltest\fR -Profiling interrupt: 82 events in 0.424 seconds (194 -events/sec) -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -Count indv cuml rcnt nsec Hottest CPU+PIL Caller ------------------------------------------------------------------------ - 8 10% 10% 1.00 698 cpu[1] utl0 - 6 7% 17% 1.00 299 cpu[0] read - 5 6% 23% 1.00 124 cpu[1] getf - 4 5% 28% 1.00 327 cpu[0] fifo_read - 4 5% 33% 1.00 112 cpu[1] poll - 4 5% 38% 1.00 212 cpu[1] uiomove - 4 5% 43% 1.00 361 cpu[1] mutex_tryenter - 3 4% 46% 1.00 682 cpu[0] write - 3 4% 50% 1.00 89 cpu[0] pcache_poll - 3 4% 54% 1.00 118 cpu[1] set_active_fd - 3 4% 57% 1.00 105 cpu[0] syscall_trap32 - 3 4% 61% 1.00 640 cpu[1] (usermode) - 2 2% 63% 1.00 127 cpu[1] fifo_poll - 2 2% 66% 1.00 300 cpu[1] fifo_write - 2 2% 68% 1.00 669 cpu[0] releasef - 2 2% 71% 1.00 112 cpu[1] bt_getlowbit - 2 2% 73% 1.00 247 cpu[1] splx - 2 2% 76% 1.00 503 cpu[0] mutex_enter - 2 2% 78% 1.00 467 cpu[0]+10 disp_lock_enter - 2 2% 80% 1.00 139 cpu[1] default_copyin ------------------------------------------------------------------------ -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 5 \fRGenerated-load Profiling -.sp -.LP -In the example above, 5% of the samples were in \fBpoll()\fR. This tells us how much time was spent inside \fBpoll()\fR itself, but tells us nothing about how much work was \fBgenerated\fR by \fBpoll()\fR; that is, how much time we spent -in functions called by \fBpoll()\fR. To determine that, we use the \fB-g\fR option. The example below shows that although \fBpolltest\fR spends only 5% of its time in \fBpoll()\fR itself, \fBpoll()\fR-induced work accounts for 34% of -the load. - -.sp -.LP -Note that the functions that generate the profiling interrupt (\fBlockstat_intr()\fR, \fBcyclic_fire()\fR, and so forth) appear in every stack trace, and therefore are considered to have generated 100% of the load. This illustrates an important point: the generated -load percentages do \fBnot\fR add up to 100% because they are not independent. If 72% of all stack traces contain both \fBfoo()\fR and \fBbar()\fR, then both \fBfoo()\fR and \fBbar()\fR are 72% load generators. - -.sp -.in +2 -.nf -example# \fBlockstat -kgIW -D 20 ./polltest\fR -Profiling interrupt: 80 events in 0.412 seconds (194 events/sec) -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -Count genr cuml rcnt nsec Hottest CPU+PIL Caller -------------------------------------------------------------------------- - 80 100% ---- 1.00 310 cpu[1] lockstat_intr - 80 100% ---- 1.00 310 cpu[1] cyclic_fire - 80 100% ---- 1.00 310 cpu[1] cbe_level14 - 80 100% ---- 1.00 310 cpu[1] current_thread - 27 34% ---- 1.00 176 cpu[1] poll - 20 25% ---- 1.00 221 cpu[0] write - 19 24% ---- 1.00 249 cpu[1] read - 17 21% ---- 1.00 232 cpu[0] write32 - 17 21% ---- 1.00 207 cpu[1] pcache_poll - 14 18% ---- 1.00 319 cpu[0] fifo_write - 13 16% ---- 1.00 214 cpu[1] read32 - 10 12% ---- 1.00 208 cpu[1] fifo_read - 10 12% ---- 1.00 787 cpu[1] utl0 - 9 11% ---- 1.00 178 cpu[0] pcacheset_resolve - 9 11% ---- 1.00 262 cpu[0] uiomove - 7 9% ---- 1.00 506 cpu[1] (usermode) - 5 6% ---- 1.00 195 cpu[1] fifo_poll - 5 6% ---- 1.00 136 cpu[1] syscall_trap32 - 4 5% ---- 1.00 139 cpu[0] releasef - 3 4% ---- 1.00 277 cpu[1] polllock -------------------------------------------------------------------------- -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 6 \fRGathering Lock Contention and Profiling Data for a Specific Module -.sp -.LP -In this example we use the \fB-f\fR option not to specify a single function, but rather to specify the entire text space of the \fBsbus\fR module. We gather both lock contention and profiling statistics so that contention can be correlated with overall load on the -module. - -.sp -.in +2 -.nf -example# \fBmodinfo | grep sbus\fR -24 102a8b6f b8b4 59 1 sbus (SBus (sysio) nexus driver) -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -example# \fBlockstat -kICE -f 0x102a8b6f,0xb8b4 sleep 10\fR -Adaptive mutex spin: 39 events in 10.042 seconds (4 events/sec) -.fi -.in -2 -.sp - -.sp -.in +2 -.nf -Count indv cuml rcnt nsec Lock Caller -------------------------------------------------------------------------- - 15 38% 38% 1.00 206 0x30005160528 sync_stream_buf - 7 18% 56% 1.00 14 0x30005160d18 sync_stream_buf - 6 15% 72% 1.00 27 0x300060c3118 sync_stream_buf - 5 13% 85% 1.00 24 0x300060c3510 sync_stream_buf - 2 5% 90% 1.00 29 0x300060c2d20 sync_stream_buf - 2 5% 95% 1.00 24 0x30005161cf8 sync_stream_buf - 1 3% 97% 1.00 21 0x30005161110 sync_stream_buf - 1 3% 100% 1.00 23 0x30005160130 sync_stream_buf +------------------------------------------------------------------------------- + 8998 8% 8% 0.00 617 0xfffff8000c7eb180 uma_dbg_getslab+0xd4 + 5901 5% 14% 0.00 917 vm_page_queue_free_mtx vm_object_terminate+0x16a + 5040 5% 18% 0.00 902 vm_dom+0x80 vm_page_free_toq+0x88 + 4884 4% 23% 0.00 1056 vm_page_queue_free_mtx vm_page_alloc+0x44e + 4664 4% 27% 0.00 759 vm_dom+0x80 vm_fault_hold+0x1a13 + 4011 4% 31% 0.00 888 vm_dom vm_page_advise+0x11b + 4010 4% 34% 0.00 957 vm_dom+0x80 _vm_page_deactivate+0x5c + 3743 3% 38% 0.00 582 0xfffff8000cf04838 pmap_is_prefaultable+0x158 + 2254 2% 40% 0.00 952 vm_dom vm_page_free_toq+0x88 + 1639 1% 41% 0.00 591 0xfffff800d60065b8 trap_pfault+0x1f7 +------------------------------------------------------------------------------- [...] -Adaptive mutex block: 9 events in 10.042 seconds (1 events/sec) +R/W writer hold: 64314 events in 1.039 seconds (61929 events/sec) -Count indv cuml rcnt nsec Lock Caller -------------------------------------------------------------------------- - 4 44% 44% 1.00 156539 0x30005160528 sync_stream_buf - 2 22% 67% 1.00 763516 0x30005160d18 sync_stream_buf - 1 11% 78% 1.00 462130 0x300060c3510 sync_stream_buf - 1 11% 89% 1.00 288749 0x30005161110 sync_stream_buf - 1 11% 100% 1.00 1015374 0x30005160130 sync_stream_buf -[...] - -Profiling interrupt: 229 events in 10.042 seconds (23 events/sec) - -Count indv cuml rcnt nsec Hottest CPU+PIL Caller - -------------------------------------------------------------------------- - 89 39% 39% 1.00 426 cpu[0]+6 sync_stream_buf - 64 28% 67% 1.00 398 cpu[0]+6 sbus_intr_wrapper - 23 10% 77% 1.00 324 cpu[0]+6 iommu_dvma_kaddr_load - 21 9% 86% 1.00 512 cpu[0]+6 iommu_tlb_flush - 14 6% 92% 1.00 342 cpu[0]+6 iommu_dvma_unload - 13 6% 98% 1.00 306 cpu[1] iommu_dvma_sync - 5 2% 100% 1.00 389 cpu[1] iommu_dma_bindhdl -------------------------------------------------------------------------- -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 7 \fRDetermining the Average PIL (processor interrupt level) for a CPU -.sp -.in +2 -.nf -example# \fBlockstat -Iw -l cpu[3] ./testprog\fR - -Profiling interrupt: 14791 events in 152.463 seconds (97 events/sec) - -Count indv cuml rcnt nsec CPU+PIL Hottest Caller - ------------------------------------------------------------------------ -13641 92% 92% 1.00 253 cpu[3] (usermode) - 579 4% 96% 1.00 325 cpu[3]+6 ip_ocsum+0xe8 - 375 3% 99% 1.00 411 cpu[3]+10 splx - 154 1% 100% 1.00 527 cpu[3]+4 fas_intr_svc+0x80 - 41 0% 100% 1.00 293 cpu[3]+13 send_mondo+0x18 - 1 0% 100% 1.00 266 cpu[3]+12 zsa_rxint+0x400 ------------------------------------------------------------------------ -[...] -.fi -.in -2 -.sp - -.LP -\fBExample 8 \fRDetermining which Subsystem is Causing the System to be Busy -.sp -.in +2 -.nf -example# \fBlockstat -s 10 -I sleep 20\fR - -Profiling interrupt: 4863 events in 47.375 seconds (103 events/sec) - -Count indv cuml rcnt nsec CPU+PIL Caller - ------------------------------------------------------------------------ -1929 40% 40% 0.00 3215 cpu[0] usec_delay+0x78 - nsec ------ Time Distribution ------ count Stack - 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1872 ata_wait+0x90 - 8192 | 27 acersb_get_intr_status+0x34 -16384 | 29 ata_set_feature+0x124 -32768 | 1 ata_disk_start+0x15c - ata_hba_start+0xbc - ghd_waitq_process_and \e - _mutex_hold+0x70 - ghd_waitq_process_and \e - _mutex_exit+0x4 - ghd_transport+0x12c - ata_disk_tran_start+0x108 ------------------------------------------------------------------------ +Count indv cuml rcnt nsec Lock Caller +------------------------------------------------------------------------------- + 7421 12% 12% 0.00 2994 pvh_global_lock pmap_page_is_mapped+0xb6 + 4668 7% 19% 0.00 3313 pvh_global_lock pmap_enter+0x9ae + 1639 3% 21% 0.00 733 0xfffff80168d10200 vm_object_deallocate+0x683 + 1639 3% 24% 0.00 3061 0xfffff80168d10200 unlock_and_deallocate+0x2b + 1639 3% 26% 0.00 2966 0xfffff80168d10200 vm_fault_hold+0x16ee + 1567 2% 29% 0.00 733 0xfffff80168d10200 vm_fault_hold+0x19bc + 821 1% 30% 0.00 786 0xfffff801eb0cc000 vm_object_madvise+0x32d + 649 1% 31% 0.00 4918 0xfffff80191105300 vm_fault_hold+0x16ee + 648 1% 32% 0.00 8112 0xfffff80191105300 unlock_and_deallocate+0x2b + 647 1% 33% 0.00 1261 0xfffff80191105300 vm_object_deallocate+0x683 +------------------------------------------------------------------------------- +.Ed +.It Example 3 Measuring Hold Times for Stack Traces Containing a Specific Function +.Pp +.Li # lockstat -H -f tcp_input -s 50 -D 10 sleep 1 +.Bd -literal +Adaptive mutex hold: 68 events in 1.026 seconds (66 events/sec) + +------------------------------------------------------------------------------- +Count indv cuml rcnt nsec Lock Caller + 32 47% 47% 0.00 1631 0xfffff800686f50d8 tcp_do_segment+0x284b + + nsec ------ Time Distribution ------ count Stack + 1024 |@@@@@@@@@@ 11 tcp_input+0xf54 + 2048 |@@@@@@@@@@@@@ 14 ip_input+0xc8 + 4096 |@@@@@ 6 swi_net+0x192 + 8192 | 1 intr_event_execute_handlers+0x93 + ithread_loop+0xa6 + fork_exit+0x84 + 0xffffffff808cf9ee +------------------------------------------------------------------------------- +Count indv cuml rcnt nsec Lock Caller + 29 43% 90% 0.00 4851 0xfffff800686f50d8 sowakeup+0xf8 + + nsec ------ Time Distribution ------ count Stack + 4096 |@@@@@@@@@@@@@@@ 15 tcp_do_segment+0x2423 + 8192 |@@@@@@@@@@@@ 12 tcp_input+0xf54 + 16384 |@@ 2 ip_input+0xc8 + swi_net+0x192 + intr_event_execute_handlers+0x93 + ithread_loop+0xa6 + fork_exit+0x84 + 0xffffffff808cf9ee +------------------------------------------------------------------------------- [...] -.fi -.in -2 -.sp - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -tab() box; -cw(2.75i) |cw(2.75i) -lw(2.75i) |lw(2.75i) -. -ATTRIBUTE TYPEATTRIBUTE VALUE -_ -AvailabilitySUNWdtrc -.TE - -.SH SEE ALSO -.sp -.LP -\fBdtrace\fR(1M), \fBplockstat\fR(1M), \fBattributes\fR(5), \fBlockstat\fR(7D), \fBmutex\fR(9F), \fBrwlock\fR(9F) -.sp -.LP -\fISolaris Dynamic Tracing Guide\fR -.SH NOTES -.sp -.LP -The profiling support provided by \fBlockstat\fR \fB-I\fR replaces the old (and undocumented) \fB/usr/bin/kgmon\fR and \fB/dev/profile\fR. -.sp -.LP -Tail-call elimination can affect call sites. For example, if \fBfoo()\fR\fB+0x50\fR calls \fBbar()\fR and the last thing \fBbar()\fR does is call \fBmutex_exit()\fR, the compiler can arrange for \fBbar()\fR to -branch to \fBmutex_exit()\fRwith a return address of \fBfoo()\fR\fB+0x58\fR. Thus, the \fBmutex_exit()\fR in \fBbar()\fR will appear as though it occurred at \fBfoo()\fR\fB+0x58\fR. -.sp -.LP -The \fBPC\fR in the stack frame in which an interrupt occurs can be bogus because, between function calls, the compiler is free to use the return address register for local storage. -.sp -.LP -When using the \fB-I\fR and \fB-s\fR options together, the interrupted PC will usually not appear anywhere in the stack since the interrupt handler is entered asynchronously, not by a function call from that \fBPC\fR. -.sp -.LP -The \fBlockstat\fR technology is provided on an as-is basis. The format and content of \fBlockstat\fR output reflect the current Solaris kernel implementation and are therefore subject to change in future releases. +.Ed +.El +.Sh SEE ALSO +.Xr dtrace 1 , +.Xr ksyms 4 , +.Xr locking 9 +.Sh NOTES +Tail-call elimination can affect call sites. +For example, if +.Fn foo Ns +0x50 +calls +.Fn bar +and the last thing +.Fn bar +does is call +.Fn mtx_unlock , +the compiler can arrange for +.Fn bar +to branch to +.Fn mtx_unlock +with a return address of +.Fn foo Ns +0x58. +Thus, the +.Fn mtx_unlock +in +.Fn bar +will appear as though it occurred at +.Fn foo Ns +0x58. +.Pp +The PC in the stack frame in which an interrupt occurs can be bogus because, +between function calls, the compiler is free to use the return address register +for local storage. +.Pp +When using the +.Fl I +and +.Fl s +options together, the interrupted PC will usually not appear anywhere in the +stack since the interrupt handler is entered asynchronously, not by a function +call from that PC. diff --git a/cddl/contrib/opensolaris/cmd/lockstat/sym.c b/cddl/contrib/opensolaris/cmd/lockstat/sym.c index 78b27d2..1aa77ad 100644 --- a/cddl/contrib/opensolaris/cmd/lockstat/sym.c +++ b/cddl/contrib/opensolaris/cmd/lockstat/sym.c @@ -179,8 +179,19 @@ symtab_init(void) size_t sz; #endif +#if defined(__FreeBSD__) + if ((fd = open("/dev/ksyms", O_RDONLY)) == -1) { + if (errno == ENOENT && modfind("ksyms") == -1) { + kldload("ksyms"); + fd = open("/dev/ksyms", O_RDONLY); + } + if (fd == -1) + return (-1); + } +#else if ((fd = open("/dev/ksyms", O_RDONLY)) == -1) return (-1); +#endif #if defined(sun) (void) elf_version(EV_CURRENT); diff --git a/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c index aa2c1f9..1288468 100644 --- a/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c +++ b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c @@ -778,7 +778,8 @@ main(int argc, char **argv) #endif int err; int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0; - char c, *p, *end; + int c; + char *p, *end; struct sigaction act; int done = 0; diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 b/cddl/contrib/opensolaris/cmd/zdb/zdb.8 index e036b96..e59f370 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.8 @@ -14,11 +14,12 @@ .\" .\" Copyright 2012, Richard Lowe. .\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>. +.\" Copyright (c) 2012 by Delphix. All rights reserved. .\" All Rights Reserved. .\" .\" $FreeBSD$ .\" -.Dd May 10, 2012 +.Dd March 20, 2014 .Dt ZDB 8 .Os .Sh NAME @@ -29,27 +30,35 @@ .Op Fl CumdibcsDvhLXFPA .Op Fl e Op Fl p Ar path... .Op Fl t Ar txg +.Op Fl U Ar cache +.Op Fl M Ar inflight I/Os .Ar poolname .Op Ar object ... .Nm .Op Fl divPA .Op Fl e Op Fl p Ar path... +.Op Fl U Ar cache .Ar dataset .Op Ar object ... .Nm .Fl m Op Fl LXFPA .Op Fl t Ar txg .Op Fl e Op Fl p Ar path... +.Op Fl U Ar cache .Ar poolname .Nm .Fl R Op Fl A .Op Fl e Op Fl p Ar path... +.Op Fl U Ar cache +.Ar poolname .Ar poolname .Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags .Nm .Fl S .Op Fl AP .Op Fl e Op Fl p Ar path... +.Op Fl U Ar cache +.Ar poolname .Ar poolname .Nm .Fl l @@ -118,6 +127,12 @@ compression ratio (compress), inflation due to the zfs copies property If specified twice, display a histogram of deduplication statistics, showing the allocated (physically present on disk) and referenced (logically referenced in the pool) block counts and sizes by reference count. +.Pp +If specified a third time, display the statistics independently for each deduplication table. +.Pp +If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks. +.Pp +If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks. .It Fl h Display pool history similar to .Cm zpool history , @@ -205,6 +220,11 @@ flag specifies the path under which devices are to be searched. .It Fl F Attempt to make an unreadable pool readable by trying progressively older transactions. +.It Fl M Ar inflight I/Os +Limit the number of outstanding checksum I/Os to the specified value. +The default value is 200. This option affects the performance of the +.Fl c +option. .It Fl P Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather than 1M. @@ -218,9 +238,7 @@ options for a means to see the available uberblocks and their associated transaction numbers. .It Fl U Ar cachefile Use a cache file other than -.Pa /etc/zfs/zpool.cache . -This option is only valid with -.Fl C +.Pa /boot/zfs/zpool.cache . .It Fl v Enable verbosity. Specify multiple times for increased verbosity. diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c index c265c99..61e8071 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ #include <stdio.h> @@ -89,6 +89,7 @@ extern void dump_intent_log(zilog_t *); uint64_t *zopt_object = NULL; int zopt_objects = 0; libzfs_handle_t *g_zfs; +uint64_t max_inflight = 200; /* * These libumem hooks provide a reasonable set of defaults for the allocator's @@ -110,16 +111,17 @@ static void usage(void) { (void) fprintf(stderr, - "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]]" - "poolname [object...]\n" - " %s [-divPA] [-e -p path...] dataset [object...]\n" - " %s -m [-LXFPA] [-t txg] [-e [-p path...]]" - "poolname [vdev [metaslab...]]\n" - " %s -R [-A] [-e [-p path...]] poolname " - "vdev:offset:size[:flags]\n" - " %s -S [-PA] [-e [-p path...]] poolname\n" - " %s -l [-uA] device\n" - " %s -C [-A] [-U config]\n\n", + "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] " + "[-U config] [-M inflight I/Os] poolname [object...]\n" + " %s [-divPA] [-e -p path...] [-U config] dataset " + "[object...]\n" + " %s -m [-LXFPA] [-t txg] [-e [-p path...]] [-U config] " + "poolname [vdev [metaslab...]]\n" + " %s -R [-A] [-e [-p path...]] poolname " + "vdev:offset:size[:flags]\n" + " %s -S [-PA] [-e [-p path...]] [-U config] poolname\n" + " %s -l [-uA] device\n" + " %s -C [-A] [-U config]\n\n", cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname); (void) fprintf(stderr, " Dataset name must include at least one " @@ -164,6 +166,8 @@ usage(void) (void) fprintf(stderr, " -P print numbers in parseable form\n"); (void) fprintf(stderr, " -t <txg> -- highest txg to use when " "searching for uberblocks\n"); + (void) fprintf(stderr, " -M <number of inflight I/Os> -- " + "specify the maximum number of checksumming I/Os [default is 200]"); (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " "to make only that option verbose\n"); (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); @@ -242,7 +246,7 @@ const char histo_stars[] = "****************************************"; const int histo_width = sizeof (histo_stars) - 1; static void -dump_histogram(const uint64_t *histo, int size) +dump_histogram(const uint64_t *histo, int size, int offset) { int i; int minidx = size - 1; @@ -263,7 +267,7 @@ dump_histogram(const uint64_t *histo, int size) for (i = minidx; i <= maxidx; i++) { (void) printf("\t\t\t%3u: %6llu %s\n", - i, (u_longlong_t)histo[i], + i + offset, (u_longlong_t)histo[i], &histo_stars[(max - histo[i]) * histo_width / max]); } } @@ -316,19 +320,19 @@ dump_zap_stats(objset_t *os, uint64_t object) (u_longlong_t)zs.zs_salt); (void) printf("\t\tLeafs with 2^n pointers:\n"); - dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE); + dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0); (void) printf("\t\tBlocks with n*5 entries:\n"); - dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE); + dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0); (void) printf("\t\tBlocks n/10 full:\n"); - dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE); + dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0); (void) printf("\t\tEntries with n chunks:\n"); - dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE); + dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0); (void) printf("\t\tBuckets with n entries:\n"); - dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE); + dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0); } /*ARGSUSED*/ @@ -517,26 +521,89 @@ dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size) zap_cursor_fini(&zc); } +int +get_dtl_refcount(vdev_t *vd) +{ + int refcount = 0; + + if (vd->vdev_ops->vdev_op_leaf) { + space_map_t *sm = vd->vdev_dtl_sm; + + if (sm != NULL && + sm->sm_dbuf->db_size == sizeof (space_map_phys_t)) + return (1); + return (0); + } + + for (int c = 0; c < vd->vdev_children; c++) + refcount += get_dtl_refcount(vd->vdev_child[c]); + return (refcount); +} + +int +get_metaslab_refcount(vdev_t *vd) +{ + int refcount = 0; + + if (vd->vdev_top == vd) { + for (int m = 0; m < vd->vdev_ms_count; m++) { + space_map_t *sm = vd->vdev_ms[m]->ms_sm; + + if (sm != NULL && + sm->sm_dbuf->db_size == sizeof (space_map_phys_t)) + refcount++; + } + } + for (int c = 0; c < vd->vdev_children; c++) + refcount += get_metaslab_refcount(vd->vdev_child[c]); + + return (refcount); +} + +static int +verify_spacemap_refcounts(spa_t *spa) +{ + uint64_t expected_refcount = 0; + uint64_t actual_refcount; + + (void) feature_get_refcount(spa, + &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM], + &expected_refcount); + actual_refcount = get_dtl_refcount(spa->spa_root_vdev); + actual_refcount += get_metaslab_refcount(spa->spa_root_vdev); + + if (expected_refcount != actual_refcount) { + (void) printf("space map refcount mismatch: expected %lld != " + "actual %lld\n", + (longlong_t)expected_refcount, + (longlong_t)actual_refcount); + return (2); + } + return (0); +} + static void -dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm) +dump_spacemap(objset_t *os, space_map_t *sm) { uint64_t alloc, offset, entry; - uint8_t mapshift = sm->sm_shift; - uint64_t mapstart = sm->sm_start; char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" }; - if (smo->smo_object == 0) + if (sm == NULL) return; /* * Print out the freelist entries in both encoded and decoded form. */ alloc = 0; - for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) { - VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset, + for (offset = 0; offset < space_map_length(sm); + offset += sizeof (entry)) { + uint8_t mapshift = sm->sm_shift; + + VERIFY0(dmu_read(os, space_map_object(sm), offset, sizeof (entry), &entry, DMU_READ_PREFETCH)); if (SM_DEBUG_DECODE(entry)) { + (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n", (u_longlong_t)(offset / sizeof (entry)), ddata[SM_DEBUG_ACTION_DECODE(entry)], @@ -548,10 +615,10 @@ dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm) (u_longlong_t)(offset / sizeof (entry)), SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F', (u_longlong_t)((SM_OFFSET_DECODE(entry) << - mapshift) + mapstart), + mapshift) + sm->sm_start), (u_longlong_t)((SM_OFFSET_DECODE(entry) << - mapshift) + mapstart + (SM_RUN_DECODE(entry) << - mapshift)), + mapshift) + sm->sm_start + + (SM_RUN_DECODE(entry) << mapshift)), (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift)); if (SM_TYPE_DECODE(entry) == SM_ALLOC) alloc += SM_RUN_DECODE(entry) << mapshift; @@ -559,10 +626,10 @@ dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm) alloc -= SM_RUN_DECODE(entry) << mapshift; } } - if (alloc != smo->smo_alloc) { + if (alloc != space_map_allocated(sm)) { (void) printf("space_map_object alloc (%llu) INCONSISTENT " "with space map summary (%llu)\n", - (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc); + (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc); } } @@ -570,15 +637,17 @@ static void dump_metaslab_stats(metaslab_t *msp) { char maxbuf[32]; - space_map_t *sm = msp->ms_map; - avl_tree_t *t = sm->sm_pp_root; - int free_pct = sm->sm_space * 100 / sm->sm_size; + range_tree_t *rt = msp->ms_tree; + avl_tree_t *t = &msp->ms_size_tree; + int free_pct = range_tree_space(rt) * 100 / msp->ms_size; - zdb_nicenum(space_map_maxsize(sm), maxbuf); + zdb_nicenum(metaslab_block_maxsize(msp), maxbuf); (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n", "segments", avl_numnodes(t), "maxsize", maxbuf, "freepct", free_pct); + (void) printf("\tIn-memory histogram:\n"); + dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0); } static void @@ -586,33 +655,44 @@ dump_metaslab(metaslab_t *msp) { vdev_t *vd = msp->ms_group->mg_vd; spa_t *spa = vd->vdev_spa; - space_map_t *sm = msp->ms_map; - space_map_obj_t *smo = &msp->ms_smo; + space_map_t *sm = msp->ms_sm; char freebuf[32]; - zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf); + zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf); (void) printf( "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n", - (u_longlong_t)(sm->sm_start / sm->sm_size), - (u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf); + (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start, + (u_longlong_t)space_map_object(sm), freebuf); - if (dump_opt['m'] > 1 && !dump_opt['L']) { + if (dump_opt['m'] > 2 && !dump_opt['L']) { mutex_enter(&msp->ms_lock); - space_map_load_wait(sm); - if (!sm->sm_loaded) - VERIFY(space_map_load(sm, zfs_metaslab_ops, - SM_FREE, smo, spa->spa_meta_objset) == 0); + metaslab_load_wait(msp); + if (!msp->ms_loaded) { + VERIFY0(metaslab_load(msp)); + range_tree_stat_verify(msp->ms_tree); + } dump_metaslab_stats(msp); - space_map_unload(sm); + metaslab_unload(msp); mutex_exit(&msp->ms_lock); } - if (dump_opt['d'] > 5 || dump_opt['m'] > 2) { - ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift)); + if (dump_opt['m'] > 1 && sm != NULL && + spa_feature_is_active(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) { + /* + * The space map histogram represents free space in chunks + * of sm_shift (i.e. bucket 0 refers to 2^sm_shift). + */ + (void) printf("\tOn-disk histogram:\n"); + dump_histogram(sm->sm_phys->smp_histogram, + SPACE_MAP_HISTOGRAM_SIZE(sm), sm->sm_shift); + } + + if (dump_opt['d'] > 5 || dump_opt['m'] > 3) { + ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift)); mutex_enter(&msp->ms_lock); - dump_spacemap(spa->spa_meta_objset, smo, sm); + dump_spacemap(spa->spa_meta_objset, msp->ms_sm); mutex_exit(&msp->ms_lock); } } @@ -684,7 +764,7 @@ dump_dde(const ddt_t *ddt, const ddt_entry_t *dde, uint64_t index) if (ddp->ddp_phys_birth == 0) continue; ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk); - sprintf_blkptr(blkbuf, &blk); + snprintf_blkptr(blkbuf, sizeof (blkbuf), &blk); (void) printf("index %llx refcnt %llu %s %s\n", (u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt, types[p], blkbuf); @@ -801,9 +881,9 @@ dump_all_ddts(spa_t *spa) } static void -dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size) +dump_dtl_seg(void *arg, uint64_t start, uint64_t size) { - char *prefix = (void *)sm; + char *prefix = arg; (void) printf("%s [%llu,%llu) length %llu\n", prefix, @@ -833,28 +913,32 @@ dump_dtl(vdev_t *vd, int indent) required ? "DTL-required" : "DTL-expendable"); for (int t = 0; t < DTL_TYPES; t++) { - space_map_t *sm = &vd->vdev_dtl[t]; - if (sm->sm_space == 0) + range_tree_t *rt = vd->vdev_dtl[t]; + if (range_tree_space(rt) == 0) continue; (void) snprintf(prefix, sizeof (prefix), "\t%*s%s", indent + 2, "", name[t]); - mutex_enter(sm->sm_lock); - space_map_walk(sm, dump_dtl_seg, (void *)prefix); - mutex_exit(sm->sm_lock); + mutex_enter(rt->rt_lock); + range_tree_walk(rt, dump_dtl_seg, prefix); + mutex_exit(rt->rt_lock); if (dump_opt['d'] > 5 && vd->vdev_children == 0) - dump_spacemap(spa->spa_meta_objset, - &vd->vdev_dtl_smo, sm); + dump_spacemap(spa->spa_meta_objset, vd->vdev_dtl_sm); } for (int c = 0; c < vd->vdev_children; c++) dump_dtl(vd->vdev_child[c], indent + 4); } +/* from spa_history.c: spa_history_create_obj() */ +#define HIS_BUF_LEN_DEF (128 << 10) +#define HIS_BUF_LEN_MAX (1 << 30) + static void dump_history(spa_t *spa) { nvlist_t **events = NULL; - char buf[SPA_MAXBLOCKSIZE]; + char *buf = NULL; + uint64_t bufsize = HIS_BUF_LEN_DEF; uint64_t resid, len, off = 0; uint_t num = 0; int error; @@ -863,8 +947,11 @@ dump_history(spa_t *spa) char tbuf[30]; char internalstr[MAXPATHLEN]; + if ((buf = malloc(bufsize)) == NULL) + (void) fprintf(stderr, "Unable to read history: " + "out of memory\n"); do { - len = sizeof (buf); + len = bufsize; if ((error = spa_history_get(spa, &off, &len, buf)) != 0) { (void) fprintf(stderr, "Unable to read history: " @@ -874,9 +961,26 @@ dump_history(spa_t *spa) if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0) break; - off -= resid; + + /* + * If the history block is too big, double the buffer + * size and try again. + */ + if (resid == len) { + free(buf); + buf = NULL; + + bufsize <<= 1; + if ((bufsize >= HIS_BUF_LEN_MAX) || + ((buf = malloc(bufsize)) == NULL)) { + (void) fprintf(stderr, "Unable to read history: " + "out of memory\n"); + return; + } + } } while (len != 0); + free(buf); (void) printf("\nHistory:\n"); for (int i = 0; i < num; i++) { @@ -945,31 +1049,39 @@ blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb) } static void -sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp) +snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp) { const dva_t *dva = bp->blk_dva; int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1; if (dump_opt['b'] >= 6) { - sprintf_blkptr(blkbuf, bp); + snprintf_blkptr(blkbuf, buflen, bp); return; } blkbuf[0] = '\0'; for (int i = 0; i < ndvas; i++) - (void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ", + (void) snprintf(blkbuf + strlen(blkbuf), + buflen - strlen(blkbuf), "%llu:%llx:%llx ", (u_longlong_t)DVA_GET_VDEV(&dva[i]), (u_longlong_t)DVA_GET_OFFSET(&dva[i]), (u_longlong_t)DVA_GET_ASIZE(&dva[i])); - (void) sprintf(blkbuf + strlen(blkbuf), - "%llxL/%llxP F=%llu B=%llu/%llu", - (u_longlong_t)BP_GET_LSIZE(bp), - (u_longlong_t)BP_GET_PSIZE(bp), - (u_longlong_t)bp->blk_fill, - (u_longlong_t)bp->blk_birth, - (u_longlong_t)BP_PHYSICAL_BIRTH(bp)); + if (BP_IS_HOLE(bp)) { + (void) snprintf(blkbuf + strlen(blkbuf), + buflen - strlen(blkbuf), "B=%llu", + (u_longlong_t)bp->blk_birth); + } else { + (void) snprintf(blkbuf + strlen(blkbuf), + buflen - strlen(blkbuf), + "%llxL/%llxP F=%llu B=%llu/%llu", + (u_longlong_t)BP_GET_LSIZE(bp), + (u_longlong_t)BP_GET_PSIZE(bp), + (u_longlong_t)bp->blk_fill, + (u_longlong_t)bp->blk_birth, + (u_longlong_t)BP_PHYSICAL_BIRTH(bp)); + } } static void @@ -994,7 +1106,7 @@ print_indirect(blkptr_t *bp, const zbookmark_t *zb, } } - sprintf_blkptr_compact(blkbuf, bp); + snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp); (void) printf("%s\n", blkbuf); } @@ -1009,7 +1121,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp, print_indirect(bp, zb, dnp); - if (BP_GET_LEVEL(bp) > 0) { + if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) { uint32_t flags = ARC_WAIT; int i; blkptr_t *cbp; @@ -1134,7 +1246,7 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size) zdb_nicenum(ds->ds_compressed_bytes, compressed); zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed); zdb_nicenum(ds->ds_unique_bytes, unique); - sprintf_blkptr(blkbuf, &ds->ds_bp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), &ds->ds_bp); (void) printf("\t\tdir_obj = %llu\n", (u_longlong_t)ds->ds_dir_obj); @@ -1179,7 +1291,7 @@ dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) char blkbuf[BP_SPRINTF_LEN]; if (bp->blk_birth != 0) { - sprintf_blkptr(blkbuf, bp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); (void) printf("\t%s\n", blkbuf); } return (0); @@ -1217,7 +1329,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) char blkbuf[BP_SPRINTF_LEN]; ASSERT(bp->blk_birth != 0); - sprintf_blkptr_compact(blkbuf, bp); + snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp); (void) printf("\t%s\n", blkbuf); return (0); } @@ -1716,8 +1828,9 @@ dump_dir(objset_t *os) zdb_nicenum(refdbytes, numbuf); if (verbosity >= 4) { - (void) sprintf(blkbuf, ", rootbp "); - (void) sprintf_blkptr(blkbuf + strlen(blkbuf), os->os_rootbp); + (void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp "); + (void) snprintf_blkptr(blkbuf + strlen(blkbuf), + sizeof (blkbuf) - strlen(blkbuf), os->os_rootbp); } else { blkbuf[0] = '\0'; } @@ -1747,7 +1860,7 @@ dump_dir(objset_t *os) if (verbosity < 2) return; - if (os->os_rootbp->blk_birth == 0) + if (BP_IS_HOLE(os->os_rootbp)) return; dump_object(os, 0, verbosity, &print_header); @@ -1788,7 +1901,7 @@ dump_uberblock(uberblock_t *ub, const char *header, const char *footer) (u_longlong_t)ub->ub_timestamp, asctime(localtime(×tamp))); if (dump_opt['u'] >= 3) { char blkbuf[BP_SPRINTF_LEN]; - sprintf_blkptr(blkbuf, &ub->ub_rootbp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), &ub->ub_rootbp); (void) printf("\trootbp = %s\n", blkbuf); } (void) printf(footer ? footer : ""); @@ -2079,16 +2192,68 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp, bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0); } +/* ARGSUSED */ +static void +zdb_blkptr_done(zio_t *zio) +{ + spa_t *spa = zio->io_spa; + blkptr_t *bp = zio->io_bp; + int ioerr = zio->io_error; + zdb_cb_t *zcb = zio->io_private; + zbookmark_t *zb = &zio->io_bookmark; + + zio_data_buf_free(zio->io_data, zio->io_size); + + mutex_enter(&spa->spa_scrub_lock); + spa->spa_scrub_inflight--; + cv_broadcast(&spa->spa_scrub_io_cv); + + if (ioerr && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { + char blkbuf[BP_SPRINTF_LEN]; + + zcb->zcb_haderrors = 1; + zcb->zcb_errors[ioerr]++; + + if (dump_opt['b'] >= 2) + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); + else + blkbuf[0] = '\0'; + + (void) printf("zdb_blkptr_cb: " + "Got error %d reading " + "<%llu, %llu, %lld, %llx> %s -- skipping\n", + ioerr, + (u_longlong_t)zb->zb_objset, + (u_longlong_t)zb->zb_object, + (u_longlong_t)zb->zb_level, + (u_longlong_t)zb->zb_blkid, + blkbuf); + } + mutex_exit(&spa->spa_scrub_lock); +} + +/* ARGSUSED */ static int zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg) { zdb_cb_t *zcb = arg; - char blkbuf[BP_SPRINTF_LEN]; dmu_object_type_t type; boolean_t is_metadata; - if (bp == NULL) + if (dump_opt['b'] >= 5 && bp->blk_birth > 0) { + char blkbuf[BP_SPRINTF_LEN]; + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); + (void) printf("objset %llu object %llu " + "level %lld offset 0x%llx %s\n", + (u_longlong_t)zb->zb_objset, + (u_longlong_t)zb->zb_object, + (longlong_t)zb->zb_level, + (u_longlong_t)blkid2offset(dnp, bp, zb), + blkbuf); + } + + if (BP_IS_HOLE(bp)) return (0); type = BP_GET_TYPE(bp); @@ -2099,53 +2264,26 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)); if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) { - int ioerr; size_t size = BP_GET_PSIZE(bp); - void *data = malloc(size); + void *data = zio_data_buf_alloc(size); int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW; /* If it's an intent log block, failure is expected. */ if (zb->zb_level == ZB_ZIL_LEVEL) flags |= ZIO_FLAG_SPECULATIVE; - ioerr = zio_wait(zio_read(NULL, spa, bp, data, size, - NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb)); + mutex_enter(&spa->spa_scrub_lock); + while (spa->spa_scrub_inflight > max_inflight) + cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); + spa->spa_scrub_inflight++; + mutex_exit(&spa->spa_scrub_lock); - free(data); - if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) { - zcb->zcb_haderrors = 1; - zcb->zcb_errors[ioerr]++; - - if (dump_opt['b'] >= 2) - sprintf_blkptr(blkbuf, bp); - else - blkbuf[0] = '\0'; - - (void) printf("zdb_blkptr_cb: " - "Got error %d reading " - "<%llu, %llu, %lld, %llx> %s -- skipping\n", - ioerr, - (u_longlong_t)zb->zb_objset, - (u_longlong_t)zb->zb_object, - (u_longlong_t)zb->zb_level, - (u_longlong_t)zb->zb_blkid, - blkbuf); - } + zio_nowait(zio_read(NULL, spa, bp, data, size, + zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb)); } zcb->zcb_readfails = 0; - if (dump_opt['b'] >= 5) { - sprintf_blkptr(blkbuf, bp); - (void) printf("objset %llu object %llu " - "level %lld offset 0x%llx %s\n", - (u_longlong_t)zb->zb_objset, - (u_longlong_t)zb->zb_object, - (longlong_t)zb->zb_level, - (u_longlong_t)blkid2offset(dnp, bp, zb), - blkbuf); - } - if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) && gethrtime() > zcb->zcb_lastprint + NANOSEC) { uint64_t now = gethrtime(); @@ -2172,39 +2310,17 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, } static void -zdb_leak(space_map_t *sm, uint64_t start, uint64_t size) +zdb_leak(void *arg, uint64_t start, uint64_t size) { - vdev_t *vd = sm->sm_ppd; + vdev_t *vd = arg; (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n", (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size); } -/* ARGSUSED */ -static void -zdb_space_map_load(space_map_t *sm) -{ -} - -static void -zdb_space_map_unload(space_map_t *sm) -{ - space_map_vacate(sm, zdb_leak, sm); -} - -/* ARGSUSED */ -static void -zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size) -{ -} - -static space_map_ops_t zdb_space_map_ops = { - zdb_space_map_load, - zdb_space_map_unload, +static metaslab_ops_t zdb_metaslab_ops = { NULL, /* alloc */ - zdb_space_map_claim, - NULL, /* free */ - NULL /* maxsize */ + NULL /* fragmented */ }; static void @@ -2259,11 +2375,21 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb) for (int m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; mutex_enter(&msp->ms_lock); - space_map_unload(msp->ms_map); - VERIFY(space_map_load(msp->ms_map, - &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo, - spa->spa_meta_objset) == 0); - msp->ms_map->sm_ppd = vd; + metaslab_unload(msp); + + /* + * For leak detection, we overload the metaslab + * ms_tree to contain allocated segments + * instead of free segments. As a result, + * we can't use the normal metaslab_load/unload + * interfaces. + */ + if (msp->ms_sm != NULL) { + msp->ms_ops = &zdb_metaslab_ops; + VERIFY0(space_map_load(msp->ms_sm, + msp->ms_tree, SM_ALLOC)); + msp->ms_loaded = B_TRUE; + } mutex_exit(&msp->ms_lock); } } @@ -2286,7 +2412,20 @@ zdb_leak_fini(spa_t *spa) for (int m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; mutex_enter(&msp->ms_lock); - space_map_unload(msp->ms_map); + + /* + * The ms_tree has been overloaded to + * contain allocated segments. Now that we + * finished traversing all blocks, any + * block that remains in the ms_tree + * represents an allocated block that we + * did not claim during the traversal. + * Claimed blocks would have been removed + * from the ms_tree. + */ + range_tree_vacate(msp->ms_tree, zdb_leak, vd); + msp->ms_loaded = B_FALSE; + mutex_exit(&msp->ms_lock); } } @@ -2301,7 +2440,7 @@ count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) if (dump_opt['b'] >= 5) { char blkbuf[BP_SPRINTF_LEN]; - sprintf_blkptr(blkbuf, bp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); (void) printf("[%s] %s\n", "deferred free", blkbuf); } @@ -2344,8 +2483,7 @@ dump_block_stats(spa_t *spa) (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj, count_block_cb, &zcb, NULL); } - if (spa_feature_is_active(spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + if (spa_feature_is_active(spa, SPA_FEATURE_ASYNC_DESTROY)) { VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset, spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb, &zcb, NULL)); @@ -2358,6 +2496,18 @@ dump_block_stats(spa_t *spa) zcb.zcb_start = zcb.zcb_lastprint = gethrtime(); zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); + /* + * If we've traversed the data blocks then we need to wait for those + * I/Os to complete. We leverage "The Godfather" zio to wait on + * all async I/Os to complete. + */ + if (dump_opt['c']) { + (void) zio_wait(spa->spa_async_zio_root); + spa->spa_async_zio_root = zio_root(spa, NULL, NULL, + ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | + ZIO_FLAG_GODFATHER); + } + if (zcb.zcb_haderrors) { (void) printf("\nError counts:\n\n"); (void) printf("\t%5s %s\n", "errno", "count"); @@ -2489,7 +2639,7 @@ dump_block_stats(spa_t *spa) "(in 512-byte sectors): " "number of blocks\n"); dump_histogram(zb->zb_psize_histogram, - PSIZE_HISTO_SIZE); + PSIZE_HISTO_SIZE, 0); } } } @@ -2524,7 +2674,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, avl_index_t where; zdb_ddt_entry_t *zdde, zdde_search; - if (bp == NULL) + if (BP_IS_HOLE(bp)) return (0); if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) { @@ -2591,7 +2741,8 @@ dump_simulated_ddt(spa_t *spa) dds.dds_ref_psize = zdde->zdde_ref_psize; dds.dds_ref_dsize = zdde->zdde_ref_dsize; - ddt_stat_add(&ddh_total.ddh_stat[highbit(refcnt) - 1], &dds, 0); + ddt_stat_add(&ddh_total.ddh_stat[highbit64(refcnt) - 1], + &dds, 0); umem_free(zdde, sizeof (*zdde)); } @@ -2646,7 +2797,7 @@ dump_zpool(spa_t *spa) } if (spa_feature_is_active(spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + SPA_FEATURE_ASYNC_DESTROY)) { dump_bptree(spa->spa_meta_objset, spa->spa_dsl_pool->dp_bptree_obj, "Pool dataset frees"); @@ -2659,6 +2810,9 @@ dump_zpool(spa_t *spa) if (dump_opt['b'] || dump_opt['c']) rc = dump_block_stats(spa); + if (rc == 0) + rc = verify_spacemap_refcounts(spa); + if (dump_opt['s']) show_pool_stats(spa); @@ -2688,7 +2842,7 @@ zdb_print_blkptr(blkptr_t *bp, int flags) if (flags & ZDB_FLAG_BSWAP) byteswap_uint64_array((void *)bp, sizeof (blkptr_t)); - sprintf_blkptr(blkbuf, bp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); (void) printf("%s\n", blkbuf); } @@ -2884,6 +3038,7 @@ zdb_read_block(char *thing, spa_t *spa) free(dup); return; } + i += p - &flagstr[i + 1]; /* skip over the number */ } } @@ -3124,7 +3279,7 @@ main(int argc, char **argv) dprintf_setup(&argc, argv); - while ((c = getopt(argc, argv, "bcdhilmsuCDRSAFLXevp:t:U:P")) != -1) { + while ((c = getopt(argc, argv, "bcdhilmM:suCDRSAFLXevp:t:U:P")) != -1) { switch (c) { case 'b': case 'c': @@ -3153,6 +3308,15 @@ main(int argc, char **argv) case 'v': verbose++; break; + case 'M': + max_inflight = strtoull(optarg, NULL, 0); + if (max_inflight == 0) { + (void) fprintf(stderr, "maximum number " + "of inflight I/Os must be greater " + "than 0\n"); + usage(); + } + break; case 'p': if (searchdirs == NULL) { searchdirs = umem_alloc(sizeof (char *), diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c index a0ed985..17f7ad3 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c @@ -24,6 +24,10 @@ */ /* + * Copyright (c) 2013 by Delphix. All rights reserved. + */ + +/* * Print intent log header and statistics. */ @@ -47,7 +51,7 @@ print_log_bp(const blkptr_t *bp, const char *prefix) { char blkbuf[BP_SPRINTF_LEN]; - sprintf_blkptr(blkbuf, bp); + snprintf_blkptr(blkbuf, sizeof (blkbuf), bp); (void) printf("%s%s\n", prefix, blkbuf); } @@ -132,6 +136,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr) if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) { (void) printf("%shas blkptr, %s\n", prefix, + !BP_IS_HOLE(bp) && bp->blk_birth >= spa_first_txg(zilog->zl_spa) ? "will claim" : "won't claim"); print_log_bp(bp, prefix); @@ -139,8 +144,6 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr) if (BP_IS_HOLE(bp)) { (void) printf("\t\t\tLSIZE 0x%llx\n", (u_longlong_t)BP_GET_LSIZE(bp)); - } - if (bp->blk_birth == 0) { bzero(buf, sizeof (buf)); (void) printf("%s<hole>\n", prefix); return; @@ -313,7 +316,8 @@ print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) if (verbose >= 5) { (void) strcpy(blkbuf, ", "); - sprintf_blkptr(blkbuf + strlen(blkbuf), bp); + snprintf_blkptr(blkbuf + strlen(blkbuf), + sizeof (blkbuf) - strlen(blkbuf), bp); } else { blkbuf[0] = '\0'; } @@ -361,7 +365,7 @@ dump_intent_log(zilog_t *zilog) int verbose = MAX(dump_opt['d'], dump_opt['i']); int i; - if (zh->zh_log.blk_birth == 0 || verbose < 1) + if (BP_IS_HOLE(&zh->zh_log) || verbose < 1) return; (void) printf("\n ZIL header: claim_txg %llu, " diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 index 9daec71..9eb3082 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 @@ -18,17 +18,19 @@ .\" information: Portions Copyright [yyyy] [name of copyright owner] .\" .\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved. -.\" Copyright (c) 2012 by Delphix. All rights reserved. +.\" Copyright (c) 2013 by Delphix. All rights reserved. .\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org> .\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org> .\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org> .\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved. .\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved. -.\" Copyright (c) 2013, Joyent, Inc. All rights reserved. +.\" Copyright (c) 2014, Joyent, Inc. All rights reserved. +.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org> +.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org> .\" .\" $FreeBSD$ .\" -.Dd September 20, 2013 +.Dd April 23, 2014 .Dt ZFS 8 .Os .Sh NAME @@ -56,12 +58,17 @@ .Cm destroy .Op Fl dnpRrv .Sm off -.Ar snapshot -.Op % Ns Ar snapname +.Ar filesystem Ns | Ns volume +.Ns @snap +.Op % Ns Ar snap +.Op , Ns Ar snap Op % Ns Ar snap .Op , Ns ... .Sm on .Nm -.Cm snapshot +.Cm destroy +.Ar filesystem Ns | Ns Ar volume Ns # Ns Ar bookmark +.Nm +.Cm snapshot Ns | Ns Cm snap .Op Fl r .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... .Ar filesystem@snapname Ns | Ns Ar volume@snapname @@ -101,7 +108,7 @@ .Nm .Cm list .Op Fl r Ns | Ns Fl d Ar depth -.Op Fl H +.Op Fl Hp .Op Fl o Ar property Ns Oo , Ns property Ns Oc Ns ... .Op Fl t Ar type Ns Oo , Ns type Ns Oc Ns ... .Oo Fl s Ar property Oc Ns ... @@ -157,7 +164,7 @@ .Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... .Fl a | Ar filesystem .Nm -.Cm unmount +.Cm unmount Ns | Ns Cm umount .Op Fl f .Fl a | Ar filesystem Ns | Ns Ar mountpoint .Nm @@ -167,16 +174,24 @@ .Cm unshare .Fl a | Ar filesystem Ns | Ns Ar mountpoint .Nm +.Cm bookmark +.Ar snapshot +.Ar bookmark +.Nm .Cm send .Op Fl DnPpRv .Op Fl i Ar snapshot | Fl I Ar snapshot .Ar snapshot .Nm -.Cm receive +.Cm send +.Op Fl i Ar snapshot Ns | Ns bookmark +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot +.Nm +.Cm receive Ns | Ns Cm recv .Op Fl vnFu .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot .Nm -.Cm receive +.Cm receive Ns | Ns Cm recv .Op Fl vnFu .Op Fl d | e .Ar filesystem @@ -527,6 +542,13 @@ if the snapshot has been marked for deferred destroy by using the .Qq Nm Cm destroy -d command. Otherwise, the property is .Cm off . +.It Sy filesystem_count +The total number of filesystems and volumes that exist under this location in the +dataset tree. +This value is only available when a +.Sy filesystem_limit +has +been set somewhere in the tree under which the dataset resides. .It Sy logicalreferenced The amount of space that is .Qq logically @@ -585,6 +607,12 @@ The compression ratio achieved for the space of this dataset, expressed as a multiplier. See also the .Sy compressratio property. +.It Sy snapshot_count +The total number of snapshots that exist under this location in the dataset tree. +This value is only available when a +.Sy snapshot_limit +has been set somewhere +in the tree under which the dataset resides. .It Sy type The type of dataset: .Sy filesystem , volume , No or Sy snapshot . @@ -1005,6 +1033,23 @@ The .Sy mlslabel property is currently not supported on .Fx . +.It Sy filesystem_limit Ns = Ns Ar count | Cm none +Limits the number of filesystems and volumes that can exist under this point in +the dataset tree. +The limit is not enforced if the user is allowed to change +the limit. +Setting a +.Sy filesystem_limit +on a descendent of a filesystem that +already has a +.Sy filesystem_limit +does not override the ancestor's +.Sy filesystem_limit , +but rather imposes an additional limit. +This feature must be enabled to be used +.Po see +.Xr zpool-features 7 +.Pc . .It Sy mountpoint Ns = Ns Ar path | Cm none | legacy Controls the mount point used for this file system. See the .Qq Sx Mount Points @@ -1046,6 +1091,27 @@ the ancestor's quota, but rather imposes an additional limit. Quotas cannot be set on volumes, as the .Sy volsize property acts as an implicit quota. +.It Sy snapshot_limit Ns = Ns Ar count | Cm none +Limits the number of snapshots that can be created on a dataset and its +descendents. +Setting a +.Sy snapshot_limit +on a descendent of a dataset that already +has a +.Sy snapshot_limit +does not override the ancestor's +.Sy snapshot_limit , +but +rather imposes an additional limit. +The limit is not enforced if the user is +allowed to change the limit. +For example, this means that recursive snapshots +taken from the global zone are counted against each delegated dataset within +a jail. +This feature must be enabled to be used +.Po see +.Xr zpool-features 7 +.Pc . .It Sy userquota@ Ns Ar user Ns = Ns Ar size | Cm none Limits the amount of space consumed by the specified user. Similar to the @@ -1291,6 +1357,38 @@ Consequently, writes to a sparse volume can fail with when the pool is low on space. For a sparse volume, changes to .Sy volsize are not reflected in the reservation. +.It Sy volmode Ns = Ns Cm default | geom | dev | none +This property specifies how volumes should be exposed to the OS. +Setting it to +.Sy geom +exposes volumes as +.Xr geom 4 +providers, providing maximal functionality. +Setting it to +.Sy dev +exposes volumes only as cdev device in devfs. +Such volumes can be accessed only as raw disk device files, i.e. they +can not be partitioned, mounted, participate in RAIDs, etc, but they +are faster, and in some use scenarios with untrusted consumer, such as +NAS or VM storage, can be more safe. +Volumes with property set to +.Sy none +are not exposed outside ZFS, but can be snapshoted, cloned, replicated, etc, +that can be suitable for backup purposes. +Value +.Sy default +means that volumes exposition is controlled by system-wide sysctl/tunable +.Va vfs.zfs.vol.mode , +where +.Sy geom , +.Sy dev +and +.Sy none +are encoded as 1, 2 and 3 respectively. +The default values is +.Sy geom . +This property can be changed any time, but so far it is processed only +during volume creation and pool import. .It Sy vscan Ns = Ns Cm off | on The .Sy vscan @@ -1320,10 +1418,21 @@ features being supported, the new file system will have the default values for these properties. .Bl -tag -width 4n .It Sy casesensitivity Ns = Ns Cm sensitive | insensitive | mixed +Indicates whether the file name matching algorithm used by the file system +should be case-sensitive, case-insensitive, or allow a combination of both +styles of matching. The default value for the +.Sy casesensitivity +property is +.Cm sensitive . +Traditionally, UNIX and POSIX file systems have case-sensitive file names. +.Pp The +.Cm mixed +value for the .Sy casesensitivity -property is currently not supported on -.Fx . +property indicates that the +file system can support requests for both case-sensitive and case-insensitive +matching behavior. .It Sy normalization Ns = Ns Cm none | formC | formD | formKC | formKD Indicates whether the file system should perform a .Sy unicode @@ -1653,7 +1762,14 @@ options, as they can destroy large portions of a pool and cause unexpected behavior for mounted file systems in use. .It Xo .Nm -.Cm snapshot +.Cm destroy +.Ar filesystem Ns | Ns Ar volume Ns # Ns Ar bookmark +.Xc +.Pp +The given bookmark is destroyed. +.It Xo +.Nm +.Cm snapshot Ns | Ns Cm snap .Op Fl r .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... .Ar filesystem@snapname Ns | Ns volume@snapname @@ -1685,14 +1801,24 @@ Roll back the given dataset to a previous snapshot. When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than the most recent one. In -order to do so, all intermediate snapshots must be destroyed by specifying the +order to do so, all intermediate snapshots and bookmarks must be destroyed +by specifying the .Fl r option. +.Pp +The +.Fl rR +options do not recursively destroy the child snapshots of a +recursive snapshot. +Only direct snapshots of the specified filesystem +are destroyed by either of these options. +To completely roll back a +recursive snapshot, you must rollback the individual child snapshots. .Bl -tag -width indent .It Fl r -Recursively destroy any snapshots more recent than the one specified. +Destroy any snapshots and bookmarks more recent than the one specified. .It Fl R -Recursively destroy any more recent snapshots, as well as any clones of those +Destroy any more recent snapshots and bookmarks, as well as any clones of those snapshots. .It Fl f Used with the @@ -1806,7 +1932,7 @@ only dataset that can be renamed recursively. .Nm .Cm list .Op Fl r Ns | Ns Fl d Ar depth -.Op Fl H +.Op Fl Hp .Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... .Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... .Oo Fl s Ar property Oc Ns ... @@ -1837,6 +1963,8 @@ will display only the dataset and its direct children. .It Fl H Used for scripting mode. Do not print headers and separate fields by a single tab instead of arbitrary white space. +.It Fl p +Display numbers in parsable (exact) values. .It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... A comma-separated list of properties to display. The property must be: .Bl -bullet -offset 2n @@ -1865,7 +1993,7 @@ syntax. A comma-separated list of types to display, where .Ar type is one of -.Sy filesystem , snapshot , volume , No or Sy all . +.Sy filesystem , snapshot , snap , volume , bookmark , No or Sy all . For example, specifying .Fl t Cm snapshot displays only snapshots. @@ -1962,7 +2090,7 @@ sections. The special value .Cm all can be used to display all properties that apply to the given dataset's type -(filesystem, volume, or snapshot). +(filesystem, volume, snapshot, or bookmark). .Bl -tag -width indent .It Fl r Recursively display properties for any children. @@ -1977,7 +2105,7 @@ Display output in a form more easily parsed by scripts. Any headers are omitted, and fields are explicitly separated by a single tab instead of an arbitrary amount of space. .It Fl p -Display numbers in parseable (exact) values. +Display numbers in parsable (exact) values. .It Fl o Cm all | Ar field Ns Oo , Ns Ar field Oc Ns ... A comma-separated list of columns to display. Supported values are .Sy name,property,value,received,source . @@ -2194,7 +2322,7 @@ Mount the specified filesystem. .El .It Xo .Nm -.Cm unmount +.Cm unmount Ns | Ns Cm umount .Op Fl f .Fl a | Ar filesystem Ns | Ns Ar mountpoint .Xc @@ -2280,6 +2408,26 @@ file system shared on the system. .El .It Xo .Nm +.Cm bookmark +.Ar snapshot +.Ar bookmark +.Xc +.Pp +Creates a bookmark of the given snapshot. +Bookmarks mark the point in time +when the snapshot was created, and can be used as the incremental source for +a +.Qq Nm Cm send +command. +.Pp +This feature must be enabled to be used. +See +.Xr zpool-features 7 +for details on ZFS feature flags and the +.Sy bookmark +feature. +.It Xo +.Nm .Cm send .Op Fl DnPpRv .Op Fl i Ar snapshot | Fl I Ar snapshot @@ -2298,17 +2446,15 @@ a file or to a different system (for example, using By default, a full stream is generated. .Bl -tag -width indent .It Fl i Ar snapshot -Generate an incremental stream from the -.Fl i Ar snapshot -to the last -.Ar snapshot . -The incremental source (the -.Fl i Ar snapshot ) -can be specified as the last component of the snapshot name (for example, the -part after the -.Sy @ ) , -and it is assumed to be from the same file system as the last -.Ar snapshot . +Generate an incremental stream from the first +.Ar snapshot Pq the incremental source +to the second +.Ar snapshot Pq the incremental target . +The incremental source can be specified as the last component of the +snapshot name +.Pq the Em @ No character and following +and +it is assumed to be from the same file system as the incremental target. .Pp If the destination is a clone, the source may be the origin snapshot, which must be fully specified (for example, @@ -2316,15 +2462,16 @@ must be fully specified (for example, not just .Cm @origin ) . .It Fl I Ar snapshot -Generate a stream package that sends all intermediary snapshots from the -.Fl I Ar snapshot -to the last +Generate a stream package that sends all intermediary snapshots from the first +.Ar snapshot +to the second .Ar snapshot . For example, .Ic -I @a fs@d is similar to .Ic -i @a fs@b; -i @b fs@c; -i @c fs@d . -The incremental source snapshot may be specified as with the +The incremental +source may be specified as with the .Fl i option. .It Fl R @@ -2377,13 +2524,42 @@ on future versions of .Tn ZFS . .It Xo .Nm -.Cm receive +.Cm send +.Op Fl i Ar snapshot Ns | Ns Ar bookmark +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot +.Xc +.Pp +Generate a send stream, which may be of a filesystem, and may be +incremental from a bookmark. +If the destination is a filesystem or volume, +the pool must be read-only, or the filesystem must not be mounted. +When the +stream generated from a filesystem or volume is received, the default snapshot +name will be +.Pq --head-- . +.Bl -tag -width indent +.It Fl i Ar snapshot Ns | Ns bookmark +Generate an incremental send stream. +The incremental source must be an earlier +snapshot in the destination's history. +It will commonly be an earlier +snapshot in the destination's filesystem, in which case it can be +specified as the last component of the name +.Pq the Em # No or Em @ No character and following . +.Pp +If the incremental target is a clone, the incremental source can +be the origin snapshot, or an earlier snapshot in the origin's filesystem, +or the origin's origin, etc. +.El +.It Xo +.Nm +.Cm receive Ns | Ns Cm recv .Op Fl vnFu .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot .Xc .It Xo .Nm -.Cm receive +.Cm receive Ns | Ns Cm recv .Op Fl vnFu .Op Fl d | e .Ar filesystem @@ -2474,7 +2650,7 @@ option to verify the name the receive operation would use. Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by -.Qq Nm Cm send Fl R Fi iI ) , +.Qq Nm Cm send Fl R Bro Fl i | Fl I Brc ) , destroy snapshots and file systems that do not exist on the sending side. .El .It Xo @@ -2613,6 +2789,7 @@ protocol .It dedup Ta property .It devices Ta property .It exec Ta property +.It filesystem_limit Ta property .It logbias Ta property .It jailed Ta property .It mlslabel Ta property @@ -2631,6 +2808,7 @@ protocol .It sharenfs Ta property .It sharesmb Ta property .It snapdir Ta property +.It snapshot_limit Ta property .It sync Ta property .It utf8only Ta property .It version Ta property @@ -2819,7 +2997,7 @@ option of .It \&P Ta event port (not supported on Fx ) .El .It Fl H -Give more parseable tab-separated output, without header lines and without +Give more parsable tab-separated output, without header lines and without arrows. .It Fl t Display the path's inode change time as the first column of output. @@ -2977,10 +3155,12 @@ pool/home/bob compression on local pool/home/bob atime on default pool/home/bob devices on default pool/home/bob exec on default +pool/home/bob filesystem_limit none default pool/home/bob setuid on default pool/home/bob readonly off default pool/home/bob jailed off default pool/home/bob snapdir hidden default +pool/home/bob snapshot_limit none default pool/home/bob aclmode discard default pool/home/bob aclinherit restricted default pool/home/bob canmount on default diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c index 62cd9d0..626d69c 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c @@ -18,10 +18,13 @@ * * CDDL HEADER END */ + /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <libintl.h> @@ -70,7 +73,7 @@ uu_avl_pool_t *avl_pool; * Include snaps if they were requested or if this a zfs list where types * were not specified and the "listsnapshots" property is set on this pool. */ -static int +static boolean_t zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb) { zpool_handle_t *zph; @@ -90,8 +93,9 @@ static int zfs_callback(zfs_handle_t *zhp, void *data) { callback_data_t *cb = data; - int dontclose = 0; - int include_snaps = zfs_include_snapshots(zhp, cb); + boolean_t dontclose = B_FALSE; + boolean_t include_snaps = zfs_include_snapshots(zhp, cb); + boolean_t include_bmarks = (cb->cb_types & ZFS_TYPE_BOOKMARK); if ((zfs_get_type(zhp) & cb->cb_types) || ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) { @@ -109,14 +113,15 @@ zfs_callback(zfs_handle_t *zhp, void *data) cb->cb_props_table); if (zfs_expand_proplist(zhp, cb->cb_proplist, - (cb->cb_flags & ZFS_ITER_RECVD_PROPS)) + (cb->cb_flags & ZFS_ITER_RECVD_PROPS), + (cb->cb_flags & ZFS_ITER_LITERAL_PROPS)) != 0) { free(node); return (-1); } } uu_avl_insert(cb->cb_avl, node, idx); - dontclose = 1; + dontclose = B_TRUE; } else { free(node); } @@ -131,11 +136,14 @@ zfs_callback(zfs_handle_t *zhp, void *data) cb->cb_depth++; if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) (void) zfs_iter_filesystems(zhp, zfs_callback, data); - if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps) { + if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT | + ZFS_TYPE_BOOKMARK)) == 0) && include_snaps) (void) zfs_iter_snapshots(zhp, (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback, data); - } + if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT | + ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks) + (void) zfs_iter_bookmarks(zhp, zfs_callback, data); cb->cb_depth--; } diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h index a287374..f4f0e5b 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h @@ -18,9 +18,11 @@ * * CDDL HEADER END */ + /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #ifndef ZFS_ITER_H @@ -44,6 +46,7 @@ typedef struct zfs_sort_column { #define ZFS_ITER_DEPTH_LIMIT (1 << 3) #define ZFS_ITER_RECVD_PROPS (1 << 4) #define ZFS_ITER_SIMPLE (1 << 5) +#define ZFS_ITER_LITERAL_PROPS (1 << 6) int zfs_for_each(int, char **, int options, zfs_type_t, zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *); diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c index a2d4973..4c5f8d44 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c @@ -21,14 +21,14 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #include <assert.h> @@ -107,6 +107,7 @@ static int zfs_do_release(int argc, char **argv); static int zfs_do_diff(int argc, char **argv); static int zfs_do_jail(int argc, char **argv); static int zfs_do_unjail(int argc, char **argv); +static int zfs_do_bookmark(int argc, char **argv); /* * Enable a reasonable set of defaults for libumem debugging on DEBUG builds. @@ -155,6 +156,7 @@ typedef enum { HELP_HOLDS, HELP_RELEASE, HELP_DIFF, + HELP_BOOKMARK, } zfs_help_t; typedef struct zfs_command { @@ -181,6 +183,7 @@ static zfs_command_t command_table[] = { { "clone", zfs_do_clone, HELP_CLONE }, { "promote", zfs_do_promote, HELP_PROMOTE }, { "rename", zfs_do_rename, HELP_RENAME }, + { "bookmark", zfs_do_bookmark, HELP_BOOKMARK }, { NULL }, { "list", zfs_do_list, HELP_LIST }, { NULL }, @@ -231,11 +234,12 @@ get_usage(zfs_help_t idx) case HELP_DESTROY: return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n" "\tdestroy [-dnpRrv] " - "<snapshot>[%<snapname>][,...]\n")); + "<filesystem|volume>@<snap>[%<snap>][,...]\n" + "\tdestroy <filesystem|volume>#<bookmark>\n")); case HELP_GET: return (gettext("\tget [-rHp] [-d max] " - "[-o \"all\" | field[,...]] [-t type[,...]] " - "[-s source[,...]]\n" + "[-o \"all\" | field[,...]]\n" + "\t [-t type[,...]] [-s source[,...]]\n" "\t <\"all\" | property[,...]> " "[filesystem|volume|snapshot] ...\n")); case HELP_INHERIT: @@ -249,9 +253,8 @@ get_usage(zfs_help_t idx) case HELP_UNJAIL: return (gettext("\tunjail <jailid|jailname> <filesystem>\n")); case HELP_LIST: - return (gettext("\tlist [-rH][-d max] " - "[-o property[,...]] [-t type[,...]] [-s property] ...\n" - "\t [-S property] ... " + return (gettext("\tlist [-Hp] [-r|-d max] [-o property[,...]] " + "[-s property]...\n\t [-S property]... [-t type[,...]] " "[filesystem|volume|snapshot] ...\n")); case HELP_MOUNT: return (gettext("\tmount\n" @@ -259,31 +262,32 @@ get_usage(zfs_help_t idx) case HELP_PROMOTE: return (gettext("\tpromote <clone-filesystem>\n")); case HELP_RECEIVE: - return (gettext("\treceive [-vnFu] <filesystem|volume|" + return (gettext("\treceive|recv [-vnFu] <filesystem|volume|" "snapshot>\n" - "\treceive [-vnFu] [-d | -e] <filesystem>\n")); + "\treceive|recv [-vnFu] [-d | -e] <filesystem>\n")); case HELP_RENAME: return (gettext("\trename [-f] <filesystem|volume|snapshot> " "<filesystem|volume|snapshot>\n" - "\trename [-f] -p <filesystem|volume> " - "<filesystem|volume>\n" + "\trename [-f] -p <filesystem|volume> <filesystem|volume>\n" "\trename -r <snapshot> <snapshot>\n" "\trename -u [-p] <filesystem> <filesystem>")); case HELP_ROLLBACK: return (gettext("\trollback [-rRf] <snapshot>\n")); case HELP_SEND: - return (gettext("\tsend [-DnPpRv] " - "[-i snapshot | -I snapshot] <snapshot>\n")); + return (gettext("\tsend [-DnPpRv] [-[iI] snapshot] " + "<snapshot>\n" + "\tsend [-i snapshot|bookmark] " + "<filesystem|volume|snapshot>\n")); case HELP_SET: return (gettext("\tset <property=value> " "<filesystem|volume|snapshot> ...\n")); case HELP_SHARE: return (gettext("\tshare <-a | filesystem>\n")); case HELP_SNAPSHOT: - return (gettext("\tsnapshot [-r] [-o property=value] ... " - "<filesystem@snapname|volume@snapname> ...\n")); + return (gettext("\tsnapshot|snap [-r] [-o property=value] ... " + "<filesystem|volume>@<snap> ...\n")); case HELP_UNMOUNT: - return (gettext("\tunmount [-f] " + return (gettext("\tunmount|umount [-f] " "<-a | filesystem|mountpoint>\n")); case HELP_UNSHARE: return (gettext("\tunshare " @@ -310,12 +314,14 @@ get_usage(zfs_help_t idx) "<filesystem|volume>\n")); case HELP_USERSPACE: return (gettext("\tuserspace [-Hinp] [-o field[,...]] " - "[-s field] ...\n\t[-S field] ... " - "[-t type[,...]] <filesystem|snapshot>\n")); + "[-s field] ...\n" + "\t [-S field] ... [-t type[,...]] " + "<filesystem|snapshot>\n")); case HELP_GROUPSPACE: return (gettext("\tgroupspace [-Hinp] [-o field[,...]] " - "[-s field] ...\n\t[-S field] ... " - "[-t type[,...]] <filesystem|snapshot>\n")); + "[-s field] ...\n" + "\t [-S field] ... [-t type[,...]] " + "<filesystem|snapshot>\n")); case HELP_HOLD: return (gettext("\thold [-r] <tag> <snapshot> ...\n")); case HELP_HOLDS: @@ -325,6 +331,8 @@ get_usage(zfs_help_t idx) case HELP_DIFF: return (gettext("\tdiff [-FHt] <snapshot> " "[snapshot|filesystem]\n")); + case HELP_BOOKMARK: + return (gettext("\tbookmark <snapshot> <bookmark>\n")); } abort(); @@ -487,9 +495,8 @@ usage(boolean_t requested) } static int -parseprop(nvlist_t *props) +parseprop(nvlist_t *props, char *propname) { - char *propname = optarg; char *propval, *strval; if ((propval = strchr(propname, '=')) == NULL) { @@ -518,7 +525,7 @@ parse_depth(char *opt, int *flags) depth = (int)strtol(opt, &tmp, 0); if (*tmp) { (void) fprintf(stderr, - gettext("%s is not an integer\n"), optarg); + gettext("%s is not an integer\n"), opt); usage(B_FALSE); } if (depth < 0) { @@ -609,7 +616,7 @@ zfs_do_clone(int argc, char **argv) while ((c = getopt(argc, argv, "o:p")) != -1) { switch (c) { case 'o': - if (parseprop(props)) + if (parseprop(props, optarg)) return (1); break; case 'p': @@ -759,7 +766,7 @@ zfs_do_create(int argc, char **argv) nomem(); break; case 'o': - if (parseprop(props)) + if (parseprop(props, optarg)) goto error; break; case 's': @@ -927,6 +934,7 @@ typedef struct destroy_cbdata { char *cb_prevsnap; int64_t cb_snapused; char *cb_snapspec; + char *cb_bookmark; } destroy_cbdata_t; /* @@ -1196,7 +1204,7 @@ zfs_do_destroy(int argc, char **argv) int err = 0; int c; zfs_handle_t *zhp = NULL; - char *at; + char *at, *pound; zfs_type_t type = ZFS_TYPE_DATASET; /* check options */ @@ -1248,6 +1256,7 @@ zfs_do_destroy(int argc, char **argv) } at = strchr(argv[0], '@'); + pound = strchr(argv[0], '#'); if (at != NULL) { /* Build the list of snaps to destroy in cb_nvl. */ @@ -1309,6 +1318,46 @@ zfs_do_destroy(int argc, char **argv) if (err != 0) rv = 1; + } else if (pound != NULL) { + int err; + nvlist_t *nvl; + + if (cb.cb_dryrun) { + (void) fprintf(stderr, + "dryrun is not supported with bookmark\n"); + return (-1); + } + + if (cb.cb_defer_destroy) { + (void) fprintf(stderr, + "defer destroy is not supported with bookmark\n"); + return (-1); + } + + if (cb.cb_recurse) { + (void) fprintf(stderr, + "recursive is not supported with bookmark\n"); + return (-1); + } + + if (!zfs_bookmark_exists(argv[0])) { + (void) fprintf(stderr, gettext("bookmark '%s' " + "does not exist.\n"), argv[0]); + return (1); + } + + nvl = fnvlist_alloc(); + fnvlist_add_boolean(nvl, argv[0]); + + err = lzc_destroy_bookmarks(nvl, NULL); + if (err != 0) { + (void) zfs_standard_error(g_zfs, err, + "cannot destroy bookmark"); + } + + nvlist_free(cb.cb_nvl); + + return (err); } else { /* Open the given dataset */ if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL) @@ -1671,7 +1720,8 @@ zfs_do_get(int argc, char **argv) flags &= ~ZFS_ITER_PROP_LISTSNAPS; while (*optarg != '\0') { static char *type_subopts[] = { "filesystem", - "volume", "snapshot", "all", NULL }; + "volume", "snapshot", "bookmark", + "all", NULL }; switch (getsubopt(&optarg, type_subopts, &value)) { @@ -1685,7 +1735,11 @@ zfs_do_get(int argc, char **argv) types |= ZFS_TYPE_SNAPSHOT; break; case 3: - types = ZFS_TYPE_DATASET; + types |= ZFS_TYPE_BOOKMARK; + break; + case 4: + types = ZFS_TYPE_DATASET | + ZFS_TYPE_BOOKMARK; break; default: @@ -2011,7 +2065,7 @@ zfs_do_upgrade(int argc, char **argv) boolean_t showversions = B_FALSE; int ret = 0; upgrade_cbdata_t cb = { 0 }; - char c; + int c; int flags = ZFS_ITER_ARGS_CAN_BE_PATHS; /* check options */ @@ -2124,7 +2178,7 @@ zfs_do_upgrade(int argc, char **argv) * -i Translate SID to POSIX ID. * -n Print numeric ID instead of user/group name. * -o Control which fields to display. - * -p Use exact (parseable) numeric output. + * -p Use exact (parsable) numeric output. * -s Specify sort columns, descending order. * -S Specify sort columns, ascending order. * -t Control which object types to display. @@ -2158,7 +2212,7 @@ static int us_type_bits[] = { USTYPE_SMB_USR, USTYPE_ALL }; -static char *us_type_names[] = { "posixgroup", "posxiuser", "smbgroup", +static char *us_type_names[] = { "posixgroup", "posixuser", "smbgroup", "smbuser", "all" }; typedef struct us_node { @@ -2811,24 +2865,25 @@ zfs_do_userspace(int argc, char **argv) } /* - * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...] - * [-s property [-s property]...] [-S property [-S property]...] - * <dataset> ... + * list [-Hp][-r|-d max] [-o property[,...]] [-s property] ... [-S property] ... + * [-t type[,...]] [filesystem|volume|snapshot] ... * - * -r Recurse over all children + * -H Scripted mode; elide headers and separate columns by tabs. + * -p Display values in parsable (literal) format. + * -r Recurse over all children. * -d Limit recursion by depth. - * -H Scripted mode; elide headers and separate columns by tabs * -o Control which fields to display. - * -t Control which object types to display. * -s Specify sort columns, descending order. * -S Specify sort columns, ascending order. + * -t Control which object types to display. * - * When given no arguments, lists all filesystems in the system. + * When given no arguments, list all filesystems in the system. * Otherwise, list the specified datasets, optionally recursing down them if * '-r' is specified. */ typedef struct list_cbdata { boolean_t cb_first; + boolean_t cb_literal; boolean_t cb_scripted; zprop_list_t *cb_proplist; } list_cbdata_t; @@ -2837,8 +2892,9 @@ typedef struct list_cbdata { * Given a list of columns to display, output appropriate headers for each one. */ static void -print_header(zprop_list_t *pl) +print_header(list_cbdata_t *cb) { + zprop_list_t *pl = cb->cb_proplist; char headerbuf[ZFS_MAXPROPLEN]; const char *header; int i; @@ -2879,19 +2935,19 @@ print_header(zprop_list_t *pl) * to the described layout. */ static void -print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted) +print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb) { + zprop_list_t *pl = cb->cb_proplist; boolean_t first = B_TRUE; char property[ZFS_MAXPROPLEN]; nvlist_t *userprops = zfs_get_user_props(zhp); nvlist_t *propval; char *propstr; boolean_t right_justify; - int width; for (; pl != NULL; pl = pl->pl_next) { if (!first) { - if (scripted) + if (cb->cb_scripted) (void) printf("\t"); else (void) printf(" "); @@ -2906,22 +2962,22 @@ print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted) right_justify = zfs_prop_align_right(pl->pl_prop); } else if (pl->pl_prop != ZPROP_INVAL) { if (zfs_prop_get(zhp, pl->pl_prop, property, - sizeof (property), NULL, NULL, 0, B_FALSE) != 0) + sizeof (property), NULL, NULL, 0, + cb->cb_literal) != 0) propstr = "-"; else propstr = property; - right_justify = zfs_prop_align_right(pl->pl_prop); } else if (zfs_prop_userquota(pl->pl_user_prop)) { if (zfs_prop_get_userquota(zhp, pl->pl_user_prop, - property, sizeof (property), B_FALSE) != 0) + property, sizeof (property), cb->cb_literal) != 0) propstr = "-"; else propstr = property; right_justify = B_TRUE; } else if (zfs_prop_written(pl->pl_user_prop)) { if (zfs_prop_get_written(zhp, pl->pl_user_prop, - property, sizeof (property), B_FALSE) != 0) + property, sizeof (property), cb->cb_literal) != 0) propstr = "-"; else propstr = property; @@ -2936,19 +2992,17 @@ print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted) right_justify = B_FALSE; } - width = pl->pl_width; - /* * If this is being called in scripted mode, or if this is the * last column and it is left-justified, don't include a width * format specifier. */ - if (scripted || (pl->pl_next == NULL && !right_justify)) + if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) (void) printf("%s", propstr); else if (right_justify) - (void) printf("%*s", width, propstr); + (void) printf("%*s", pl->pl_width, propstr); else - (void) printf("%-*s", width, propstr); + (void) printf("%-*s", pl->pl_width, propstr); } (void) printf("\n"); @@ -2964,11 +3018,11 @@ list_callback(zfs_handle_t *zhp, void *data) if (cbp->cb_first) { if (!cbp->cb_scripted) - print_header(cbp->cb_proplist); + print_header(cbp); cbp->cb_first = B_FALSE; } - print_dataset(zhp, cbp->cb_proplist, cbp->cb_scripted); + print_dataset(zhp, cbp); return (0); } @@ -2977,7 +3031,6 @@ static int zfs_do_list(int argc, char **argv) { int c; - boolean_t scripted = B_FALSE; static char default_fields[] = "name,used,available,referenced,mountpoint"; int types = ZFS_TYPE_DATASET; @@ -2991,11 +3044,15 @@ zfs_do_list(int argc, char **argv) int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS; /* check options */ - while ((c = getopt(argc, argv, ":d:o:rt:Hs:S:")) != -1) { + while ((c = getopt(argc, argv, "HS:d:o:prs:t:")) != -1) { switch (c) { case 'o': fields = optarg; break; + case 'p': + cb.cb_literal = B_TRUE; + flags |= ZFS_ITER_LITERAL_PROPS; + break; case 'd': limit = parse_depth(optarg, &flags); break; @@ -3003,7 +3060,7 @@ zfs_do_list(int argc, char **argv) flags |= ZFS_ITER_RECURSE; break; case 'H': - scripted = B_TRUE; + cb.cb_scripted = B_TRUE; break; case 's': if (zfs_add_sort_column(&sortcol, optarg, @@ -3027,7 +3084,8 @@ zfs_do_list(int argc, char **argv) flags &= ~ZFS_ITER_PROP_LISTSNAPS; while (*optarg != '\0') { static char *type_subopts[] = { "filesystem", - "volume", "snapshot", "all", NULL }; + "volume", "snapshot", "snap", "bookmark", + "all", NULL }; switch (getsubopt(&optarg, type_subopts, &value)) { @@ -3038,12 +3096,16 @@ zfs_do_list(int argc, char **argv) types |= ZFS_TYPE_VOLUME; break; case 2: + case 3: types |= ZFS_TYPE_SNAPSHOT; break; - case 3: - types = ZFS_TYPE_DATASET; + case 4: + types |= ZFS_TYPE_BOOKMARK; + break; + case 5: + types = ZFS_TYPE_DATASET | + ZFS_TYPE_BOOKMARK; break; - default: (void) fprintf(stderr, gettext("invalid type '%s'\n"), @@ -3092,7 +3154,6 @@ zfs_do_list(int argc, char **argv) != 0) usage(B_FALSE); - cb.cb_scripted = scripted; cb.cb_first = B_TRUE; ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist, @@ -3284,9 +3345,29 @@ typedef struct rollback_cbdata { char *cb_target; int cb_error; boolean_t cb_recurse; - boolean_t cb_dependent; } rollback_cbdata_t; +static int +rollback_check_dependent(zfs_handle_t *zhp, void *data) +{ + rollback_cbdata_t *cbp = data; + + if (cbp->cb_first && cbp->cb_recurse) { + (void) fprintf(stderr, gettext("cannot rollback to " + "'%s': clones of previous snapshots exist\n"), + cbp->cb_target); + (void) fprintf(stderr, gettext("use '-R' to " + "force deletion of the following clones and " + "dependents:\n")); + cbp->cb_first = 0; + cbp->cb_error = 1; + } + + (void) fprintf(stderr, "%s\n", zfs_get_name(zhp)); + + zfs_close(zhp); + return (0); +} /* * Report any snapshots more recent than the one specified. Used when '-r' is * not specified. We reuse this same callback for the snapshot dependents - if @@ -3303,52 +3384,30 @@ rollback_check(zfs_handle_t *zhp, void *data) return (0); } - if (!cbp->cb_dependent) { - if (strcmp(zfs_get_name(zhp), cbp->cb_target) != 0 && - zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && - zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > - cbp->cb_create) { - - if (cbp->cb_first && !cbp->cb_recurse) { - (void) fprintf(stderr, gettext("cannot " - "rollback to '%s': more recent snapshots " - "exist\n"), - cbp->cb_target); - (void) fprintf(stderr, gettext("use '-r' to " - "force deletion of the following " - "snapshots:\n")); - cbp->cb_first = 0; - cbp->cb_error = 1; - } - - if (cbp->cb_recurse) { - cbp->cb_dependent = B_TRUE; - if (zfs_iter_dependents(zhp, B_TRUE, - rollback_check, cbp) != 0) { - zfs_close(zhp); - return (-1); - } - cbp->cb_dependent = B_FALSE; - } else { - (void) fprintf(stderr, "%s\n", - zfs_get_name(zhp)); - } - } - } else { - if (cbp->cb_first && cbp->cb_recurse) { - (void) fprintf(stderr, gettext("cannot rollback to " - "'%s': clones of previous snapshots exist\n"), + if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) { + if (cbp->cb_first && !cbp->cb_recurse) { + (void) fprintf(stderr, gettext("cannot " + "rollback to '%s': more recent snapshots " + "or bookmarks exist\n"), cbp->cb_target); - (void) fprintf(stderr, gettext("use '-R' to " - "force deletion of the following clones and " - "dependents:\n")); + (void) fprintf(stderr, gettext("use '-r' to " + "force deletion of the following " + "snapshots and bookmarks:\n")); cbp->cb_first = 0; cbp->cb_error = 1; } - (void) fprintf(stderr, "%s\n", zfs_get_name(zhp)); + if (cbp->cb_recurse) { + if (zfs_iter_dependents(zhp, B_TRUE, + rollback_check_dependent, cbp) != 0) { + zfs_close(zhp); + return (-1); + } + } else { + (void) fprintf(stderr, "%s\n", + zfs_get_name(zhp)); + } } - zfs_close(zhp); return (0); } @@ -3418,7 +3477,9 @@ zfs_do_rollback(int argc, char **argv) cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG); cb.cb_first = B_TRUE; cb.cb_error = 0; - if ((ret = zfs_iter_children(zhp, rollback_check, &cb)) != 0) + if ((ret = zfs_iter_snapshots(zhp, B_FALSE, rollback_check, &cb)) != 0) + goto out; + if ((ret = zfs_iter_bookmarks(zhp, rollback_check, &cb)) != 0) goto out; if ((ret = cb.cb_error) != 0) @@ -3560,7 +3621,7 @@ static int zfs_do_snapshot(int argc, char **argv) { int ret = 0; - char c; + int c; nvlist_t *props; snap_cbdata_t sd = { 0 }; boolean_t multiple_snaps = B_FALSE; @@ -3574,7 +3635,7 @@ zfs_do_snapshot(int argc, char **argv) while ((c = getopt(argc, argv, "ro:")) != -1) { switch (c) { case 'o': - if (parseprop(props)) + if (parseprop(props, optarg)) return (1); break; case 'r': @@ -3713,12 +3774,45 @@ zfs_do_send(int argc, char **argv) return (1); } - cp = strchr(argv[0], '@'); - if (cp == NULL) { - (void) fprintf(stderr, - gettext("argument must be a snapshot\n")); - usage(B_FALSE); + /* + * Special case sending a filesystem, or from a bookmark. + */ + if (strchr(argv[0], '@') == NULL || + (fromname && strchr(fromname, '#') != NULL)) { + char frombuf[ZFS_MAXNAMELEN]; + + if (flags.replicate || flags.doall || flags.props || + flags.dedup || flags.dryrun || flags.verbose || + flags.progress) { + (void) fprintf(stderr, + gettext("Error: " + "Unsupported flag with filesystem or bookmark.\n")); + return (1); + } + + zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET); + if (zhp == NULL) + return (1); + + if (fromname != NULL && + (fromname[0] == '#' || fromname[0] == '@')) { + /* + * Incremental source name begins with # or @. + * Default to same fs as target. + */ + (void) strncpy(frombuf, argv[0], sizeof (frombuf)); + cp = strchr(frombuf, '@'); + if (cp != NULL) + *cp = '\0'; + (void) strlcat(frombuf, fromname, sizeof (frombuf)); + fromname = frombuf; + } + err = zfs_send_one(zhp, fromname, STDOUT_FILENO); + zfs_close(zhp); + return (err != 0); } + + cp = strchr(argv[0], '@'); *cp = '\0'; toname = cp + 1; zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); @@ -3874,6 +3968,7 @@ zfs_do_receive(int argc, char **argv) #define ZFS_DELEG_PERM_HOLD "hold" #define ZFS_DELEG_PERM_RELEASE "release" #define ZFS_DELEG_PERM_DIFF "diff" +#define ZFS_DELEG_PERM_BOOKMARK "bookmark" #define ZFS_NUM_DELEG_NOTES ZFS_DELEG_NOTE_NONE @@ -3893,6 +3988,7 @@ static zfs_deleg_perm_tab_t zfs_deleg_perm_tbl[] = { { ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND }, { ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE }, { ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT }, + { ZFS_DELEG_PERM_BOOKMARK, ZFS_DELEG_NOTE_BOOKMARK }, { ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA }, { ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED }, @@ -6664,6 +6760,108 @@ zfs_do_diff(int argc, char **argv) return (err != 0); } +/* + * zfs bookmark <fs@snap> <fs#bmark> + * + * Creates a bookmark with the given name from the given snapshot. + */ +static int +zfs_do_bookmark(int argc, char **argv) +{ + char snapname[ZFS_MAXNAMELEN]; + zfs_handle_t *zhp; + nvlist_t *nvl; + int ret = 0; + int c; + + /* check options */ + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + case '?': + (void) fprintf(stderr, + gettext("invalid option '%c'\n"), optopt); + goto usage; + } + } + + argc -= optind; + argv += optind; + + /* check number of arguments */ + if (argc < 1) { + (void) fprintf(stderr, gettext("missing snapshot argument\n")); + goto usage; + } + if (argc < 2) { + (void) fprintf(stderr, gettext("missing bookmark argument\n")); + goto usage; + } + + if (strchr(argv[1], '#') == NULL) { + (void) fprintf(stderr, + gettext("invalid bookmark name '%s' -- " + "must contain a '#'\n"), argv[1]); + goto usage; + } + + if (argv[0][0] == '@') { + /* + * Snapshot name begins with @. + * Default to same fs as bookmark. + */ + (void) strncpy(snapname, argv[1], sizeof (snapname)); + *strchr(snapname, '#') = '\0'; + (void) strlcat(snapname, argv[0], sizeof (snapname)); + } else { + (void) strncpy(snapname, argv[0], sizeof (snapname)); + } + zhp = zfs_open(g_zfs, snapname, ZFS_TYPE_SNAPSHOT); + if (zhp == NULL) + goto usage; + zfs_close(zhp); + + + nvl = fnvlist_alloc(); + fnvlist_add_string(nvl, argv[1], snapname); + ret = lzc_bookmark(nvl, NULL); + fnvlist_free(nvl); + + if (ret != 0) { + const char *err_msg; + char errbuf[1024]; + + (void) snprintf(errbuf, sizeof (errbuf), + dgettext(TEXT_DOMAIN, + "cannot create bookmark '%s'"), argv[1]); + + switch (ret) { + case EXDEV: + err_msg = "bookmark is in a different pool"; + break; + case EEXIST: + err_msg = "bookmark exists"; + break; + case EINVAL: + err_msg = "invalid argument"; + break; + case ENOTSUP: + err_msg = "bookmark feature not enabled"; + break; + default: + err_msg = "unknown error"; + break; + } + (void) fprintf(stderr, "%s: %s\n", errbuf, + dgettext(TEXT_DOMAIN, err_msg)); + } + + return (ret); + +usage: + usage(B_FALSE); + return (-1); +} + int main(int argc, char **argv) { @@ -6726,6 +6924,12 @@ main(int argc, char **argv) cmdname = "receive"; /* + * The 'snap' command is an alias for 'snapshot' + */ + if (strcmp(cmdname, "snap") == 0) + cmdname = "snapshot"; + + /* * Special case '-?' */ if (strcmp(cmdname, "-?") == 0) diff --git a/cddl/contrib/opensolaris/cmd/zhack/zhack.c b/cddl/contrib/opensolaris/cmd/zhack/zhack.c index 1eb8713..ace8c32 100644 --- a/cddl/contrib/opensolaris/cmd/zhack/zhack.c +++ b/cddl/contrib/opensolaris/cmd/zhack/zhack.c @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. */ @@ -85,10 +85,15 @@ usage(void) static void -fatal(const char *fmt, ...) +fatal(spa_t *spa, void *tag, const char *fmt, ...) { va_list ap; + if (spa != NULL) { + spa_close(spa, tag); + (void) spa_export(g_pool, NULL, B_TRUE, B_FALSE); + } + va_start(ap, fmt); (void) fprintf(stderr, "%s: ", cmdname); (void) vfprintf(stderr, fmt, ap); @@ -159,13 +164,14 @@ import_pool(const char *target, boolean_t readonly) g_importargs.can_be_active = B_TRUE; if (zpool_search_import(g_zfs, &g_importargs) != NULL || spa_open(target, &spa, FTAG) == 0) { - fatal("cannot import '%s': pool is active; run " - "\"zpool export %s\" first\n", - g_pool, g_pool); + fatal(spa, FTAG, "cannot import '%s': pool is " + "active; run " "\"zpool export %s\" " + "first\n", g_pool, g_pool); } } - fatal("cannot import '%s': no such pool available\n", g_pool); + fatal(NULL, FTAG, "cannot import '%s': no such pool " + "available\n", g_pool); } elem = nvlist_next_nvpair(pools, NULL); @@ -186,7 +192,8 @@ import_pool(const char *target, boolean_t readonly) error = 0; if (error) - fatal("can't import '%s': %s", name, strerror(error)); + fatal(NULL, FTAG, "can't import '%s': %s", name, + strerror(error)); } static void @@ -201,10 +208,11 @@ zhack_spa_open(const char *target, boolean_t readonly, void *tag, spa_t **spa) zfeature_checks_disable = B_FALSE; if (err != 0) - fatal("cannot open '%s': %s", target, strerror(err)); + fatal(*spa, FTAG, "cannot open '%s': %s", target, + strerror(err)); if (spa_version(*spa) < SPA_VERSION_FEATURES) { - fatal("'%s' has version %d, features not enabled", target, - (int)spa_version(*spa)); + fatal(*spa, FTAG, "'%s' has version %d, features not enabled", + target, (int)spa_version(*spa)); } } @@ -269,18 +277,22 @@ zhack_do_feature_stat(int argc, char **argv) dump_obj(os, spa->spa_feat_for_read_obj, "for_read"); dump_obj(os, spa->spa_feat_for_write_obj, "for_write"); dump_obj(os, spa->spa_feat_desc_obj, "descriptions"); + if (spa_feature_is_active(spa, SPA_FEATURE_ENABLED_TXG)) { + dump_obj(os, spa->spa_feat_enabled_txg_obj, "enabled_txg"); + } dump_mos(spa); spa_close(spa, FTAG); } static void -feature_enable_sync(void *arg, dmu_tx_t *tx) +zhack_feature_enable_sync(void *arg, dmu_tx_t *tx) { spa_t *spa = dmu_tx_pool(tx)->dp_spa; zfeature_info_t *feature = arg; - spa_feature_enable(spa, feature, tx); + feature_enable_sync(spa, feature, tx); + spa_history_log_internal(spa, "zhack enable feature", tx, "name=%s can_readonly=%u", feature->fi_guid, feature->fi_can_readonly); @@ -294,7 +306,7 @@ zhack_do_feature_enable(int argc, char **argv) spa_t *spa; objset_t *mos; zfeature_info_t feature; - zfeature_info_t *nodeps[] = { NULL }; + spa_feature_t nodeps[] = { SPA_FEATURE_NONE }; /* * Features are not added to the pool's label until their refcounts @@ -304,7 +316,9 @@ zhack_do_feature_enable(int argc, char **argv) feature.fi_uname = "zhack"; feature.fi_mos = B_FALSE; feature.fi_can_readonly = B_FALSE; + feature.fi_activate_on_enable = B_FALSE; feature.fi_depends = nodeps; + feature.fi_feature = SPA_FEATURE_NONE; optind = 1; while ((c = getopt(argc, argv, "rmd:")) != -1) { @@ -336,18 +350,19 @@ zhack_do_feature_enable(int argc, char **argv) feature.fi_guid = argv[1]; if (!zfeature_is_valid_guid(feature.fi_guid)) - fatal("invalid feature guid: %s", feature.fi_guid); + fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid); zhack_spa_open(target, B_FALSE, FTAG, &spa); mos = spa->spa_meta_objset; - if (0 == zfeature_lookup_guid(feature.fi_guid, NULL)) - fatal("'%s' is a real feature, will not enable"); + if (zfeature_is_supported(feature.fi_guid)) + fatal(spa, FTAG, "'%s' is a real feature, will not enable"); if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid)) - fatal("feature already enabled: %s", feature.fi_guid); + fatal(spa, FTAG, "feature already enabled: %s", + feature.fi_guid); VERIFY0(dsl_sync_task(spa_name(spa), NULL, - feature_enable_sync, &feature, 5)); + zhack_feature_enable_sync, &feature, 5)); spa_close(spa, FTAG); @@ -359,8 +374,10 @@ feature_incr_sync(void *arg, dmu_tx_t *tx) { spa_t *spa = dmu_tx_pool(tx)->dp_spa; zfeature_info_t *feature = arg; + uint64_t refcount; - spa_feature_incr(spa, feature, tx); + VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount)); + feature_sync(spa, feature, refcount + 1, tx); spa_history_log_internal(spa, "zhack feature incr", tx, "name=%s", feature->fi_guid); } @@ -370,8 +387,10 @@ feature_decr_sync(void *arg, dmu_tx_t *tx) { spa_t *spa = dmu_tx_pool(tx)->dp_spa; zfeature_info_t *feature = arg; + uint64_t refcount; - spa_feature_decr(spa, feature, tx); + VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount)); + feature_sync(spa, feature, refcount - 1, tx); spa_history_log_internal(spa, "zhack feature decr", tx, "name=%s", feature->fi_guid); } @@ -385,7 +404,7 @@ zhack_do_feature_ref(int argc, char **argv) spa_t *spa; objset_t *mos; zfeature_info_t feature; - zfeature_info_t *nodeps[] = { NULL }; + spa_feature_t nodeps[] = { SPA_FEATURE_NONE }; /* * fi_desc does not matter here because it was written to disk @@ -397,6 +416,7 @@ zhack_do_feature_ref(int argc, char **argv) feature.fi_mos = B_FALSE; feature.fi_desc = NULL; feature.fi_depends = nodeps; + feature.fi_feature = SPA_FEATURE_NONE; optind = 1; while ((c = getopt(argc, argv, "md")) != -1) { @@ -423,13 +443,15 @@ zhack_do_feature_ref(int argc, char **argv) feature.fi_guid = argv[1]; if (!zfeature_is_valid_guid(feature.fi_guid)) - fatal("invalid feature guid: %s", feature.fi_guid); + fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid); zhack_spa_open(target, B_FALSE, FTAG, &spa); mos = spa->spa_meta_objset; - if (0 == zfeature_lookup_guid(feature.fi_guid, NULL)) - fatal("'%s' is a real feature, will not change refcount"); + if (zfeature_is_supported(feature.fi_guid)) { + fatal(spa, FTAG, + "'%s' is a real feature, will not change refcount"); + } if (0 == zap_contains(mos, spa->spa_feat_for_read_obj, feature.fi_guid)) { @@ -438,11 +460,17 @@ zhack_do_feature_ref(int argc, char **argv) feature.fi_guid)) { feature.fi_can_readonly = B_TRUE; } else { - fatal("feature is not enabled: %s", feature.fi_guid); + fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid); } - if (decr && !spa_feature_is_active(spa, &feature)) - fatal("feature refcount already 0: %s", feature.fi_guid); + if (decr) { + uint64_t count; + if (feature_get_refcount_from_disk(spa, &feature, + &count) == 0 && count != 0) { + fatal(spa, FTAG, "feature refcount already 0: %s", + feature.fi_guid); + } + } VERIFY0(dsl_sync_task(spa_name(spa), NULL, decr ? feature_decr_sync : feature_incr_sync, &feature, 5)); @@ -530,8 +558,8 @@ main(int argc, char **argv) usage(); } - if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_TRUE) != 0) { - fatal("pool export failed; " + if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_FALSE) != 0) { + fatal(NULL, FTAG, "pool export failed; " "changes may not be committed to disk\n"); } diff --git a/cddl/contrib/opensolaris/cmd/zinject/zinject.c b/cddl/contrib/opensolaris/cmd/zinject/zinject.c index 994d687..ddcdb1f 100644 --- a/cddl/contrib/opensolaris/cmd/zinject/zinject.c +++ b/cddl/contrib/opensolaris/cmd/zinject/zinject.c @@ -148,6 +148,7 @@ #include <sys/mount.h> #include <libzfs.h> +#include <libzfs_compat.h> #undef verify /* both libzfs.h and zfs_context.h want to define this */ diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 index d018acc..5560de9 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 20, 2013 +.Dd April 23, 2014 .Dt ZPOOL-FEATURES 7 .Os .Sh NAME @@ -187,6 +187,23 @@ This feature is .Sy active while there are any filesystems, volumes, or snapshots which were created after enabling this feature. +.It Sy filesystem_limits +.Bl -column "READ\-ONLY COMPATIBLE" "com.joyent:filesystem_limits" +.It GUID Ta com.joyent:filesystem_limits +.It READ\-ONLY COMPATIBLE Ta yes +.It DEPENDENCIES Ta extensible_dataset +.El +.Pp +This feature enables filesystem and snapshot limits. +These limits can be used +to control how many filesystems and/or snapshots can be created at the point in +the tree on which the limits are set. +.Pp +This feature is +.Sy active +once either of the limit properties has been +set on a dataset. +Once activated the feature is never deactivated. .It Sy lz4_compress .Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress" .It GUID Ta org.illumos:lz4_compress @@ -222,12 +239,16 @@ command. Please note that doing so will immediately activate the .Sy lz4_compress feature on the underlying -pool (even before any data is written). Since this feature is not -read-only compatible, this operation will render the pool unimportable -on systems without support for the +pool +.Pq even before any data is written , +and the feature will not be +deactivated. +Since this feature is not read-only compatible, this +operation will render the pool unimportable on systems without support +for the .Sy lz4_compress -feature. At the -moment, this operation cannot be reversed. Booting off of +feature. +Booting off of .Sy lz4 -compressed root pools is supported. .It Sy multi_vdev_crash_dump @@ -251,6 +272,130 @@ configuration. .\" .Xr dumpon 8 .\" command to configure a .\" dump device on a pool comprised of multiple vdevs. +.It Sy spacemap_histogram +.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:spacemap_histogram" +.It GUID Ta com.delphix:spacemap_histogram +.It READ\-ONLY COMPATIBLE Ta yes +.It DEPENDENCIES Ta none +.El +.Pp +This features allows ZFS to maintain more information about how free space +is organized within the pool. If this feature is +.Sy enabled , +ZFS will +set this feature to +.Sy active +when a new space map object is created or +an existing space map is upgraded to the new format. +Once the feature is +.Sy active , +it will remain in that state until the pool is destroyed. +.It Sy extensible_dataset +.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:extensible_dataset" +.It GUID Ta com.delphix:extensible_dataset +.It READ\-ONLY COMPATIBLE Ta no +.It DEPENDENCIES Ta none +.El +.Pp +This feature allows more flexible use of internal ZFS data structures, +and exists for other features to depend on. +.Pp +This feature will be +.Sy active +when the first dependent feature uses it, +and will be returned to the +.Sy enabled +state when all datasets that use +this feature are destroyed. +.It Sy bookmarks +.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:bookmarks" +.It GUID Ta com.delphix:bookmarks +.It READ\-ONLY COMPATIBLE Ta yes +.It DEPENDENCIES Ta extensible_dataset +.El +.Pp +This feature enables use of the +.Nm zfs +.Cm bookmark +subcommand. +.Pp +This feature is +.Sy active +while any bookmarks exist in the pool. +All bookmarks in the pool can be listed by running +.Nm zfs +.Cm list +.Fl t No bookmark Fl r Ar poolname . +.It Sy enabled_txg +.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:enabled_txg" +.It GUID Ta com.delphix:enabled_txg +.It READ\-ONLY COMPATIBLE Ta yes +.It DEPENDENCIES Ta none +.El +.Pp +Once this feature is enabled ZFS records the transaction group number +in which new features are enabled. This has no user-visible impact, +but other features may depend on this feature. +.Pp +This feature becomes +.Sy active +as soon as it is enabled and will +never return to being +.Sy enabled . +.It Sy hole_birth +.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:hole_birth" +.It GUID Ta com.delphix:hole_birth +.It READ\-ONLY COMPATIBLE Ta no +.It DEPENDENCIES Ta enabled_txg +.El +.Pp +This feature improves performance of incremental sends +.Pq Dq zfs send -i +and receives for objects with many holes. +The most common case of +hole-filled objects is zvols. +.Pp +An incremental send stream from snapshot +.Sy A +to snapshot +.Sy B +contains information about every block that changed between +.Sy A +and +.Sy B . +Blocks which did not change between those snapshots can be +identified and omitted from the stream using a piece of metadata called +the 'block birth time', but birth times are not recorded for holes +.Pq blocks filled only with zeroes . +Since holes created after +.Sy A +cannot be +distinguished from holes created before +.Sy A , +information about every +hole in the entire filesystem or zvol is included in the send stream. +.Pp +For workloads where holes are rare this is not a problem. +However, when +incrementally replicating filesystems or zvols with many holes +.Pq for example a zvol formatted with another filesystem +a lot of time will +be spent sending and receiving unnecessary information about holes that +already exist on the receiving side. +.Pp +Once the +.Sy hole_birth +feature has been enabled the block birth times +of all new holes will be recorded. +Incremental sends between snapshots +created after this feature is enabled will use this new metadata to avoid +sending information about holes that already exist on the receiving side. +.Pp +This feature becomes +.Sy active +as soon as it is enabled and will +never return to being +.Sy enabled . .El .Sh SEE ALSO .Xr zpool 8 diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8 index 715439b..1061e45 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8 @@ -1,5 +1,6 @@ '\" te .\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>. +.\" Copyright (c) 2013-2014, Xin Li <delphij@FreeBSD.org>. .\" All Rights Reserved. .\" .\" The contents of this file are subject to the terms of the @@ -25,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 14, 2013 +.Dd March 28, 2014 .Dt ZPOOL 8 .Os .Sh NAME @@ -70,6 +71,8 @@ .Ar pool ... .Nm .Cm get +.Op Fl Hp +.Op Fl o Ar field Ns Op , Ns Ar ... .Ar all | property Ns Op , Ns Ar ... .Ar pool ... .Nm @@ -120,7 +123,7 @@ .Ar device .Nm .Cm list -.Op Fl H +.Op Fl Hpv .Op Fl o Ar property Ns Op , Ns Ar ... .Op Fl T Cm d Ns | Ns Cm u .Op Ar pool @@ -141,6 +144,9 @@ .Cm remove .Ar pool device ... .Nm +.Cm reopen +.Ar pool +.Nm .Cm replace .Op Fl f .Ar pool device @@ -621,6 +627,9 @@ Datasets of this pool can only be mounted read-only .It To write to a read-only pool, a export and import of the pool is required. .El +.Pp +This property can also be referred to by its shortened column name, +.Sy rdonly . .El .Pp The following properties can be set at creation time and import time, and later @@ -679,7 +688,9 @@ property. Threshold for the number of block ditto copies. If the reference count for a deduplicated block increases above this number, a new ditto copy of this block is automatically stored. Default setting is -.Cm 0 . +.Cm 0 +which causes no ditto copies to be created for deduplicated blocks. +The miniumum legal nonzero setting is 100. .It Sy delegation Ns = Ns Cm on No | Cm off Controls whether a non-privileged user is granted access based on the dataset permissions defined on the dataset. See @@ -1010,6 +1021,8 @@ is currently being used. This may lead to potential data corruption. .It Xo .Nm .Cm get +.Op Fl Hp +.Op Fl o Ar field Ns Op , Ns Ar ... .Ar all | property Ns Op , Ns Ar ... .Ar pool ... .Xc @@ -1028,6 +1041,19 @@ the following fields: See the .Qq Sx Properties section for more information on the available pool properties. +.Pp +.It Fl H +Scripted mode. Do not display headers, and separate fields by a single tab +instead of arbitrary space. +.It Fl p +Display numbers in parsable (exact) values. +.It Fl o Ar field +A comma-separated list of columns to display. +.Sy name Ns , Ns +.Sy property Ns , Ns +.Sy value Ns , Ns +.Sy source +is the default value. .It Xo .Nm .Cm history @@ -1149,9 +1175,10 @@ option is also required. .It Fl f Forces import, even if the pool appears to be potentially active. .It Fl m -Enables import with missing log devices. +Allows a pool to import when there is a missing log device. Recent transactions +can be lost because the log device will be discarded. .It Fl N -Do not mount any filesystems from the imported pool. +Import the pool without mounting any file systems. .It Fl R Ar root Sets the .Qq Sy cachefile @@ -1242,9 +1269,10 @@ option is also required. .It Fl f Forces import, even if the pool appears to be potentially active. .It Fl m -Enables import with missing log devices. +Allows a pool to import when there is a missing log device. Recent transactions +can be lost because the log device will be discarded. .It Fl N -Do not mount any filesystems from the imported pool. +Import the pool without mounting any file systems. .It Fl R Ar root Equivalent to .Qq Fl o Cm cachefile=none,altroot= Ns Pa root @@ -1319,13 +1347,13 @@ The .Ar device must not be part of an active pool configuration. .Bl -tag -width indent -.It Fl v +.It Fl f Treat exported or foreign devices as inactive. .El .It Xo .Nm .Cm list -.Op Fl Hv +.Op Fl Hpv .Op Fl o Ar property Ns Op , Ns Ar ... .Op Fl T Cm d Ns | Ns Cm u .Op Ar pool @@ -1333,8 +1361,9 @@ Treat exported or foreign devices as inactive. .Op Ar inverval Op Ar count .Xc .Pp -Lists the given pools along with a health status and space usage. When given no -arguments, all pools in the system are listed. +Lists the given pools along with a health status and space usage. If no +.Ar pools +are specified, all pools in the system are listed. .Pp When given an interval, the output is printed every .Ar interval @@ -1346,9 +1375,22 @@ is specified, the command exits after .Ar count reports are printed. .Bl -tag -width indent +.It Fl T Cm d Ns | Ns Cm u +Print a timestamp. +.Pp +Use modifier +.Cm d +for standard date format. See +.Xr date 1 . +Use modifier +.Cm u +for unixtime +.Pq equals Qq Ic date +%s . .It Fl H Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space. +.It Fl p +Display numbers in parsable (exact) values. .It Fl v Show more detailed information. .It Fl o Ar property Ns Op , Ns Ar ... @@ -1431,6 +1473,13 @@ command. Non-redundant and devices cannot be removed from a pool. .It Xo .Nm +.Cm reopen +.Ar pool +.Xc +.Pp +Reopen all the vdevs associated with the pool. +.It Xo +.Nm .Cm replace .Op Fl f .Ar pool device @@ -1667,7 +1716,7 @@ Once this is done, the pool will no longer be accessible on systems that do not support feature flags. See .Xr zpool-features 7 -for details on compatability with system sthat support feature flags, but do +for details on compatibility with systems that support feature flags, but do not support all features enabled on the pool. .Bl -tag -width indent .It Fl a @@ -1946,3 +1995,9 @@ The .Xr mdoc 7 implementation of this manual page was initially written by .An Martin Matuska Aq mm@FreeBSD.org . +.Sh CAVEATS +The +.Cm spare +feature requires a utility to detect zpool degradation and initiate +disk replacement within the zpool. +FreeBSD does not provide such a utility at this time. diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c index 0dcf11b..bec5e70 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2012 by Frederik Wessels. All rights reserved. * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. @@ -236,7 +236,7 @@ get_usage(zpool_help_t idx) { case HELP_LABELCLEAR: return (gettext("\tlabelclear [-f] <vdev>\n")); case HELP_LIST: - return (gettext("\tlist [-Hv] [-o property[,...]] " + return (gettext("\tlist [-Hpv] [-o property[,...]] " "[-T d|u] [pool] ... [interval [count]]\n")); case HELP_OFFLINE: return (gettext("\toffline [-t] <pool> <device> ...\n")); @@ -248,7 +248,7 @@ get_usage(zpool_help_t idx) { case HELP_REMOVE: return (gettext("\tremove <pool> <device> ...\n")); case HELP_REOPEN: - return (""); /* Undocumented command */ + return (gettext("\treopen <pool>\n")); case HELP_SCRUB: return (gettext("\tscrub [-s] <pool> ...\n")); case HELP_STATUS: @@ -258,8 +258,8 @@ get_usage(zpool_help_t idx) { return (gettext("\tupgrade [-v]\n" "\tupgrade [-V version] <-a | pool ...>\n")); case HELP_GET: - return (gettext("\tget <\"all\" | property[,...]> " - "<pool> ...\n")); + return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " + "<\"all\" | property[,...]> <pool> ...\n")); case HELP_SET: return (gettext("\tset <property=value> <pool> \n")); case HELP_SPLIT: @@ -1004,7 +1004,7 @@ zpool_do_create(int argc, char **argv) * Hand off to libzfs. */ if (enable_all_pool_feat) { - int i; + spa_feature_t i; for (i = 0; i < SPA_FEATURES; i++) { char propname[MAXPATHLEN]; zfeature_info_t *feat = &spa_feature_table[i]; @@ -1702,6 +1702,12 @@ show_import(nvlist_t *config) "resilvered.\n")); break; + case ZPOOL_STATUS_NON_NATIVE_ASHIFT: + (void) printf(gettext("status: One or more devices were " + "configured to use a non-native block size.\n" + "\tExpect reduced performance.\n")); + break; + default: /* * No other status can be seen when importing pools. @@ -1963,7 +1969,7 @@ zpool_do_import(int argc, char **argv) char *endptr; /* check options */ - while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) { + while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:T:VX")) != -1) { switch (c) { case 'a': do_all = B_TRUE; @@ -2759,6 +2765,7 @@ typedef struct list_cbdata { int cb_namewidth; boolean_t cb_scripted; zprop_list_t *cb_proplist; + boolean_t cb_literal; } list_cbdata_t; /* @@ -2854,7 +2861,7 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0) propstr = "-"; else if (zpool_get_prop(zhp, pl->pl_prop, property, - sizeof (property), NULL) != 0) + sizeof (property), NULL, cb->cb_literal) != 0) propstr = "-"; else propstr = property; @@ -3005,12 +3012,13 @@ list_callback(zpool_handle_t *zhp, void *data) } /* - * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] + * zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] * * -H Scripted mode. Don't display headers, and separate properties * by a single tab. * -o List of properties to display. Defaults to * "name,size,allocated,free,capacity,health,altroot" + * -p Diplay values in parsable (exact) format. * -T Display a timestamp in date(1) or Unix format * * List all pools in the system, whether or not they're healthy. Output space @@ -3031,7 +3039,7 @@ zpool_do_list(int argc, char **argv) boolean_t first = B_TRUE; /* check options */ - while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) { + while ((c = getopt(argc, argv, ":Ho:pT:v")) != -1) { switch (c) { case 'H': cb.cb_scripted = B_TRUE; @@ -3039,6 +3047,9 @@ zpool_do_list(int argc, char **argv) case 'o': props = optarg; break; + case 'p': + cb.cb_literal = B_TRUE; + break; case 'T': get_timestamp_arg(*optarg); break; @@ -3714,22 +3725,37 @@ zpool_do_reguid(int argc, char **argv) * zpool reopen <pool> * * Reopen the pool so that the kernel can update the sizes of all vdevs. - * - * NOTE: This command is currently undocumented. If the command is ever - * exposed then the appropriate usage() messages will need to be made. */ int zpool_do_reopen(int argc, char **argv) { + int c; int ret = 0; zpool_handle_t *zhp; char *pool; + /* check options */ + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + case '?': + (void) fprintf(stderr, gettext("invalid option '%c'\n"), + optopt); + usage(B_FALSE); + } + } + argc--; argv++; - if (argc != 1) - return (2); + if (argc < 1) { + (void) fprintf(stderr, gettext("missing pool name\n")); + usage(B_FALSE); + } + + if (argc > 1) { + (void) fprintf(stderr, gettext("too many arguments\n")); + usage(B_FALSE); + } pool = argv[0]; if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) @@ -5178,7 +5204,7 @@ get_callback(zpool_handle_t *zhp, void *data) } } else { if (zpool_get_prop(zhp, pl->pl_prop, value, - sizeof (value), &srctype) != 0) + sizeof (value), &srctype, cbp->cb_literal) != 0) continue; zprop_print_one_property(zpool_get_name(zhp), cbp, @@ -5189,20 +5215,32 @@ get_callback(zpool_handle_t *zhp, void *data) return (0); } +/* + * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... + * + * -H Scripted mode. Don't display headers, and separate properties + * by a single tab. + * -o List of columns to display. Defaults to + * "name,property,value,source". + * -p Diplay values in parsable (exact) format. + * + * Get properties of pools in the system. Output space statistics + * for each one as well as other attributes. + */ int zpool_do_get(int argc, char **argv) { zprop_get_cbdata_t cb = { 0 }; zprop_list_t fake_name = { 0 }; int ret; - - if (argc < 2) { - (void) fprintf(stderr, gettext("missing property " - "argument\n")); - usage(B_FALSE); - } + int c, i; + char *value; cb.cb_first = B_TRUE; + + /* + * Set up default columns and sources. + */ cb.cb_sources = ZPROP_SRC_ALL; cb.cb_columns[0] = GET_COL_NAME; cb.cb_columns[1] = GET_COL_PROPERTY; @@ -5210,10 +5248,89 @@ zpool_do_get(int argc, char **argv) cb.cb_columns[3] = GET_COL_SOURCE; cb.cb_type = ZFS_TYPE_POOL; - if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, + /* check options */ + while ((c = getopt(argc, argv, ":Hpo:")) != -1) { + switch (c) { + case 'p': + cb.cb_literal = B_TRUE; + break; + case 'H': + cb.cb_scripted = B_TRUE; + break; + case 'o': + bzero(&cb.cb_columns, sizeof (cb.cb_columns)); + i = 0; + while (*optarg != '\0') { + static char *col_subopts[] = + { "name", "property", "value", "source", + "all", NULL }; + + if (i == ZFS_GET_NCOLS) { + (void) fprintf(stderr, gettext("too " + "many fields given to -o " + "option\n")); + usage(B_FALSE); + } + + switch (getsubopt(&optarg, col_subopts, + &value)) { + case 0: + cb.cb_columns[i++] = GET_COL_NAME; + break; + case 1: + cb.cb_columns[i++] = GET_COL_PROPERTY; + break; + case 2: + cb.cb_columns[i++] = GET_COL_VALUE; + break; + case 3: + cb.cb_columns[i++] = GET_COL_SOURCE; + break; + case 4: + if (i > 0) { + (void) fprintf(stderr, + gettext("\"all\" conflicts " + "with specific fields " + "given to -o option\n")); + usage(B_FALSE); + } + cb.cb_columns[0] = GET_COL_NAME; + cb.cb_columns[1] = GET_COL_PROPERTY; + cb.cb_columns[2] = GET_COL_VALUE; + cb.cb_columns[3] = GET_COL_SOURCE; + i = ZFS_GET_NCOLS; + break; + default: + (void) fprintf(stderr, + gettext("invalid column name " + "'%s'\n"), value); + usage(B_FALSE); + } + } + break; + case '?': + (void) fprintf(stderr, gettext("invalid option '%c'\n"), + optopt); + usage(B_FALSE); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + (void) fprintf(stderr, gettext("missing property " + "argument\n")); + usage(B_FALSE); + } + + if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, ZFS_TYPE_POOL) != 0) usage(B_FALSE); + argc--; + argv++; + if (cb.cb_proplist != NULL) { fake_name.pl_prop = ZPOOL_PROP_NAME; fake_name.pl_width = strlen(gettext("NAME")); @@ -5221,7 +5338,7 @@ zpool_do_get(int argc, char **argv) cb.cb_proplist = &fake_name; } - ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, + ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, get_callback, &cb); if (cb.cb_proplist == &fake_name) diff --git a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1 b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1 index 6f8ca6e..7158075 100644 --- a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1 +++ b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1 @@ -18,10 +18,11 @@ .\" information: Portions Copyright [yyyy] [name of copyright owner] .\" .\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright (c) 2013, Delphix. All Rights Reserved. .\" .\" $FreeBSD$ .\" -.Dd November 26, 2011 +.Dd December 31, 2013 .Dt ZSTREAMDUMP 8 .Os .Sh NAME @@ -30,6 +31,7 @@ .Sh SYNOPSIS .Nm .Op Fl C +.Op Fl d .Op Fl v .Sh DESCRIPTION The @@ -43,6 +45,8 @@ The following options are supported: .Bl -tag -width indent .It Fl C Suppress the validation of checksums. +.It Fl d +Dump contents of blocks modified, implies verbose. .It Fl v Verbose. Dump all headers, not only begin and end headers. .El diff --git a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c index df23cc1..f7a4091 100644 --- a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c +++ b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c @@ -24,6 +24,11 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + */ + +#include <ctype.h> #include <libnvpair.h> #include <stdio.h> #include <stdlib.h> @@ -34,6 +39,16 @@ #include <sys/zfs_ioctl.h> #include <zfs_fletcher.h> +/* + * If dump mode is enabled, the number of bytes to print per line + */ +#define BYTES_PER_LINE 16 +/* + * If dump mode is enabled, the number of bytes to group together, separated + * by newlines or spaces + */ +#define DUMP_GROUPING 4 + uint64_t drr_record_count[DRR_NUMTYPES]; uint64_t total_write_size = 0; uint64_t total_stream_len = 0; @@ -45,9 +60,11 @@ boolean_t do_cksum = B_TRUE; static void usage(void) { - (void) fprintf(stderr, "usage: zstreamdump [-v] [-C] < file\n"); + (void) fprintf(stderr, "usage: zstreamdump [-v] [-C] [-d] < file\n"); (void) fprintf(stderr, "\t -v -- verbose\n"); (void) fprintf(stderr, "\t -C -- suppress checksum verification\n"); + (void) fprintf(stderr, "\t -d -- dump contents of blocks modified, " + "implies verbose\n"); exit(1); } @@ -75,6 +92,70 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum) return (outlen); } +/* + * Print part of a block in ASCII characters + */ +static void +print_ascii_block(char *subbuf, int length) +{ + int i; + + for (i = 0; i < length; i++) { + char char_print = isprint(subbuf[i]) ? subbuf[i] : '.'; + if (i != 0 && i % DUMP_GROUPING == 0) { + (void) printf(" "); + } + (void) printf("%c", char_print); + } + (void) printf("\n"); +} + +/* + * print_block - Dump the contents of a modified block to STDOUT + * + * Assume that buf has capacity evenly divisible by BYTES_PER_LINE + */ +static void +print_block(char *buf, int length) +{ + int i; + /* + * Start printing ASCII characters at a constant offset, after + * the hex prints. Leave 3 characters per byte on a line (2 digit + * hex number plus 1 space) plus spaces between characters and + * groupings + */ + int ascii_start = BYTES_PER_LINE * 3 + + BYTES_PER_LINE / DUMP_GROUPING + 2; + + for (i = 0; i < length; i += BYTES_PER_LINE) { + int j; + int this_line_length = MIN(BYTES_PER_LINE, length - i); + int print_offset = 0; + + for (j = 0; j < this_line_length; j++) { + int buf_offset = i + j; + + /* + * Separate every DUMP_GROUPING bytes by a space. + */ + if (buf_offset % DUMP_GROUPING == 0) { + print_offset += printf(" "); + } + + /* + * Print the two-digit hex value for this byte. + */ + unsigned char hex_print = buf[buf_offset]; + print_offset += printf("%02x ", hex_print); + } + + (void) printf("%*s", ascii_start - print_offset, " "); + + print_ascii_block(buf + i, this_line_length); + } +} + int main(int argc, char *argv[]) { @@ -92,11 +173,17 @@ main(int argc, char *argv[]) char c; boolean_t verbose = B_FALSE; boolean_t first = B_TRUE; + /* + * dump flag controls whether the contents of any modified data blocks + * are printed to the console during processing of the stream. Warning: + * for large streams, this can obviously lead to massive prints. + */ + boolean_t dump = B_FALSE; int err; zio_cksum_t zc = { 0 }; zio_cksum_t pcksum = { 0 }; - while ((c = getopt(argc, argv, ":vC")) != -1) { + while ((c = getopt(argc, argv, ":vCd")) != -1) { switch (c) { case 'C': do_cksum = B_FALSE; @@ -104,6 +191,10 @@ main(int argc, char *argv[]) case 'v': verbose = B_TRUE; break; + case 'd': + dump = B_TRUE; + verbose = B_TRUE; + break; case ':': (void) fprintf(stderr, "missing argument for '%c' option\n", optopt); @@ -128,6 +219,10 @@ main(int argc, char *argv[]) pcksum = zc; while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) { + /* + * If this is the first DMU record being processed, check for + * the magic bytes and figure out the endian-ness based on them. + */ if (first) { if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) { do_byteswap = B_TRUE; @@ -209,7 +304,7 @@ main(int argc, char *argv[]) nvlist_t *nv; int sz = drr->drr_payloadlen; - if (sz > 1<<20) { + if (sz > INITIAL_BUFLEN) { free(buf); buf = malloc(sz); } @@ -283,6 +378,10 @@ main(int argc, char *argv[]) if (drro->drr_bonuslen > 0) { (void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen, 8), &zc); + if (dump) { + print_block(buf, + P2ROUNDUP(drro->drr_bonuslen, 8)); + } } break; @@ -312,6 +411,10 @@ main(int argc, char *argv[]) drrw->drr_key.ddk_prop = BSWAP_64(drrw->drr_key.ddk_prop); } + /* + * If this is verbose and/or dump output, + * print info on the modified block + */ if (verbose) { (void) printf("WRITE object = %llu type = %u " "checksum type = %u\n" @@ -324,7 +427,16 @@ main(int argc, char *argv[]) (u_longlong_t)drrw->drr_length, (u_longlong_t)drrw->drr_key.ddk_prop); } + /* + * Read the contents of the block in from STDIN to buf + */ (void) ssread(buf, drrw->drr_length, &zc); + /* + * If in dump mode + */ + if (dump) { + print_block(buf, drrw->drr_length); + } total_write_size += drrw->drr_length; break; @@ -390,6 +502,9 @@ main(int argc, char *argv[]) drrs->drr_length); } (void) ssread(buf, drrs->drr_length, &zc); + if (dump) { + print_block(buf, drrs->drr_length); + } break; } pcksum = zc; diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c index b6dcf09..6e028c3 100644 --- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c +++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c @@ -186,7 +186,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = { extern uint64_t metaslab_gang_bang; extern uint64_t metaslab_df_alloc_threshold; -extern uint64_t zfs_deadman_synctime; +extern uint64_t zfs_deadman_synctime_ms; static ztest_shared_opts_t *ztest_shared_opts; static ztest_shared_opts_t ztest_opts; @@ -5328,10 +5328,10 @@ ztest_deadman_thread(void *arg) hrtime_t delta, total = 0; for (;;) { - delta = (zs->zs_thread_stop - zs->zs_thread_start) / - NANOSEC + zfs_deadman_synctime; + delta = zs->zs_thread_stop - zs->zs_thread_start + + MSEC2NSEC(zfs_deadman_synctime_ms); - (void) poll(NULL, 0, (int)(1000 * delta)); + (void) poll(NULL, 0, (int)NSEC2MSEC(delta)); /* * If the pool is suspended then fail immediately. Otherwise, @@ -5339,15 +5339,15 @@ ztest_deadman_thread(void *arg) * vdev_deadman() discovers that there hasn't been any recent * I/Os then it will end up aborting the tests. */ - if (spa_suspended(spa)) { + if (spa_suspended(spa) || spa->spa_root_vdev == NULL) { fatal(0, "aborting test after %llu seconds because " "pool has transitioned to a suspended state.", - zfs_deadman_synctime); + zfs_deadman_synctime_ms / 1000); return (NULL); } vdev_deadman(spa->spa_root_vdev); - total += zfs_deadman_synctime; + total += zfs_deadman_synctime_ms/1000; (void) printf("ztest has been running for %lld seconds\n", total); } @@ -6080,7 +6080,7 @@ main(int argc, char **argv) (void) setvbuf(stdout, NULL, _IOLBF, 0); dprintf_setup(&argc, argv); - zfs_deadman_synctime = 300; + zfs_deadman_synctime_ms = 300000; ztest_fd_rand = open("/dev/urandom", O_RDONLY); ASSERT3S(ztest_fd_rand, >=, 0); diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c index 239d166..7364814 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c @@ -65,7 +65,7 @@ ctf_create(int *errp) cts.cts_name = _CTF_SECTION; cts.cts_type = SHT_PROGBITS; cts.cts_flags = 0; - cts.cts_data = &hdr; + cts.cts_data = (void *)&hdr; cts.cts_size = sizeof (hdr); cts.cts_entsize = 1; cts.cts_offset = 0; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index 3b4a38c..bb02d8c 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -20,6 +20,7 @@ */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2013 Voxer Inc. All rights reserved. * Use is subject to license terms. */ @@ -144,7 +145,8 @@ dtrace_dof_init(void) Lmid_t lmid; #else u_long lmid = 0; - dof_sec_t *sec; + dof_sec_t *sec, *secstart, *dofstrtab, *dofprobes; + dof_provider_t *dofprovider; size_t i; #endif int fd; @@ -152,14 +154,15 @@ dtrace_dof_init(void) #if !defined(sun) Elf *e; Elf_Scn *scn = NULL; - Elf_Data *symtabdata = NULL, *dynsymdata = NULL; + Elf_Data *symtabdata = NULL, *dynsymdata = NULL, *dofdata = NULL; + dof_hdr_t *dof_next = NULL; GElf_Shdr shdr; int efd, nprobes; char *s; + char *dofstrtabraw; size_t shstridx, symtabidx = 0, dynsymidx = 0; - unsigned char *dofstrtab = NULL; unsigned char *buf; - int fixedprobes = 0; + int fixedprobes; #endif if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL) @@ -209,7 +212,8 @@ dtrace_dof_init(void) } else if (shdr.sh_type == SHT_PROGBITS) { s = elf_strptr(e, shstridx, shdr.sh_name); if (s && strcmp(s, ".SUNW_dof") == 0) { - dof = elf_getdata(scn, NULL)->d_buf; + dofdata = elf_getdata(scn, NULL); + dof = dofdata->d_buf; } } } @@ -219,6 +223,10 @@ dtrace_dof_init(void) close(efd); return; } + + while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) { + fixedprobes = 0; + dof_next = (void *) ((char *) dof + dof->dofh_filesz); #endif if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 || @@ -290,34 +298,49 @@ dtrace_dof_init(void) * We are assuming the number of probes is less than the number of * symbols (libc can have 4k symbols, for example). */ - sec = (dof_sec_t *)(dof + 1); + 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_STRTAB) - dofstrtab = (unsigned char *)(buf + sec->dofs_offset); - else if (sec->dofs_type == DOF_SECT_PROBES && dofstrtab) + 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; - - } - nprobes = sec->dofs_size / sec->dofs_entsize; - fixsymbol(e, symtabdata, symtabidx, nprobes, buf, sec, &fixedprobes, - dofstrtab); - 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, sec, - &fixedprobes, dofstrtab); - } - 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"); + } + 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) @@ -330,7 +353,12 @@ dtrace_dof_init(void) } (void) close(fd); + #if !defined(sun) + /* End of while loop */ + dof = dof_next; + } + elf_end(e); (void) close(efd); #endif diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c index 01ef0f9..5442683 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -486,7 +487,7 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data) return (0); } -static void +static int dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) { dtrace_hdl_t *dtp = ddo->ddo_hdl; @@ -497,8 +498,12 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) size_t sz; id_t i; - if (pvp->pv_flags & DT_PROVIDER_IMPL) - return; /* ignore providers that are exported by dtrace(7D) */ + if (pvp->pv_flags & DT_PROVIDER_IMPL) { + /* + * ignore providers that are exported by dtrace(7D) + */ + return (0); + } nxr = dt_popcb(pvp->pv_xrefs, pvp->pv_xrmax); dofs = alloca(sizeof (dof_secidx_t) * (nxr + 1)); @@ -525,6 +530,9 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) (void) dt_idhash_iter(pvp->pv_probes, dof_add_probe, ddo); + if (dt_buf_len(&ddo->ddo_probes) == 0) + return (dt_set_errno(dtp, EDT_NOPROBES)); + dofpv.dofpv_probes = dof_add_lsect(ddo, NULL, DOF_SECT_PROBES, sizeof (uint64_t), 0, sizeof (dof_probe_t), dt_buf_len(&ddo->ddo_probes)); @@ -579,6 +587,8 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) sizeof (dof_secidx_t), 0, sizeof (dof_secidx_t), sizeof (dof_secidx_t) * (nxr + 1)); } + + return (0); } static int @@ -822,8 +832,10 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags) */ if (flags & DTRACE_D_PROBES) { for (pvp = dt_list_next(&dtp->dt_provlist); - pvp != NULL; pvp = dt_list_next(pvp)) - dof_add_provider(ddo, pvp); + pvp != NULL; pvp = dt_list_next(pvp)) { + if (dof_add_provider(ddo, pvp) != 0) + return (NULL); + } } /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c index 66776be..d8dbbabb 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c @@ -26,6 +26,7 @@ /* * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <string.h> @@ -109,7 +110,8 @@ static const struct { { EDT_BADSTACKPC, "Invalid stack program counter size" }, { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, { EDT_OVERSION, "Client requested deprecated version of library" }, - { EDT_ENABLING_ERR, "Failed to enable probe" } + { EDT_ENABLING_ERR, "Failed to enable probe" }, + { EDT_NOPROBES, "No probe sites found for declared provider" } }; static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h index e4b1db5..2bae220 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h @@ -25,7 +25,7 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -535,7 +535,8 @@ enum { EDT_BADSTACKPC, /* invalid stack program counter size */ EDT_BADAGGVAR, /* invalid aggregation variable identifier */ EDT_OVERSION, /* client is requesting deprecated version */ - EDT_ENABLING_ERR /* failed to enable probe */ + EDT_ENABLING_ERR, /* failed to enable probe */ + EDT_NOPROBES /* no probes sites for declared provider */ }; /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index 2d0428a..f31c600 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -242,8 +242,14 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); /* XXX */ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); #elif defined(__powerpc__) -/* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + /* + * Add 4 bytes to hit the low half of this 64-bit + * big-endian address. + */ + rel->r_offset = s->dofs_offset + + dofr[j].dofr_offset + 4; + rel->r_info = ELF32_R_INFO(count + dep->de_global, + R_PPC_REL32); #elif defined(__sparc) /* * Add 4 bytes to hit the low half of this 64-bit @@ -423,7 +429,10 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) #elif defined(__mips__) /* XXX */ #elif defined(__powerpc__) -/* XXX */ + rel->r_offset = s->dofs_offset + + dofr[j].dofr_offset; + rel->r_info = ELF64_R_INFO(count + dep->de_global, + R_PPC64_REL64); #elif defined(__i386) || defined(__amd64) rel->r_offset = s->dofs_offset + dofr[j].dofr_offset; @@ -824,12 +833,84 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); return (0); } #elif defined(__powerpc__) +/* The sentinel is 'xor r3,r3,r3'. */ +#define DT_OP_XOR_R3 0x7c631a78 + +#define DT_OP_NOP 0x60000000 +#define DT_OP_BLR 0x4e800020 + +/* This captures all forms of branching to address. */ +#define DT_IS_BRANCH(inst) ((inst & 0xfc000000) == 0x48000000) +#define DT_IS_BL(inst) (DT_IS_BRANCH(inst) && (inst & 0x01)) + /* XXX */ static int dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + uint32_t *ip; + + if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0) + return (-1); + + /*LINTED*/ + ip = (uint32_t *)(p + rela->r_offset); + + /* + * We only know about some specific relocation types. + */ + if (GELF_R_TYPE(rela->r_info) != R_PPC_REL24 && + GELF_R_TYPE(rela->r_info) != R_PPC_PLTREL24) + return (-1); + + /* + * We may have already processed this object file in an earlier linker + * invocation. Check to see if the present instruction sequence matches + * the one we would install below. + */ + if (isenabled) { + if (ip[0] == DT_OP_XOR_R3) { + (*off) += sizeof (ip[0]); + return (0); + } + } else { + if (ip[0] == DT_OP_NOP) { + (*off) += sizeof (ip[0]); + return (0); + } + } + + /* + * We only expect branch to address instructions. + */ + if (!DT_IS_BRANCH(ip[0])) { + dt_dprintf("found %x instead of a branch instruction at %llx\n", + ip[0], (u_longlong_t)rela->r_offset); + return (-1); + } + + if (isenabled) { + /* + * It would necessarily indicate incorrect usage if an is- + * enabled probe were tail-called so flag that as an error. + * It's also potentially (very) tricky to handle gracefully, + * but could be done if this were a desired use scenario. + */ + if (!DT_IS_BL(ip[0])) { + dt_dprintf("tail call to is-enabled probe at %llx\n", + (u_longlong_t)rela->r_offset); + return (-1); + } + + ip[0] = DT_OP_XOR_R3; + (*off) += sizeof (ip[0]); + } else { + if (DT_IS_BL(ip[0])) + ip[0] = DT_OP_NOP; + else + ip[0] = DT_OP_BLR; + } + return (0); } @@ -1539,10 +1620,17 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) * the executable file as the symbol is going to be * change from UND to ABS. */ - rela.r_offset = 0; - rela.r_info = 0; - rela.r_addend = 0; - (void) gelf_update_rela(data_rel, i, &rela); + if (shdr_rel.sh_type == SHT_RELA) { + rela.r_offset = 0; + rela.r_info = 0; + rela.r_addend = 0; + (void) gelf_update_rela(data_rel, i, &rela); + } else { + GElf_Rel rel; + rel.r_offset = 0; + rel.r_info = 0; + (void) gelf_update_rel(data_rel, i, &rel); + } #endif mod = 1; @@ -1628,8 +1716,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, */ return (0); } - /* XXX Should get a temp file name here. */ - snprintf(tfile, sizeof(tfile), "%s.tmp", file); #endif /* @@ -1704,9 +1790,11 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, "failed to open %s: %s", file, strerror(errno))); } #else - if ((fd = open(tfile, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) + snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file); + if ((fd = mkstemp(tfile)) == -1) return (dt_link_error(dtp, NULL, -1, NULL, - "failed to open %s: %s", tfile, strerror(errno))); + "failed to create temporary file %s: %s", + tfile, strerror(errno))); #endif /* @@ -1749,13 +1837,15 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, status = dump_elf32(dtp, dof, fd); if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { -#else - /* We don't write the ELF header, just the DOF section */ - if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) { -#endif 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) + return (dt_link_error(dtp, NULL, -1, NULL, + "failed to write %s: %s", tfile, strerror(errno))); +#endif if (!dtp->dt_lazyload) { #if defined(sun) @@ -1783,7 +1873,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, * Arches which default to 64-bit need to explicitly use * the 32-bit library path. */ - int use_32 = !(dtp->dt_oflags & DTRACE_O_LP64); + int use_32 = (dtp->dt_oflags & DTRACE_O_ILP32); #else /* * Arches which are 32-bit only just use the normal @@ -1798,9 +1888,7 @@ 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; -#if !defined(sun) len *= 2; -#endif cmd = alloca(len); (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c index 9c9b2a6..767114e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -311,6 +311,10 @@ static const dt_ident_t _dtrace_globals[] = { &dt_idops_func, "void(@)" }, { "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "uintptr_t *(void *, size_t)" }, +#if !defined(sun) +{ "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0, + &dt_idops_func, "string(void *, char, size_t)" }, +#endif { "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "void(@)" }, { "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN, @@ -483,22 +487,16 @@ static const dt_ident_t _dtrace_globals[] = { DT_VERS_1_0, &dt_idops_func, "void(...)" }, { "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "uintptr_t *(void *, size_t, string, size_t)" }, -#if defined(sun) { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, -#endif { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint64_t" }, -#if defined(sun) { "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, -#endif { "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uid_t" }, -#if defined(sun) { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, -#endif { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_regs, NULL }, { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -506,10 +504,8 @@ static const dt_ident_t _dtrace_globals[] = { { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint32_t" }, -#if defined(sun) { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, -#endif { "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint64_t" }, diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c index 020df2f..c20d250 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -906,30 +904,6 @@ dt_options_load(dtrace_hdl_t *dtp) return (0); } -/*ARGSUSED*/ -static int -dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) -{ - dtrace_optval_t size; - void *p; - - if (arg == NULL || dt_optval_parse(arg, &size) != 0) - return (dt_set_errno(dtp, EDT_BADOPTVAL)); - - if (size > SIZE_MAX) - size = SIZE_MAX; - - if ((p = dt_zalloc(dtp, size)) == NULL) { - do { - size /= 2; - } while ((p = dt_zalloc(dtp, size)) == NULL); - } - - dt_free(dtp, p); - - return (0); -} - typedef struct dt_option { const char *o_name; int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t); @@ -968,7 +942,6 @@ static const dt_option_t _dtrace_ctoptions[] = { { "linktype", dt_opt_linktype }, { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS }, { "pgmax", dt_opt_pgmax }, - { "preallocate", dt_opt_preallocate }, { "pspec", dt_opt_cflags, DTRACE_C_PSPEC }, { "setenv", dt_opt_setenv, 1 }, { "stdc", dt_opt_stdc }, diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c index 24682b2..e4cbd21 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c @@ -694,8 +694,13 @@ static const dt_pfconv_t _dtrace_conversions[] = { { "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr }, { "T", "s", "int64_t", pfcheck_time, pfprint_time822 }, { "u", "u", pfproto_xint, pfcheck_xint, pfprint_uint }, +#if defined(sun) { "wc", "wc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */ { "ws", "ws", pfproto_wstr, pfcheck_wstr, pfprint_wstr }, +#else +{ "wc", "lc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */ +{ "ws", "ls", pfproto_wstr, pfcheck_wstr, pfprint_wstr }, +#endif { "x", "x", pfproto_xint, pfcheck_xint, pfprint_uint }, { "X", "X", pfproto_xint, pfcheck_xint, pfprint_uint }, { "Y", "s", "int64_t", pfcheck_time, pfprint_time }, diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c index 87211a2..4429019 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c @@ -734,11 +734,6 @@ dt_zalloc(dtrace_hdl_t *dtp, size_t size) { void *data; - if (size > 16 * 1024 * 1024) { - (void) dt_set_errno(dtp, EDT_NOMEM); - return (NULL); - } - if ((data = malloc(size)) == NULL) (void) dt_set_errno(dtp, EDT_NOMEM); else @@ -752,11 +747,6 @@ dt_alloc(dtrace_hdl_t *dtp, size_t size) { void *data; - if (size > 16 * 1024 * 1024) { - (void) dt_set_errno(dtp, EDT_NOMEM); - return (NULL); - } - if ((data = malloc(size)) == NULL) (void) dt_set_errno(dtp, EDT_NOMEM); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c index 1aeb95f..f4b02c9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c @@ -35,14 +35,26 @@ #include <dt_impl.h> #include <dt_pid.h> +#include <libproc_compat.h> + /*ARGSUSED*/ int dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp) { + ftp->ftps_type = DTFTP_ENTRY; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + ftp->ftps_offs[0] = 0; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } - dt_dprintf("%s: unimplemented\n", __func__); - return (DT_PROC_ERR); + return (1); } int @@ -50,8 +62,74 @@ dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret) { - dt_dprintf("%s: unimplemented\n", __func__); - return (DT_PROC_ERR); + uintptr_t temp; + uint32_t *text; + int i; + int srdepth = 0; + + if ((text = malloc(symp->st_size + 4)) == NULL) { + dt_dprintf("mr sparkle: malloc() failed\n"); + return (DT_PROC_ERR); + } + + if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) { + dt_dprintf("mr sparkle: Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + + /* + * Leave a dummy instruction in the last slot to simplify edge + * conditions. + */ + text[symp->st_size / 4] = 0; + + ftp->ftps_type = DTFTP_RETURN; + ftp->ftps_pc = symp->st_value; + ftp->ftps_size = symp->st_size; + ftp->ftps_noffs = 0; + + for (i = 0; i < symp->st_size / 4; i++) { + + if ((text[i] & 0xfc000001) != 0x48000000 && + text[i] != 0x4e800020) + continue; + + /* + * Check for a jump within this function. If it's outside this + * function then it's a tail-call, so a return point. + */ + if ((text[i] & 0xfc000000) == 0x48000000) { + temp = (text[i] & 0x03fffffc); + /* Bit 30 denotes an absolute address. */ + if (!(text[i] & 0x02)) { + temp += symp->st_value + i * 4; + } + else { + /* Sign extend the absolute address. */ + if (temp & 0x02000000) { + temp |= (UINTPTR_MAX - 0x03ffffff); + } + } + if (temp >= symp->st_value && + temp <= (symp->st_value + symp->st_size)) + continue; + } + dt_dprintf("return at offset %x\n", i * 4); + ftp->ftps_offs[ftp->ftps_noffs++] = i * 4; + } + + free(text); + if (ftp->ftps_noffs > 0) { + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + } + + + return (ftp->ftps_noffs); } /*ARGSUSED*/ @@ -59,9 +137,22 @@ int dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off) { + if (off & 0x3) + return (DT_PROC_ALIGN); + + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + ftp->ftps_offs[0] = off; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } - dt_dprintf("%s: unimplemented\n", __func__); - return (DT_PROC_ERR); + return (1); } /*ARGSUSED*/ @@ -69,7 +160,38 @@ int dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern) { + ulong_t i; + + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 0; + + /* + * If we're matching against everything, just iterate through each + * instruction in the function, otherwise look for matching offset + * names by constructing the string and comparing it against the + * pattern. + */ + if (strcmp("*", pattern) == 0) { + for (i = 0; i < symp->st_size; i += 4) { + ftp->ftps_offs[ftp->ftps_noffs++] = i; + } + } else { + char name[sizeof (i) * 2 + 1]; + + for (i = 0; i < symp->st_size; i += 4) { + (void) sprintf(name, "%lx", i); + if (gmatch(name, pattern)) + ftp->ftps_offs[ftp->ftps_noffs++] = i; + } + } + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } - dt_dprintf("%s: unimplemented\n", __func__); - return (DT_PROC_ERR); + return (ftp->ftps_noffs); } diff --git a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c index 3302ac7..7a265bd 100644 --- a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c +++ b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c @@ -210,7 +210,7 @@ NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d") NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x") NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld") NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx") -NVLIST_PRTFUNC(double, double, double, "0x%llf") +NVLIST_PRTFUNC(double, double, double, "0x%f") NVLIST_PRTFUNC(string, char *, char *, "%s") NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx") diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c index 308e920..5e78ece 100644 --- a/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c +++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c @@ -128,6 +128,7 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp) pp->uap_next->uap_prev = pp->uap_prev; pp->uap_prev->uap_next = pp->uap_next; (void) pthread_mutex_unlock(&uu_apool_list_lock); + (void) pthread_mutex_destroy(&pp->uap_lock); pp->uap_prev = NULL; pp->uap_next = NULL; uu_free(pp); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h index 0a5ca82..24131d6 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h @@ -21,13 +21,13 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBZFS_H @@ -193,6 +193,7 @@ extern int zpool_log_history(libzfs_handle_t *, const char *); extern int libzfs_errno(libzfs_handle_t *); extern const char *libzfs_error_action(libzfs_handle_t *); extern const char *libzfs_error_description(libzfs_handle_t *); +extern int zfs_standard_error(libzfs_handle_t *, int, const char *); extern void libzfs_mnttab_init(libzfs_handle_t *); extern void libzfs_mnttab_fini(libzfs_handle_t *); extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t); @@ -269,7 +270,7 @@ extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, const char *); */ extern int zpool_set_prop(zpool_handle_t *, const char *, const char *); extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *, - size_t proplen, zprop_source_t *); + size_t proplen, zprop_source_t *, boolean_t); extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *); @@ -463,7 +464,8 @@ typedef struct zprop_list { boolean_t pl_fixed; } zprop_list_t; -extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t); +extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t, + boolean_t); extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *); #define ZFS_MOUNTPOINT_NONE "none" @@ -536,6 +538,7 @@ extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *); extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *); extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *); extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *); +extern int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *); typedef struct get_all_cb { zfs_handle_t **cb_handles; @@ -610,6 +613,7 @@ typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *); extern int zfs_send(zfs_handle_t *, const char *, const char *, sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **); +extern int zfs_send_one(zfs_handle_t *, const char *, int); extern int zfs_promote(zfs_handle_t *); extern int zfs_hold(zfs_handle_t *, const char *, const char *, @@ -679,6 +683,7 @@ extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t); extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *, zfs_type_t); extern int zfs_spa_version(zfs_handle_t *, int *); +extern boolean_t zfs_bookmark_exists(const char *path); /* * Mount support functions. diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index e330ad2..11378a2 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -21,13 +21,14 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #include <ctype.h> @@ -295,7 +296,7 @@ zpool_handle(zfs_handle_t *zhp) int len; zpool_handle_t *zph; - len = strcspn(zhp->zfs_name, "/@") + 1; + len = strcspn(zhp->zfs_name, "/@#") + 1; pool_name = zfs_alloc(zhp->zfs_hdl, len); (void) strlcpy(pool_name, zhp->zfs_name, len); @@ -579,6 +580,70 @@ zfs_handle_dup(zfs_handle_t *zhp_orig) return (zhp); } +boolean_t +zfs_bookmark_exists(const char *path) +{ + nvlist_t *bmarks; + nvlist_t *props; + char fsname[ZFS_MAXNAMELEN]; + char *bmark_name; + char *pound; + int err; + boolean_t rv; + + + (void) strlcpy(fsname, path, sizeof (fsname)); + pound = strchr(fsname, '#'); + if (pound == NULL) + return (B_FALSE); + + *pound = '\0'; + bmark_name = pound + 1; + props = fnvlist_alloc(); + err = lzc_get_bookmarks(fsname, props, &bmarks); + nvlist_free(props); + if (err != 0) { + nvlist_free(bmarks); + return (B_FALSE); + } + + rv = nvlist_exists(bmarks, bmark_name); + nvlist_free(bmarks); + return (rv); +} + +zfs_handle_t * +make_bookmark_handle(zfs_handle_t *parent, const char *path, + nvlist_t *bmark_props) +{ + zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1); + + if (zhp == NULL) + return (NULL); + + /* Fill in the name. */ + zhp->zfs_hdl = parent->zfs_hdl; + (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name)); + + /* Set the property lists. */ + if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) { + free(zhp); + return (NULL); + } + + /* Set the types. */ + zhp->zfs_head_type = parent->zfs_head_type; + zhp->zfs_type = ZFS_TYPE_BOOKMARK; + + if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) { + nvlist_free(zhp->zfs_props); + free(zhp); + return (NULL); + } + + return (zhp); +} + /* * Opens the given snapshot, filesystem, or volume. The 'types' * argument is a mask of acceptable types. The function will print an @@ -1846,6 +1911,10 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, case ZFS_PROP_REFQUOTA: case ZFS_PROP_RESERVATION: case ZFS_PROP_REFRESERVATION: + case ZFS_PROP_FILESYSTEM_LIMIT: + case ZFS_PROP_SNAPSHOT_LIMIT: + case ZFS_PROP_FILESYSTEM_COUNT: + case ZFS_PROP_SNAPSHOT_COUNT: *val = getprop_uint64(zhp, prop, source); if (*source == NULL) { @@ -2173,8 +2242,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, } if ((zpool_get_prop(zhp->zpool_hdl, - ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) || - (strcmp(root, "-") == 0)) + ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL, + B_FALSE)) || (strcmp(root, "-") == 0)) root[0] = '\0'; /* * Special case an alternate root of '/'. This will @@ -2251,6 +2320,30 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, } break; + case ZFS_PROP_FILESYSTEM_LIMIT: + case ZFS_PROP_SNAPSHOT_LIMIT: + case ZFS_PROP_FILESYSTEM_COUNT: + case ZFS_PROP_SNAPSHOT_COUNT: + + if (get_numeric_property(zhp, prop, src, &source, &val) != 0) + return (-1); + + /* + * If limit is UINT64_MAX, we translate this into 'none' (unless + * literal is set), and indicate that it's the default value. + * Otherwise, we print the number nicely and indicate that it's + * set locally. + */ + if (literal) { + (void) snprintf(propbuf, proplen, "%llu", + (u_longlong_t)val); + } else if (val == UINT64_MAX) { + (void) strlcpy(propbuf, "none", proplen); + } else { + zfs_nicenum(val, propbuf, proplen); + } + break; + case ZFS_PROP_REFRATIO: case ZFS_PROP_COMPRESSRATIO: if (get_numeric_property(zhp, prop, src, &source, &val) != 0) @@ -2271,6 +2364,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, case ZFS_TYPE_SNAPSHOT: str = "snapshot"; break; + case ZFS_TYPE_BOOKMARK: + str = "bookmark"; + break; default: abort(); } @@ -2477,6 +2573,7 @@ out: return (err); #else /* !sun */ assert(!"invalid code path"); + return (EINVAL); // silence compiler warning #endif /* !sun */ } @@ -3133,6 +3230,19 @@ zfs_destroy(zfs_handle_t *zhp, boolean_t defer) { zfs_cmd_t zc = { 0 }; + if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) { + nvlist_t *nv = fnvlist_alloc(); + fnvlist_add_boolean(nv, zhp->zfs_name); + int error = lzc_destroy_bookmarks(nv, NULL); + fnvlist_free(nv); + if (error != 0) { + return (zfs_standard_error_fmt(zhp->zfs_hdl, errno, + dgettext(TEXT_DOMAIN, "cannot destroy '%s'"), + zhp->zfs_name)); + } + return (0); + } + (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); if (ZFS_IS_VOLUME(zhp)) { @@ -3515,45 +3625,44 @@ typedef struct rollback_data { const char *cb_target; /* the snapshot */ uint64_t cb_create; /* creation time reference */ boolean_t cb_error; - boolean_t cb_dependent; boolean_t cb_force; } rollback_data_t; static int -rollback_destroy(zfs_handle_t *zhp, void *data) +rollback_destroy_dependent(zfs_handle_t *zhp, void *data) { rollback_data_t *cbp = data; + prop_changelist_t *clp; - if (!cbp->cb_dependent) { - if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 && - zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && - zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > - cbp->cb_create) { + /* We must destroy this clone; first unmount it */ + clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, + cbp->cb_force ? MS_FORCE: 0); + if (clp == NULL || changelist_prefix(clp) != 0) { + cbp->cb_error = B_TRUE; + zfs_close(zhp); + return (0); + } + if (zfs_destroy(zhp, B_FALSE) != 0) + cbp->cb_error = B_TRUE; + else + changelist_remove(clp, zhp->zfs_name); + (void) changelist_postfix(clp); + changelist_free(clp); - cbp->cb_dependent = B_TRUE; - cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE, - rollback_destroy, cbp); - cbp->cb_dependent = B_FALSE; + zfs_close(zhp); + return (0); +} - cbp->cb_error |= zfs_destroy(zhp, B_FALSE); - } - } else { - /* We must destroy this clone; first unmount it */ - prop_changelist_t *clp; +static int +rollback_destroy(zfs_handle_t *zhp, void *data) +{ + rollback_data_t *cbp = data; - clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, - cbp->cb_force ? MS_FORCE: 0); - if (clp == NULL || changelist_prefix(clp) != 0) { - cbp->cb_error = B_TRUE; - zfs_close(zhp); - return (0); - } - if (zfs_destroy(zhp, B_FALSE) != 0) - cbp->cb_error = B_TRUE; - else - changelist_remove(clp, zhp->zfs_name); - (void) changelist_postfix(clp); - changelist_free(clp); + if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) { + cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE, + rollback_destroy_dependent, cbp); + + cbp->cb_error |= zfs_destroy(zhp, B_FALSE); } zfs_close(zhp); @@ -3564,8 +3673,8 @@ rollback_destroy(zfs_handle_t *zhp, void *data) * Given a dataset, rollback to a specific snapshot, discarding any * data changes since then and making it the active dataset. * - * Any snapshots more recent than the target are destroyed, along with - * their dependents. + * Any snapshots and bookmarks more recent than the target are + * destroyed, along with their dependents (i.e. clones). */ int zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) @@ -3585,7 +3694,8 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) cb.cb_force = force; cb.cb_target = snap->zfs_name; cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG); - (void) zfs_iter_children(zhp, rollback_destroy, &cb); + (void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb); + (void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb); if (cb.cb_error) return (-1); @@ -3882,7 +3992,8 @@ zfs_get_recvd_props(zfs_handle_t *zhp) * of the RECEIVED column. */ int -zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received) +zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received, + boolean_t literal) { libzfs_handle_t *hdl = zhp->zfs_hdl; zprop_list_t *entry; @@ -3944,18 +4055,18 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received) * Now go through and check the width of any non-fixed columns */ for (entry = *plp; entry != NULL; entry = entry->pl_next) { - if (entry->pl_fixed) + if (entry->pl_fixed && !literal) continue; if (entry->pl_prop != ZPROP_INVAL) { if (zfs_prop_get(zhp, entry->pl_prop, - buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) { + buf, sizeof (buf), NULL, NULL, 0, literal) == 0) { if (strlen(buf) > entry->pl_width) entry->pl_width = strlen(buf); } if (received && zfs_prop_get_recvd(zhp, zfs_prop_to_name(entry->pl_prop), - buf, sizeof (buf), B_FALSE) == 0) + buf, sizeof (buf), literal) == 0) if (strlen(buf) > entry->pl_recvd_width) entry->pl_recvd_width = strlen(buf); } else { @@ -3968,7 +4079,7 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received) } if (received && zfs_prop_get_recvd(zhp, entry->pl_user_prop, - buf, sizeof (buf), B_FALSE) == 0) + buf, sizeof (buf), literal) == 0) if (strlen(buf) > entry->pl_recvd_width) entry->pl_recvd_width = strlen(buf); } diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h index 11a57a9..481ae52 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h @@ -23,7 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. */ @@ -191,6 +191,8 @@ int create_parents(libzfs_handle_t *, char *, int); boolean_t isa_child_of(const char *dataset, const char *parent); zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *); +zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *, + nvlist_t *props); int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index fa3d609..e53a8cd 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -20,8 +20,8 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* @@ -995,10 +995,10 @@ nozpool_all_slices(avl_tree_t *r, const char *sname) #endif /* sun */ } +#ifdef sun static void check_slices(avl_tree_t *r, int fd, const char *sname) { -#ifdef sun struct extvtoc vtoc; struct dk_gpt *gpt; char diskname[MAXNAMELEN]; @@ -1028,8 +1028,8 @@ check_slices(avl_tree_t *r, int fd, const char *sname) check_one_slice(r, diskname, i, 0, 1); efi_free(gpt); } -#endif /* sun */ } +#endif /* sun */ static void zpool_open_func(void *arg) @@ -1059,6 +1059,7 @@ zpool_open_func(void *arg) return; } /* this file is too small to hold a zpool */ +#ifdef sun if (S_ISREG(statbuf.st_mode) && statbuf.st_size < SPA_MINDEVSIZE) { (void) close(fd); @@ -1070,6 +1071,12 @@ zpool_open_func(void *arg) */ check_slices(rn->rn_avl, fd, rn->rn_name); } +#else /* !sun */ + if (statbuf.st_size < SPA_MINDEVSIZE) { + (void) close(fd); + return; + } +#endif /* sun */ if ((zpool_read_label(fd, &config)) != 0) { (void) close(fd); @@ -1606,9 +1613,16 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr, * its state to active. */ if (pool_active(hdl, name, guid, &isactive) == 0 && isactive && - (zhp = zpool_open_canfail(hdl, name)) != NULL && - zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL)) - stateval = POOL_STATE_ACTIVE; + (zhp = zpool_open_canfail(hdl, name)) != NULL) { + if (zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL)) + stateval = POOL_STATE_ACTIVE; + + /* + * All we needed the zpool handle for is the + * readonly prop check. + */ + zpool_close(zhp); + } ret = B_TRUE; break; diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c index 259d045..9698a72 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c @@ -21,7 +21,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 (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. @@ -146,7 +146,8 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func, zfs_handle_t *nzhp; int ret; - if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) + if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT || + zhp->zfs_type == ZFS_TYPE_BOOKMARK) return (0); zc.zc_simple = simple; @@ -173,6 +174,59 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func, } /* + * Iterate over all bookmarks + */ +int +zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data) +{ + zfs_handle_t *nzhp; + nvlist_t *props = NULL; + nvlist_t *bmarks = NULL; + int err; + + if ((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK)) != 0) + return (0); + + /* Setup the requested properties nvlist. */ + props = fnvlist_alloc(); + fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_GUID)); + fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATETXG)); + fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATION)); + + /* Allocate an nvlist to hold the bookmarks. */ + bmarks = fnvlist_alloc(); + + if ((err = lzc_get_bookmarks(zhp->zfs_name, props, &bmarks)) != 0) + goto out; + + for (nvpair_t *pair = nvlist_next_nvpair(bmarks, NULL); + pair != NULL; pair = nvlist_next_nvpair(bmarks, pair)) { + char name[ZFS_MAXNAMELEN]; + char *bmark_name; + nvlist_t *bmark_props; + + bmark_name = nvpair_name(pair); + bmark_props = fnvpair_value_nvlist(pair); + + (void) snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name, + bmark_name); + + nzhp = make_bookmark_handle(zhp, name, bmark_props); + if (nzhp == NULL) + continue; + + if ((err = func(nzhp, data)) != 0) + goto out; + } + +out: + fnvlist_free(props); + fnvlist_free(bmarks); + + return (err); +} + +/* * Routines for dealing with the sorted snapshot functionality */ typedef struct zfs_node { @@ -406,13 +460,13 @@ static int iter_dependents_cb(zfs_handle_t *zhp, void *arg) { iter_dependents_arg_t *ida = arg; - int err; + int err = 0; boolean_t first = ida->first; ida->first = B_FALSE; if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { err = zfs_iter_clones(zhp, iter_dependents_cb, ida); - } else { + } else if (zhp->zfs_type != ZFS_TYPE_BOOKMARK) { iter_stack_frame_t isf; iter_stack_frame_t *f; diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c index df8317f..8dd24a7 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ @@ -240,7 +240,7 @@ zpool_pool_state_to_name(pool_state_t state) */ int zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, - zprop_source_t *srctype) + zprop_source_t *srctype, boolean_t literal) { uint64_t intval; const char *strval; @@ -272,9 +272,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src), len); - if (srctype != NULL) - *srctype = src; - return (0); + break; } /* FALLTHROUGH */ default: @@ -306,12 +304,22 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, case ZPOOL_PROP_FREE: case ZPOOL_PROP_FREEING: case ZPOOL_PROP_EXPANDSZ: - (void) zfs_nicenum(intval, buf, len); + if (literal) { + (void) snprintf(buf, len, "%llu", + (u_longlong_t)intval); + } else { + (void) zfs_nicenum(intval, buf, len); + } break; case ZPOOL_PROP_CAPACITY: - (void) snprintf(buf, len, "%llu%%", - (u_longlong_t)intval); + if (literal) { + (void) snprintf(buf, len, "%llu", + (u_longlong_t)intval); + } else { + (void) snprintf(buf, len, "%llu%%", + (u_longlong_t)intval); + } break; case ZPOOL_PROP_DEDUPRATIO: @@ -407,7 +415,7 @@ zpool_is_bootable(zpool_handle_t *zhp) char bootfs[ZPOOL_MAXNAMELEN]; return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, - sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-", + sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-", sizeof (bootfs)) != 0); } @@ -443,10 +451,9 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, prop = zpool_name_to_prop(propname); if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) { int err; - zfeature_info_t *feature; char *fname = strchr(propname, '@') + 1; - err = zfeature_lookup_name(fname, &feature); + err = zfeature_lookup_name(fname, NULL); if (err != 0) { ASSERT3U(err, ==, ENOENT); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, @@ -807,7 +814,7 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp) if (entry->pl_prop != ZPROP_INVAL && zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf), - NULL) == 0) { + NULL, B_FALSE) == 0) { if (strlen(buf) > entry->pl_width) entry->pl_width = strlen(buf); } @@ -839,14 +846,14 @@ zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf, */ if (supported) { int ret; - zfeature_info_t *fi; + spa_feature_t fid; - ret = zfeature_lookup_name(feature, &fi); + ret = zfeature_lookup_name(feature, &fid); if (ret != 0) { (void) strlcpy(buf, "-", len); return (ENOTSUP); } - feature = fi->fi_guid; + feature = spa_feature_table[fid].fi_guid; } if (nvlist_lookup_uint64(features, feature, &refcount) == 0) @@ -3737,7 +3744,9 @@ zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover, return (0); } -#define HIS_BUF_LEN (128*1024) +/* from spa_history.c: spa_history_create_obj() */ +#define HIS_BUF_LEN_DEF (128 << 10) +#define HIS_BUF_LEN_MAX (1 << 30) /* * Retrieve the command history of a pool. @@ -3745,21 +3754,24 @@ zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover, int zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp) { - char buf[HIS_BUF_LEN]; + char *buf = NULL; + uint64_t bufsize = HIS_BUF_LEN_DEF; uint64_t off = 0; nvlist_t **records = NULL; uint_t numrecords = 0; int err, i; + if ((buf = malloc(bufsize)) == NULL) + return (ENOMEM); do { - uint64_t bytes_read = sizeof (buf); + uint64_t bytes_read = bufsize; uint64_t leftover; if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0) break; /* if nothing else was read in, we're at EOF, just return */ - if (!bytes_read) + if (bytes_read == 0) break; if ((err = zpool_history_unpack(buf, bytes_read, @@ -3767,8 +3779,25 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp) break; off -= leftover; + /* + * If the history block is too big, double the buffer + * size and try again. + */ + if (leftover == bytes_read) { + free(buf); + buf = NULL; + + bufsize <<= 1; + if ((bufsize >= HIS_BUF_LEN_MAX) || + ((buf = malloc(bufsize)) == NULL)) { + err = ENOMEM; + break; + } + } + /* CONSTCOND */ } while (1); + free(buf); if (!err) { verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c index 1fc46c2..feddb69 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c @@ -21,7 +21,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 (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. @@ -1619,6 +1619,62 @@ err_out: return (err); } +int +zfs_send_one(zfs_handle_t *zhp, const char *from, int fd) +{ + int err; + libzfs_handle_t *hdl = zhp->zfs_hdl; + + char errbuf[1024]; + (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, + "warning: cannot send '%s'"), zhp->zfs_name); + + err = lzc_send(zhp->zfs_name, from, fd); + if (err != 0) { + switch (errno) { + case EXDEV: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "not an earlier snapshot from the same fs")); + return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); + + case ENOENT: + case ESRCH: + if (lzc_exists(zhp->zfs_name)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "incremental source (%s) does not exist"), + from); + } + return (zfs_error(hdl, EZFS_NOENT, errbuf)); + + case EBUSY: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "target is busy; if a filesystem, " + "it must not be mounted")); + return (zfs_error(hdl, EZFS_BUSY, errbuf)); + + case EDQUOT: + case EFBIG: + case EIO: + case ENOLINK: + case ENOSPC: +#ifdef illumos + case ENOSTR: +#endif + case ENXIO: + case EPIPE: + case ERANGE: + case EFAULT: + case EROFS: + zfs_error_aux(hdl, strerror(errno)); + return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); + + default: + return (zfs_standard_error(hdl, errno, errbuf)); + } + } + return (err != 0); +} + /* * Routines specific to "zfs recv" */ diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c index 6823c07..3b59914 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -1268,6 +1269,16 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, "use 'none' to disable quota/refquota")); goto error; } + + /* + * Special handling for "*_limit=none". In this case it's not + * 0 but UINT64_MAX. + */ + if ((type & ZFS_TYPE_DATASET) && isnone && + (prop == ZFS_PROP_FILESYSTEM_LIMIT || + prop == ZFS_PROP_SNAPSHOT_LIMIT)) { + *ivalp = UINT64_MAX; + } break; case PROP_TYPE_INDEX: diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c index 6f4b46c..1c87223 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c @@ -486,18 +486,30 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp) } /* - * If fromsnap is NULL, a full (non-incremental) stream will be sent. + * + * "snapname" is the full name of the snapshot to send (e.g. "pool/fs@snap") + * + * If "from" is NULL, a full (non-incremental) stream will be sent. + * If "from" is non-NULL, it must be the full name of a snapshot or + * bookmark to send an incremental from (e.g. "pool/fs@earlier_snap" or + * "pool/fs#earlier_bmark"). If non-NULL, the specified snapshot or + * bookmark must represent an earlier point in the history of "snapname"). + * It can be an earlier snapshot in the same filesystem or zvol as "snapname", + * or it can be the origin of "snapname"'s filesystem, or an earlier + * snapshot in the origin, etc. + * + * "fd" is the file descriptor to write the send stream to. */ int -lzc_send(const char *snapname, const char *fromsnap, int fd) +lzc_send(const char *snapname, const char *from, int fd) { nvlist_t *args; int err; args = fnvlist_alloc(); fnvlist_add_int32(args, "fd", fd); - if (fromsnap != NULL) - fnvlist_add_string(args, "fromsnap", fromsnap); + if (from != NULL) + fnvlist_add_string(args, "fromsnap", from); err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL); nvlist_free(args); return (err); @@ -652,3 +664,97 @@ lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen) } return (err); } + +/* + * Creates bookmarks. + * + * The bookmarks nvlist maps from name of the bookmark (e.g. "pool/fs#bmark") to + * the name of the snapshot (e.g. "pool/fs@snap"). All the bookmarks and + * snapshots must be in the same pool. + * + * The returned results nvlist will have an entry for each bookmark that failed. + * The value will be the (int32) error code. + * + * The return value will be 0 if all bookmarks were created, otherwise it will + * be the errno of a (undetermined) bookmarks that failed. + */ +int +lzc_bookmark(nvlist_t *bookmarks, nvlist_t **errlist) +{ + nvpair_t *elem; + int error; + char pool[MAXNAMELEN]; + + /* determine the pool name */ + elem = nvlist_next_nvpair(bookmarks, NULL); + if (elem == NULL) + return (0); + (void) strlcpy(pool, nvpair_name(elem), sizeof (pool)); + pool[strcspn(pool, "/#")] = '\0'; + + error = lzc_ioctl(ZFS_IOC_BOOKMARK, pool, bookmarks, errlist); + + return (error); +} + +/* + * Retrieve bookmarks. + * + * Retrieve the list of bookmarks for the given file system. The props + * parameter is an nvlist of property names (with no values) that will be + * returned for each bookmark. + * + * The following are valid properties on bookmarks, all of which are numbers + * (represented as uint64 in the nvlist) + * + * "guid" - globally unique identifier of the snapshot it refers to + * "createtxg" - txg when the snapshot it refers to was created + * "creation" - timestamp when the snapshot it refers to was created + * + * The format of the returned nvlist as follows: + * <short name of bookmark> -> { + * <name of property> -> { + * "value" -> uint64 + * } + * } + */ +int +lzc_get_bookmarks(const char *fsname, nvlist_t *props, nvlist_t **bmarks) +{ + return (lzc_ioctl(ZFS_IOC_GET_BOOKMARKS, fsname, props, bmarks)); +} + +/* + * Destroys bookmarks. + * + * The keys in the bmarks nvlist are the bookmarks to be destroyed. + * They must all be in the same pool. Bookmarks are specified as + * <fs>#<bmark>. + * + * Bookmarks that do not exist will be silently ignored. + * + * The return value will be 0 if all bookmarks that existed were destroyed. + * + * Otherwise the return value will be the errno of a (undetermined) bookmark + * that failed, no bookmarks will be destroyed, and the errlist will have an + * entry for each bookmarks that failed. The value in the errlist will be + * the (int32) error code. + */ +int +lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist) +{ + nvpair_t *elem; + int error; + char pool[MAXNAMELEN]; + + /* determine the pool name */ + elem = nvlist_next_nvpair(bmarks, NULL); + if (elem == NULL) + return (0); + (void) strlcpy(pool, nvpair_name(elem), sizeof (pool)); + pool[strcspn(pool, "/#")] = '\0'; + + error = lzc_ioctl(ZFS_IOC_DESTROY_BOOKMARKS, pool, bmarks, errlist); + + return (error); +} diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h index c55caf4..380560f 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h @@ -39,27 +39,27 @@ extern "C" { int libzfs_core_init(void); void libzfs_core_fini(void); -int lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist); -int lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props); -int lzc_clone(const char *fsname, const char *origin, nvlist_t *props); -int lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist); +int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **); +int lzc_create(const char *, dmu_objset_type_t, nvlist_t *); +int lzc_clone(const char *, const char *, nvlist_t *); +int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **); +int lzc_bookmark(nvlist_t *, nvlist_t **); +int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **); +int lzc_destroy_bookmarks(nvlist_t *, nvlist_t **); -int lzc_snaprange_space(const char *firstsnap, const char *lastsnap, - uint64_t *usedp); +int lzc_snaprange_space(const char *, const char *, uint64_t *); -int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist); -int lzc_release(nvlist_t *holds, nvlist_t **errlist); -int lzc_get_holds(const char *snapname, nvlist_t **holdsp); +int lzc_hold(nvlist_t *, int, nvlist_t **); +int lzc_release(nvlist_t *, nvlist_t **); +int lzc_get_holds(const char *, nvlist_t **); -int lzc_send(const char *snapname, const char *fromsnap, int fd); -int lzc_receive(const char *snapname, nvlist_t *props, const char *origin, - boolean_t force, int fd); -int lzc_send_space(const char *snapname, const char *fromsnap, - uint64_t *result); +int lzc_send(const char *, const char *, int); +int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int); +int lzc_send_space(const char *, const char *, uint64_t *); -boolean_t lzc_exists(const char *dataset); +boolean_t lzc_exists(const char *); -int lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen); +int lzc_rollback(const char *, char *, int); #ifdef __cplusplus } diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c index c4e2d2e..2b174f9 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c @@ -20,6 +20,8 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <assert.h> @@ -661,7 +663,7 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...) if (dprintf_find_string("pid")) (void) printf("%d ", getpid()); if (dprintf_find_string("tid")) - (void) printf("%u ", thr_self()); + (void) printf("%ul ", thr_self()); #if 0 if (dprintf_find_string("cpu")) (void) printf("%u ", getcpuid()); @@ -800,20 +802,17 @@ delay(clock_t ticks) /* * Find highest one bit set. * Returns bit number + 1 of highest bit that is set, otherwise returns 0. - * High order bit is 31 (or 63 in _LP64 kernel). */ int -highbit(ulong_t i) +highbit64(uint64_t i) { - register int h = 1; + int h = 1; if (i == 0) return (0); -#ifdef _LP64 - if (i & 0xffffffff00000000ul) { + if (i & 0xffffffff00000000ULL) { h += 32; i >>= 32; } -#endif if (i & 0xffff0000) { h += 16; i >>= 16; } @@ -1125,3 +1124,50 @@ zvol_create_minors(const char *name) return (0); } #endif + +#ifdef illumos +void +bioinit(buf_t *bp) +{ + bzero(bp, sizeof (buf_t)); +} + +void +biodone(buf_t *bp) +{ + if (bp->b_iodone != NULL) { + (*(bp->b_iodone))(bp); + return; + } + ASSERT((bp->b_flags & B_DONE) == 0); + bp->b_flags |= B_DONE; +} + +void +bioerror(buf_t *bp, int error) +{ + ASSERT(bp != NULL); + ASSERT(error >= 0); + + if (error != 0) { + bp->b_flags |= B_ERROR; + } else { + bp->b_flags &= ~B_ERROR; + } + bp->b_error = error; +} + + +int +geterror(struct buf *bp) +{ + int error = 0; + + if (bp->b_flags & B_ERROR) { + error = bp->b_error; + if (!error) + error = EIO; + } + return (error); +} +#endif diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h index 15c181e..cc8285d 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h +++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h @@ -20,9 +20,12 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ #ifndef _SYS_ZFS_CONTEXT_H #define _SYS_ZFS_CONTEXT_H @@ -62,6 +65,7 @@ extern "C" { #include <inttypes.h> #include <fsshare.h> #include <pthread.h> +#include <sched.h> #include <sys/debug.h> #include <sys/note.h> #include <sys/types.h> @@ -201,6 +205,8 @@ extern int aok; */ #define curthread ((void *)(uintptr_t)thr_self()) +#define kpreempt(x) sched_yield() + typedef struct kthread kthread_t; #define thread_create(stk, stksize, func, arg, len, pp, state, pri) \ @@ -367,6 +373,16 @@ typedef struct taskq taskq_t; typedef uintptr_t taskqid_t; typedef void (task_func_t)(void *); +typedef struct taskq_ent { + struct taskq_ent *tqent_next; + struct taskq_ent *tqent_prev; + task_func_t *tqent_func; + void *tqent_arg; + uintptr_t tqent_flags; +} taskq_ent_t; + +#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */ + #define TASKQ_PREPOPULATE 0x0001 #define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ #define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ @@ -378,6 +394,7 @@ typedef void (task_func_t)(void *); #define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ #define TQ_FRONT 0x08 /* Queue in front */ + extern taskq_t *system_taskq; extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); @@ -386,6 +403,8 @@ extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); #define taskq_create_sysdc(a, b, d, e, p, dc, f) \ (taskq_create(a, b, maxclsyspri, d, e, f)) extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); +extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, + taskq_ent_t *); extern void taskq_destroy(taskq_t *); extern void taskq_wait(taskq_t *); extern int taskq_member(taskq_t *, void *); @@ -539,7 +558,7 @@ extern void delay(clock_t ticks); extern uint64_t physmem; -extern int highbit(ulong_t i); +extern int highbit64(uint64_t i); extern int random_get_bytes(uint8_t *ptr, size_t len); extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); @@ -759,6 +778,38 @@ extern void cyclic_remove(cyclic_id_t); extern int cyclic_reprogram(cyclic_id_t, hrtime_t); #endif /* illumos */ +#ifdef illumos +/* + * Buf structure + */ +#define B_BUSY 0x0001 +#define B_DONE 0x0002 +#define B_ERROR 0x0004 +#define B_READ 0x0040 /* read when I/O occurs */ +#define B_WRITE 0x0100 /* non-read pseudo-flag */ + +typedef struct buf { + int b_flags; + size_t b_bcount; + union { + caddr_t b_addr; + } b_un; + + lldaddr_t _b_blkno; +#define b_lblkno _b_blkno._f + size_t b_resid; + size_t b_bufsize; + int (*b_iodone)(struct buf *); + int b_error; + void *b_private; +} buf_t; + +extern void bioinit(buf_t *); +extern void biodone(buf_t *); +extern void bioerror(buf_t *, int); +extern int geterror(buf_t *); +#endif + #ifdef __cplusplus } #endif diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c index c407bba..d4036d0 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c @@ -22,19 +22,15 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ #include <sys/zfs_context.h> int taskq_now; taskq_t *system_taskq; -typedef struct task { - struct task *task_next; - struct task *task_prev; - task_func_t *task_func; - void *task_arg; -} task_t; - #define TASKQ_ACTIVE 0x00010000 struct taskq { @@ -51,18 +47,18 @@ struct taskq { int tq_maxalloc; kcondvar_t tq_maxalloc_cv; int tq_maxalloc_wait; - task_t *tq_freelist; - task_t tq_task; + taskq_ent_t *tq_freelist; + taskq_ent_t tq_task; }; -static task_t * +static taskq_ent_t * task_alloc(taskq_t *tq, int tqflags) { - task_t *t; + taskq_ent_t *t; int rv; again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) { - tq->tq_freelist = t->task_next; + tq->tq_freelist = t->tqent_next; } else { if (tq->tq_nalloc >= tq->tq_maxalloc) { if (!(tqflags & KM_SLEEP)) @@ -87,7 +83,7 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) { } mutex_exit(&tq->tq_lock); - t = kmem_alloc(sizeof (task_t), tqflags & KM_SLEEP); + t = kmem_alloc(sizeof (taskq_ent_t), tqflags & KM_SLEEP); mutex_enter(&tq->tq_lock); if (t != NULL) @@ -97,15 +93,15 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) { } static void -task_free(taskq_t *tq, task_t *t) +task_free(taskq_t *tq, taskq_ent_t *t) { if (tq->tq_nalloc <= tq->tq_minalloc) { - t->task_next = tq->tq_freelist; + t->tqent_next = tq->tq_freelist; tq->tq_freelist = t; } else { tq->tq_nalloc--; mutex_exit(&tq->tq_lock); - kmem_free(t, sizeof (task_t)); + kmem_free(t, sizeof (taskq_ent_t)); mutex_enter(&tq->tq_lock); } @@ -116,7 +112,7 @@ task_free(taskq_t *tq, task_t *t) taskqid_t taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) { - task_t *t; + taskq_ent_t *t; if (taskq_now) { func(arg); @@ -130,26 +126,58 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) return (0); } if (tqflags & TQ_FRONT) { - t->task_next = tq->tq_task.task_next; - t->task_prev = &tq->tq_task; + t->tqent_next = tq->tq_task.tqent_next; + t->tqent_prev = &tq->tq_task; } else { - t->task_next = &tq->tq_task; - t->task_prev = tq->tq_task.task_prev; + t->tqent_next = &tq->tq_task; + t->tqent_prev = tq->tq_task.tqent_prev; } - t->task_next->task_prev = t; - t->task_prev->task_next = t; - t->task_func = func; - t->task_arg = arg; + t->tqent_next->tqent_prev = t; + t->tqent_prev->tqent_next = t; + t->tqent_func = func; + t->tqent_arg = arg; cv_signal(&tq->tq_dispatch_cv); mutex_exit(&tq->tq_lock); return (1); } void +taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, + taskq_ent_t *t) +{ + ASSERT(func != NULL); + ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC)); + + /* + * Mark it as a prealloc'd task. This is important + * to ensure that we don't free it later. + */ + t->tqent_flags |= TQENT_FLAG_PREALLOC; + /* + * Enqueue the task to the underlying queue. + */ + mutex_enter(&tq->tq_lock); + + if (flags & TQ_FRONT) { + t->tqent_next = tq->tq_task.tqent_next; + t->tqent_prev = &tq->tq_task; + } else { + t->tqent_next = &tq->tq_task; + t->tqent_prev = tq->tq_task.tqent_prev; + } + t->tqent_next->tqent_prev = t; + t->tqent_prev->tqent_next = t; + t->tqent_func = func; + t->tqent_arg = arg; + cv_signal(&tq->tq_dispatch_cv); + mutex_exit(&tq->tq_lock); +} + +void taskq_wait(taskq_t *tq) { mutex_enter(&tq->tq_lock); - while (tq->tq_task.task_next != &tq->tq_task || tq->tq_active != 0) + while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0) cv_wait(&tq->tq_wait_cv, &tq->tq_lock); mutex_exit(&tq->tq_lock); } @@ -158,27 +186,32 @@ static void * taskq_thread(void *arg) { taskq_t *tq = arg; - task_t *t; + taskq_ent_t *t; + boolean_t prealloc; mutex_enter(&tq->tq_lock); while (tq->tq_flags & TASKQ_ACTIVE) { - if ((t = tq->tq_task.task_next) == &tq->tq_task) { + if ((t = tq->tq_task.tqent_next) == &tq->tq_task) { if (--tq->tq_active == 0) cv_broadcast(&tq->tq_wait_cv); cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock); tq->tq_active++; continue; } - t->task_prev->task_next = t->task_next; - t->task_next->task_prev = t->task_prev; + t->tqent_prev->tqent_next = t->tqent_next; + t->tqent_next->tqent_prev = t->tqent_prev; + t->tqent_next = NULL; + t->tqent_prev = NULL; + prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC; mutex_exit(&tq->tq_lock); rw_enter(&tq->tq_threadlock, RW_READER); - t->task_func(t->task_arg); + t->tqent_func(t->tqent_arg); rw_exit(&tq->tq_threadlock); mutex_enter(&tq->tq_lock); - task_free(tq, t); + if (!prealloc) + task_free(tq, t); } tq->tq_nthreads--; cv_broadcast(&tq->tq_wait_cv); @@ -217,8 +250,8 @@ taskq_create(const char *name, int nthreads, pri_t pri, tq->tq_nthreads = nthreads; tq->tq_minalloc = minalloc; tq->tq_maxalloc = maxalloc; - tq->tq_task.task_next = &tq->tq_task; - tq->tq_task.task_prev = &tq->tq_task; + tq->tq_task.tqent_next = &tq->tq_task; + tq->tq_task.tqent_prev = &tq->tq_task; tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP); if (flags & TASKQ_PREPOPULATE) { diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py b/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py index fa8209f..7ad4b49 100644 --- a/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py +++ b/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py @@ -20,6 +20,7 @@ # CDDL HEADER END # # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013 by Delphix. All rights reserved. # """This module implements the "zfs allow" and "zfs unallow" subcommands. @@ -219,6 +220,7 @@ perms_subcmd = dict( hold=_("Allows adding a user hold to a snapshot"), release=_("Allows releasing a user hold which\n\t\t\t\tmight destroy the snapshot"), diff=_("Allows lookup of paths within a dataset,\n\t\t\t\tgiven an object number. Ordinary users need this\n\t\t\t\tin order to use zfs diff"), + bookmark="", ) perms_other = dict( diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c index 0738dd0..55ce7b2 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c @@ -96,9 +96,6 @@ #include "list.h" #include "traverse.h" -/* The version of DWARF which we support. */ -#define DWARF_VERSION 2 - /* * We need to define a couple of our own intrinsics, to smooth out some of the * differences between the GCC and DevPro DWARF emitters. See the referenced @@ -271,7 +268,7 @@ die_off(dwarf_t *dw, Dwarf_Die die) return (off); terminate("failed to get offset for die: %s\n", - dwarf_errmsg(&dw->dw_err)); + dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (0); } @@ -289,7 +286,7 @@ die_sibling(dwarf_t *dw, Dwarf_Die die) return (NULL); terminate("die %llu: failed to find type sibling: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); } @@ -306,7 +303,7 @@ die_child(dwarf_t *dw, Dwarf_Die die) return (NULL); terminate("die %llu: failed to find type child: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); } @@ -320,7 +317,7 @@ die_tag(dwarf_t *dw, Dwarf_Die die) return (tag); terminate("die %llu: failed to get tag for type: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (0); } @@ -343,7 +340,7 @@ die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req) } terminate("die %llu: failed to get attribute for type: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); } @@ -353,10 +350,10 @@ die_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp, int req) { *valp = 0; - if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { + if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DW_DLV_OK) { if (req) terminate("die %llu: failed to get signed: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); return (0); } @@ -368,10 +365,10 @@ die_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp, int req) { *valp = 0; - if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { + if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DW_DLV_OK) { if (req) terminate("die %llu: failed to get unsigned: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); return (0); } @@ -383,10 +380,10 @@ die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req) { *valp = 0; - if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { + if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DW_DLV_OK) { if (req) terminate("die %llu: failed to get flag: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); return (0); } @@ -398,11 +395,11 @@ die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req) { const char *str = NULL; - if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE || + if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DW_DLV_OK || str == NULL) { if (req) terminate("die %llu: failed to get string: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); else *strp = NULL; return (0); @@ -417,9 +414,9 @@ die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) { Dwarf_Off off; - if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) { + if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get ref: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + die_off(dw, die), dwarf_errmsg(dw->dw_err)); } return (off); @@ -431,6 +428,8 @@ die_name(dwarf_t *dw, Dwarf_Die die) char *str = NULL; (void) die_string(dw, die, DW_AT_name, &str, 0); + if (str == NULL) + str = xstrdup(""); return (str); } @@ -489,21 +488,73 @@ die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, { Dwarf_Locdesc *loc = NULL; Dwarf_Signed locnum = 0; + Dwarf_Attribute at; + Dwarf_Half form; + + if (name != DW_AT_data_member_location) + terminate("die %llu: can only process attribute " + "DW_AT_data_member_location\n", die_off(dw, die)); - if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) + if ((at = die_attr(dw, die, name, 0)) == NULL) return (0); - if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { - terminate("die %llu: cannot parse member offset\n", - die_off(dw, die)); - } + if (dwarf_whatform(at, &form, &dw->dw_err) != DW_DLV_OK) + return (0); + + switch (form) { + case DW_FORM_sec_offset: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + /* + * GCC in base and Clang (3.3 or below) generates + * DW_AT_data_member_location attribute with DW_FORM_block* + * form. The attribute contains one DW_OP_plus_uconst + * operator. The member offset stores in the operand. + */ + if (dwarf_loclist(at, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) + return (0); + if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { + terminate("die %llu: cannot parse member offset with " + "operator other than DW_OP_plus_uconst\n", + die_off(dw, die)); + } + *valp = loc->ld_s->lr_number; + if (loc != NULL) { + dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC); + } + break; - *valp = loc->ld_s->lr_number; + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + /* + * Clang 3.4 generates DW_AT_data_member_location attribute + * with DW_FORM_data* form (constant class). The attribute + * stores a contant value which is the member offset. + * + * However, note that DW_FORM_data[48] in DWARF version 2 or 3 + * could be used as a section offset (offset into .debug_loc in + * this case). Here we assume the attribute always stores a + * constant because we know Clang 3.4 does this and GCC in + * base won't emit DW_FORM_data[48] for this attribute. This + * code will remain correct if future vesrions of Clang and + * GCC conform to DWARF4 standard and only use the form + * DW_FORM_sec_offset for section offset. + */ + if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != + DW_DLV_OK) + return (0); + break; - if (loc != NULL) - if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK) - terminate("die %llu: cannot free location descriptor: %s\n", - die_off(dw, die), dwarf_errmsg(&dw->dw_err)); + default: + terminate("die %llu: cannot parse member offset with form " + "%u\n", die_off(dw, die), form); + } return (1); } @@ -885,6 +936,9 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp, int type, const char *typename) { Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0; +#if BYTE_ORDER == _LITTLE_ENDIAN + Dwarf_Unsigned bysz; +#endif Dwarf_Die mem; mlist_t *ml, **mlastp; iidesc_t *ii; @@ -959,8 +1013,26 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp, #if BYTE_ORDER == _BIG_ENDIAN ml->ml_offset += bitoff; #else - ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff - - ml->ml_size; + /* + * Note that Clang 3.4 will sometimes generate + * member DIE before generating the DIE for the + * member's type. The code can not handle this + * properly so that tdesc_bitsize(ml->ml_type) will + * return 0 because ml->ml_type is unknown. As a + * result, a wrong member offset will be calculated. + * To workaround this, we can instead try to + * retrieve the value of DW_AT_byte_size attribute + * which stores the byte size of the space occupied + * by the type. If this attribute exists, its value + * should equal to tdesc_bitsize(ml->ml_type)/NBBY. + */ + if (die_unsigned(dw, mem, DW_AT_byte_size, &bysz, 0) && + bysz > 0) + ml->ml_offset += bysz * NBBY - bitoff - + ml->ml_size; + else + ml->ml_offset += tdesc_bitsize(ml->ml_type) - + bitoff - ml->ml_size; #endif } @@ -1852,7 +1924,7 @@ int dw_read(tdata_t *td, Elf *elf, char *filename __unused) { Dwarf_Unsigned abboff, hdrlen, nxthdr; - Dwarf_Half vers, addrsz; + Dwarf_Half vers, addrsz, offsz; Dwarf_Die cu = 0; Dwarf_Die child = 0; dwarf_t dw; @@ -1869,7 +1941,7 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused) dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash, tdesc_namecmp); - if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw, + if ((rc = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw.dw_dw, &dw.dw_err)) == DW_DLV_NO_ENTRY) { if (should_have_dwarf(elf)) { errno = ENOENT; @@ -1878,7 +1950,7 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused) return (0); } } else if (rc != DW_DLV_OK) { - if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) { + if (dwarf_errno(dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) { /* * There's no type data in the DWARF section, but * libdwarf is too clever to handle that properly. @@ -1887,12 +1959,12 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused) } terminate("failed to initialize DWARF: %s\n", - dwarf_errmsg(&dw.dw_err)); + dwarf_errmsg(dw.dw_err)); } - if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff, - &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK) - terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err)); + if ((rc = dwarf_next_cu_header_b(dw.dw_dw, &hdrlen, &vers, &abboff, + &addrsz, &offsz, NULL, &nxthdr, &dw.dw_err)) != DW_DLV_OK) + terminate("rc = %d %s\n", rc, dwarf_errmsg(dw.dw_err)); if ((cu = die_sibling(&dw, NULL)) == NULL || (((child = die_child(&dw, cu)) == NULL) && @@ -1909,9 +1981,9 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused) terminate("file contains too many types\n"); debug(1, "DWARF version: %d\n", vers); - if (vers != DWARF_VERSION) { + if (vers < 2 || vers > 4) { terminate("file contains incompatible version %d DWARF code " - "(version 2 required)\n", vers); + "(version 2, 3 or 4 required)\n", vers); } if (die_string(&dw, cu, DW_AT_producer, &prod, 0)) { @@ -1930,11 +2002,11 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused) if ((child = die_child(&dw, cu)) != NULL) die_create(&dw, child); - if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff, - &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY) + if ((rc = dwarf_next_cu_header_b(dw.dw_dw, &hdrlen, &vers, &abboff, + &addrsz, &offsz, NULL, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY) terminate("multiple compilation units not supported\n"); - (void) dwarf_finish(&dw.dw_dw, &dw.dw_err); + (void) dwarf_finish(dw.dw_dw, &dw.dw_err); die_resolve(&dw); diff --git a/cddl/lib/Makefile b/cddl/lib/Makefile index 53d402a..fef1383 100644 --- a/cddl/lib/Makefile +++ b/cddl/lib/Makefile @@ -11,7 +11,12 @@ SUBDIR= ${_drti} \ libuutil \ ${_libzfs_core} \ ${_libzfs} \ - ${_libzpool} + ${_libzpool} \ + ${_tests} + +.if ${MK_TESTS} != "no" +_tests= tests +.endif .if ${MK_ZFS} != "no" _libzfs_core= libzfs_core diff --git a/cddl/lib/libctf/Makefile b/cddl/lib/libctf/Makefile index 5829111..50c7937 100644 --- a/cddl/lib/libctf/Makefile +++ b/cddl/lib/libctf/Makefile @@ -27,5 +27,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ -I${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common \ -I${OPENSOLARIS_SYS_DISTDIR}/uts/common +DPADD= ${LIBZ} +LDADD= -lz + .include <bsd.lib.mk> diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 46f7046..006740a 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -69,9 +69,11 @@ CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \ #CFLAGS+= -DYYDEBUG .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" +CFLAGS+= -I${.CURDIR}/../../../sys/cddl/dev/dtrace/x86 CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386 .PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH} +.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/x86 .elif ${MACHINE_CPUARCH} == "sparc64" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc diff --git a/cddl/lib/libdtrace/psinfo.d b/cddl/lib/libdtrace/psinfo.d index 068e72e..c2219f7 100644 --- a/cddl/lib/libdtrace/psinfo.d +++ b/cddl/lib/libdtrace/psinfo.d @@ -57,7 +57,8 @@ translator psinfo_t < struct proc *T > { pr_gid = T->p_ucred->cr_rgid; pr_egid = T->p_ucred->cr_groups[0]; pr_addr = 0; - pr_psargs = stringof(T->p_args->ar_args); + pr_psargs = (T->p_args->ar_args == 0) ? "" : + memstr(T->p_args->ar_args, ' ', T->p_args->ar_length); pr_arglen = T->p_args->ar_length; pr_jailid = T->p_ucred->cr_prison->pr_id; }; diff --git a/cddl/lib/libnvpair/Makefile b/cddl/lib/libnvpair/Makefile index bd159fc..677068f 100644 --- a/cddl/lib/libnvpair/Makefile +++ b/cddl/lib/libnvpair/Makefile @@ -21,4 +21,13 @@ CFLAGS+= -I${.CURDIR}/../../../sys CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem +# This library uses macros to define fprintf behavior for several object types +# The compiler will see the non-string literal arguments to the fprintf calls and +# omit warnings for them. Quiesce these warnings in contrib code: +# +# cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c:743:12: warning: format +# string is not a string literal (potentially insecure) [-Wformat-security] +# ARENDER(pctl, nvlist_array, nvl, name, val, nelem); +# +CFLAGS+= -Wno-format-security .include <bsd.lib.mk> diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile index 848325a..7d4528f 100644 --- a/cddl/lib/libzpool/Makefile +++ b/cddl/lib/libzpool/Makefile @@ -60,7 +60,7 @@ DPADD= ${LIBMD} ${LIBPTHREAD} ${LIBZ} LDADD= -lmd -lpthread -lz # atomic.S doesn't like profiling. -NO_PROFILE= +MK_PROFILE= no CSTD= c99 diff --git a/cddl/lib/tests/Makefile b/cddl/lib/tests/Makefile new file mode 100644 index 0000000..4a49d9f --- /dev/null +++ b/cddl/lib/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/cddl/lib + +.PATH: ${.CURDIR:H:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> diff --git a/cddl/sbin/Makefile b/cddl/sbin/Makefile index f74307c..4fd96f6 100644 --- a/cddl/sbin/Makefile +++ b/cddl/sbin/Makefile @@ -2,7 +2,11 @@ .include <bsd.own.mk> -SUBDIR= ${_zfs} ${_zpool} +SUBDIR= ${_tests} ${_zfs} ${_zpool} + +.if ${MK_TESTS} != "no" +_tests= tests +.endif .if ${MK_ZFS} != "no" _zfs= zfs diff --git a/cddl/sbin/tests/Makefile b/cddl/sbin/tests/Makefile new file mode 100644 index 0000000..91bbaee --- /dev/null +++ b/cddl/sbin/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/cddl/sbin + +.PATH: ${.CURDIR:H:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> diff --git a/cddl/tests/Makefile b/cddl/tests/Makefile new file mode 100644 index 0000000..34a27ea --- /dev/null +++ b/cddl/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/cddl + +.PATH: ${.CURDIR:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> diff --git a/cddl/usr.bin/Makefile b/cddl/usr.bin/Makefile index 13d3a86..3547ff7 100644 --- a/cddl/usr.bin/Makefile +++ b/cddl/usr.bin/Makefile @@ -7,11 +7,16 @@ SUBDIR= \ ctfdump \ ctfmerge \ sgsmsg \ + ${_tests} \ ${_zinject} \ ${_zlook} \ ${_zstreamdump} \ ${_ztest} +.if ${MK_TESTS} != "no" +_tests= tests +.endif + .if ${MK_ZFS} != "no" _zinject= zinject #_zlook= zlook diff --git a/cddl/usr.bin/sgsmsg/Makefile b/cddl/usr.bin/sgsmsg/Makefile index 8d1f70f..e1b318c 100644 --- a/cddl/usr.bin/sgsmsg/Makefile +++ b/cddl/usr.bin/sgsmsg/Makefile @@ -5,7 +5,7 @@ # This program is required as a bootstrap tool for 'make buildworld' PROG= sgsmsg -NO_MAN= +MAN= SRCS= avl.c sgsmsg.c string_table.c findprime.c WARNS?= 0 diff --git a/cddl/usr.bin/tests/Makefile b/cddl/usr.bin/tests/Makefile new file mode 100644 index 0000000..c94d591 --- /dev/null +++ b/cddl/usr.bin/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/cddl/usr.bin + +.PATH: ${.CURDIR:H:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> diff --git a/cddl/usr.bin/zinject/Makefile b/cddl/usr.bin/zinject/Makefile index 8c5c141..adb5023 100644 --- a/cddl/usr.bin/zinject/Makefile +++ b/cddl/usr.bin/zinject/Makefile @@ -4,7 +4,7 @@ PROG= zinject SRCS= zinject.c translate.c -NO_MAN= +MAN= WARNS?= 0 CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris @@ -16,6 +16,7 @@ CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libnvpair CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common +CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs/ CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head CFLAGS+= -I${.CURDIR}/../../lib/libumem diff --git a/cddl/usr.bin/zlook/Makefile b/cddl/usr.bin/zlook/Makefile index 0251f57..eae2fd0 100644 --- a/cddl/usr.bin/zlook/Makefile +++ b/cddl/usr.bin/zlook/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zlook PROG= zlook -NO_MAN= +MAN= WARNS?= 0 CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile index 370eacb5..0865226 100644 --- a/cddl/usr.bin/ztest/Makefile +++ b/cddl/usr.bin/ztest/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest PROG= ztest -NO_MAN= +MAN= WARNS?= 0 CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris diff --git a/cddl/usr.sbin/Makefile b/cddl/usr.sbin/Makefile index fb2c437..8551c28 100644 --- a/cddl/usr.sbin/Makefile +++ b/cddl/usr.sbin/Makefile @@ -5,9 +5,14 @@ SUBDIR= ${_dtrace} \ ${_dtruss} \ ${_lockstat} \ + ${_tests} \ ${_zdb} \ ${_zhack} +.if ${MK_TESTS} != "no" +_tests= tests +.endif + .if ${MK_ZFS} != "no" .if ${MK_LIBTHR} != "no" _zdb= zdb diff --git a/cddl/usr.sbin/lockstat/Makefile b/cddl/usr.sbin/lockstat/Makefile index ef3ac3c..0668758 100644 --- a/cddl/usr.sbin/lockstat/Makefile +++ b/cddl/usr.sbin/lockstat/Makefile @@ -3,7 +3,6 @@ .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/lockstat PROG= lockstat -NO_MAN= SRCS= lockstat.c sym.c BINDIR?= /usr/sbin diff --git a/cddl/usr.sbin/tests/Makefile b/cddl/usr.sbin/tests/Makefile new file mode 100644 index 0000000..0305aee --- /dev/null +++ b/cddl/usr.sbin/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/cddl/usr.sbin + +.PATH: ${.CURDIR:H:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> diff --git a/cddl/usr.sbin/zhack/Makefile b/cddl/usr.sbin/zhack/Makefile index f09d2d8..9ae3395 100644 --- a/cddl/usr.sbin/zhack/Makefile +++ b/cddl/usr.sbin/zhack/Makefile @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zhack PROG= zhack -NO_MAN= +MAN= WARNS?= 0 CSTD= c99 diff --git a/lib/Makefile b/lib/Makefile index 9ac8945..fe99085 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -32,8 +32,13 @@ SUBDIR_ORDERED= ${_csu} \ libc \ + libc_nonshared \ libbsm \ libauditd \ + libutil \ + libpjdlog \ + libnv \ + ${_libcapsicum} \ libcompiler_rt \ libcrypt \ libelf \ @@ -48,7 +53,6 @@ SUBDIR_ORDERED= ${_csu} \ librpcsvc \ libsbuf \ libtacplus \ - libutil \ ${_libypclnt} \ ${_libcxxrt} \ ${_libcplusplus} @@ -65,9 +69,11 @@ SUBDIR= ${SUBDIR_ORDERED} \ libblocksruntime \ ${_libbluetooth} \ ${_libbsnmp} \ + libbsdstat \ libbz2 \ libcalendar \ libcam \ + ${_libcasper} \ libcompat \ libdevinfo \ libdevstat \ @@ -81,9 +87,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libgpib} \ ${_libgssapi} \ ${_librpcsec_gss} \ - ${_libiconv_compat} \ libipsec \ - ${_libipx} \ libjail \ libkiconv \ liblzma \ @@ -114,6 +118,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libtelnet} \ ${_libthr} \ libthread_db \ + libucl \ libufs \ libugidfw \ libulog \ @@ -124,10 +129,10 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libvmmapi} \ libwrap \ liby \ - libyaml \ libz \ ${_atf} \ - ${_clang} + ${_clang} \ + ${_tests} .if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf) _csu=csu/${MACHINE_ARCH}-elf @@ -141,10 +146,6 @@ _csu=csu # NB: keep these sorted by MK_* knobs -.if ${MK_ATF} != "no" -_atf= atf -.endif - .if ${MK_ATM} != "no" _libngatm= libngatm .endif @@ -158,6 +159,11 @@ _libsdp= libsdp _libbsnmp= libbsnmp .endif +.if ${MK_CASPER} != "no" +_libcapsicum= libcapsicum +_libcasper= libcasper +.endif + .if ${MK_CLANG} != "no" && !defined(COMPAT_32BIT) _clang= clang .endif @@ -175,10 +181,6 @@ _librpcsec_gss= librpcsec_gss _libiconv_modules= libiconv_modules .endif -.if ${MK_IPX} != "no" -_libipx= libipx -.endif - .if ${MK_LDNS} != "no" _libldns= libldns .endif @@ -188,10 +190,6 @@ _libcxxrt= libcxxrt _libcplusplus= libc++ .endif -.if ${MK_LIBICONV_COMPAT} != "no" -_libiconv_compat= libiconv_compat -.endif - .if ${MK_LIBTHR} != "no" _libthr= libthr .endif @@ -258,6 +256,11 @@ _libsmutil= libsmutil _libtelnet= libtelnet .endif +.if ${MK_TESTS} != "no" +_atf= atf +_tests= tests +.endif + .if ${MK_UNBOUND} != "no" _libunbound= libunbound .endif @@ -272,4 +275,8 @@ afterinstall: ${INSTALL_SYMLINK} ../include ${DESTDIR}/usr/lib/include .endif +.if !make(install) +SUBDIR_PARALLEL= +.endif + .include <bsd.subdir.mk> diff --git a/lib/atf/Makefile b/lib/atf/Makefile index 0da9aa8..a191f0d 100644 --- a/lib/atf/Makefile +++ b/lib/atf/Makefile @@ -27,9 +27,13 @@ .include <bsd.own.mk> -SUBDIR= \ - libatf-c \ - libatf-c++ +SUBDIR= libatf-c \ + libatf-c++ \ + ${_tests} + +.if ${MK_TESTS} != "no" +_tests= tests +.endif .ORDER: ${SUBDIR} diff --git a/lib/atf/Makefile.inc b/lib/atf/Makefile.inc index 937187a..40da946 100644 --- a/lib/atf/Makefile.inc +++ b/lib/atf/Makefile.inc @@ -25,8 +25,6 @@ # # $FreeBSD$ -ATF= ${.CURDIR}/../../../contrib/atf - _CFLAGS:= ${CFLAGS} _CPPFLAGS:= ${CPPFLAGS} _CXXFLAGS:= ${CXXFLAGS} @@ -40,6 +38,7 @@ CFLAGS+= -DATF_BUILD_CPPFLAGS='"${_CPPFLAGS}"' CFLAGS+= -DATF_BUILD_CXX='"${CXX}"' CFLAGS+= -DATF_BUILD_CXXFLAGS='"${_CXXFLAGS}"' CFLAGS+= -DATF_CONFDIR='"${CONFDIR}/atf"' +CFLAGS+= -DATF_C_TESTS_BASE='"${TESTSBASE}/lib/atf/libatf-c"' CFLAGS+= -DATF_INCLUDEDIR='"${INCLUDEDIR}"' CFLAGS+= -DATF_LIBDIR='"${LIBDIR}"' CFLAGS+= -DATF_LIBEXECDIR='"${LIBEXECDIR}"' diff --git a/lib/atf/common.mk b/lib/atf/common.mk new file mode 100644 index 0000000..6338207 --- /dev/null +++ b/lib/atf/common.mk @@ -0,0 +1,19 @@ +# $FreeBSD$ +# +# Common Makefile code for all components of ATF. +# + +.if !defined(ATF) +.error "ATF must be defined and point to the contrib/atf directory" +.endif + +# Depend on the atf-version target to generate a file that contains the +# version number of the currently imported ATF release and that only +# changes on new imports. +atf-version: atf-version-real + @cmp -s atf-version atf-version-real \ + || cp atf-version-real atf-version +atf-version-real: .PHONY + @grep 'define VERSION' ${ATF}/bconfig.h \ + | cut -d '"' -f 2 >atf-version-real +CLEANFILES+= atf-version atf-version-real diff --git a/lib/atf/libatf-c++/Makefile b/lib/atf/libatf-c++/Makefile index 37d6073..d52e496 100644 --- a/lib/atf/libatf-c++/Makefile +++ b/lib/atf/libatf-c++/Makefile @@ -28,7 +28,7 @@ .include <bsd.init.mk> LIB= atf-c++ -SHLIB_MAJOR= 1 +SHLIB_MAJOR= 2 # libatf-c++ depends on the C version of the ATF library to build. DPADD= ${LIBATFC} @@ -36,6 +36,7 @@ LDADD= -latf-c LDFLAGS+= -L${.OBJDIR}/../libatf-c +ATF= ${.CURDIR:H:H:H}/contrib/atf .PATH: ${ATF} .PATH: ${ATF}/atf-c++ .PATH: ${ATF}/atf-c++/detail @@ -52,13 +53,11 @@ SRCS= application.cpp \ config.cpp \ env.cpp \ exceptions.cpp \ - expand.cpp \ fs.cpp \ - parser.cpp \ process.cpp \ tests.cpp \ text.cpp \ - ui.cpp + utils.cpp INCS= build.hpp \ check.hpp \ @@ -73,4 +72,23 @@ INCSDIR_atf-c++.hpp= ${INCLUDEDIR} MAN= atf-c++-api.3 +all: atf-c++.pc +atf-c++.pc: atf-c++.pc.in atf-version + sed -e 's,__CXX__,${CXX},g' \ + -e 's,__INCLUDEDIR__,${INCLUDEDIR},g' \ + -e 's,__LIBDIR__,${LIBDIR},g' \ + -e "s,__ATF_VERSION__,$$(cat atf-version),g" \ + <${ATF}/atf-c++/atf-c++.pc.in >atf-c++.pc + +beforeinstall: + ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ + atf-c++.pc ${DESTDIR}${LIBDATADIR}/pkgconfig + ${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \ + ${ATF}/atf-c++/atf-c++.m4 ${DESTDIR}${SHAREDIR}/aclocal + +.if ${MK_TESTS} != "no" +SUBDIR= tests +.endif + +.include "../common.mk" .include <bsd.lib.mk> diff --git a/lib/atf/libatf-c++/Makefile.inc b/lib/atf/libatf-c++/Makefile.inc new file mode 100644 index 0000000..265f86d --- /dev/null +++ b/lib/atf/libatf-c++/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/lib/atf/libatf-c++/tests/Makefile b/lib/atf/libatf-c++/tests/Makefile new file mode 100644 index 0000000..c5a1d24 --- /dev/null +++ b/lib/atf/libatf-c++/tests/Makefile @@ -0,0 +1,31 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c++ +TESTS_SUBDIRS= detail + +ATF= ${.CURDIR:H:H:H:H}/contrib/atf +.PATH: ${ATF}/atf-c++ +.PATH: ${ATF}/atf-c++/detail + +CFLAGS+= -I${ATF} + +FILESDIR= ${TESTSDIR} +FILES= macros_hpp_test.cpp +FILES+= unused_test.cpp + +.for _T in atf_c++_test \ + build_test \ + check_test \ + config_test \ + macros_test \ + tests_test \ + utils_test +ATF_TESTS_CXX+= ${_T} +SRCS.${_T}= ${_T}.cpp test_helpers.cpp +.endfor + +ATF_TESTS_SH= pkg_config_test + +.include <bsd.test.mk> diff --git a/lib/atf/libatf-c++/tests/Makefile.inc b/lib/atf/libatf-c++/tests/Makefile.inc new file mode 100644 index 0000000..265f86d --- /dev/null +++ b/lib/atf/libatf-c++/tests/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/lib/atf/libatf-c++/tests/detail/Makefile b/lib/atf/libatf-c++/tests/detail/Makefile new file mode 100644 index 0000000..b3fd4dc --- /dev/null +++ b/lib/atf/libatf-c++/tests/detail/Makefile @@ -0,0 +1,32 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c++/detail + +ATF= ${.CURDIR:H:H:H:H:H}/contrib/atf +.PATH: ${ATF}/atf-c++/detail + +CFLAGS+= -I${ATF} + +.for _T in application_test \ + env_test \ + exceptions_test \ + fs_test \ + process_test \ + sanity_test \ + text_test +ATF_TESTS_CXX+= ${_T} +SRCS.${_T}= ${_T}.cpp test_helpers.cpp +.endfor + +.for p in version_helper +PROGS_CXX+= ${p} +SRCS.${p}= ${p}.cpp +MAN.${p}= # defined +BINDIR.${p}= ${TESTSDIR} +.endfor +version_helper.o: atf-version + +.include "../../../common.mk" +.include <bsd.test.mk> diff --git a/lib/atf/libatf-c/Makefile b/lib/atf/libatf-c/Makefile index 26fba5c..69c4611 100644 --- a/lib/atf/libatf-c/Makefile +++ b/lib/atf/libatf-c/Makefile @@ -30,6 +30,7 @@ LIB= atf-c SHLIB_MAJOR= 1 +ATF= ${.CURDIR:H:H:H}/contrib/atf .PATH: ${ATF} .PATH: ${ATF}/atf-c .PATH: ${ATF}/atf-c/detail @@ -73,4 +74,25 @@ INCSDIR_atf-c.h= ${INCLUDEDIR} MAN= atf-c-api.3 +all: atf-c.pc +atf-c.pc: atf-c.pc.in atf-version + sed -e 's,__CC__,${CC},g' \ + -e 's,__INCLUDEDIR__,${INCLUDEDIR},g' \ + -e 's,__LIBDIR__,${LIBDIR},g' \ + -e "s,__ATF_VERSION__,$$(cat atf-version),g" \ + <${ATF}/atf-c/atf-c.pc.in >atf-c.pc + +beforeinstall: + ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ + atf-c.pc ${DESTDIR}${LIBDATADIR}/pkgconfig + ${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \ + ${ATF}/atf-c/atf-common.m4 ${DESTDIR}${SHAREDIR}/aclocal + ${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \ + ${ATF}/atf-c/atf-c.m4 ${DESTDIR}${SHAREDIR}/aclocal + +.if ${MK_TESTS} != "no" +SUBDIR= tests +.endif + +.include "../common.mk" .include <bsd.lib.mk> diff --git a/lib/atf/libatf-c/Makefile.inc b/lib/atf/libatf-c/Makefile.inc new file mode 100644 index 0000000..265f86d --- /dev/null +++ b/lib/atf/libatf-c/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/lib/atf/libatf-c/tests/Makefile b/lib/atf/libatf-c/tests/Makefile new file mode 100644 index 0000000..1a091d3 --- /dev/null +++ b/lib/atf/libatf-c/tests/Makefile @@ -0,0 +1,38 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c +TESTS_SUBDIRS= detail + +ATF= ${.CURDIR:H:H:H:H}/contrib/atf +.PATH: ${ATF}/atf-c +.PATH: ${ATF}/atf-c/detail + +CFLAGS+= -I${ATF} + +# macros_test.c contains a double 'const const' which will be gone with +# the import of atf-0.18. +# TODO(jmmv): Remove this workaround once we do that update. +CFLAGS.clang+= -Wno-duplicate-decl-specifier + +FILESDIR= ${TESTSDIR} +FILES= macros_h_test.c +FILES+= unused_test.c + +.for _T in atf_c_test \ + build_test \ + check_test \ + config_test \ + error_test \ + macros_test \ + tc_test \ + tp_test \ + utils_test +ATF_TESTS_C+= ${_T} +SRCS.${_T}= ${_T}.c test_helpers.c +.endfor + +ATF_TESTS_SH= pkg_config_test + +.include <bsd.test.mk> diff --git a/lib/atf/libatf-c/tests/Makefile.inc b/lib/atf/libatf-c/tests/Makefile.inc new file mode 100644 index 0000000..265f86d --- /dev/null +++ b/lib/atf/libatf-c/tests/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/lib/atf/libatf-c/tests/detail/Makefile b/lib/atf/libatf-c/tests/detail/Makefile new file mode 100644 index 0000000..aa85aa3 --- /dev/null +++ b/lib/atf/libatf-c/tests/detail/Makefile @@ -0,0 +1,34 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c/detail + +ATF= ${.CURDIR:H:H:H:H:H}/contrib/atf +.PATH: ${ATF}/atf-c/detail + +CFLAGS+= -I${ATF} + +.for _T in dynstr_test \ + env_test \ + fs_test \ + list_test \ + map_test \ + process_test \ + sanity_test \ + text_test \ + user_test +ATF_TESTS_C+= ${_T} +SRCS.${_T}= ${_T}.c test_helpers.c +.endfor + +.for p in process_helpers version_helper +PROGS+= ${p} +SRCS.${p}= ${p}.c +MAN.${p}= # defined +BINDIR.${p}= ${TESTSDIR} +.endfor +version_helper.o: atf-version + +.include "../../../common.mk" +.include <bsd.test.mk> diff --git a/lib/atf/tests/Makefile b/lib/atf/tests/Makefile new file mode 100644 index 0000000..7bc96c9 --- /dev/null +++ b/lib/atf/tests/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf + +.PATH: ${.CURDIR:H:H:H}/tests +KYUAFILE= yes + +SUBDIR= test-programs + +.include <bsd.test.mk> diff --git a/lib/atf/tests/test-programs/Makefile b/lib/atf/tests/test-programs/Makefile new file mode 100644 index 0000000..b0c1c23 --- /dev/null +++ b/lib/atf/tests/test-programs/Makefile @@ -0,0 +1,24 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +TESTSDIR= ${TESTSBASE}/lib/atf/test-programs +KYUAFILE= yes + +ATF= ${.CURDIR:H:H:H:H}/contrib/atf +.PATH: ${ATF}/test-programs + +CFLAGS+= -I${ATF} + +ATF_TESTS_C= c_helpers + +ATF_TESTS_CXX= cpp_helpers +SRCS.cpp_helpers= cpp_helpers.cpp + +ATF_TESTS_SH= sh_helpers +.for _T in config_test expect_test meta_data_test result_test srcdir_test +ATF_TESTS_SH+= ${_T} +ATF_TESTS_SH_SRC_${_T}= common.sh ${_T}.sh +.endfor + +.include <bsd.test.mk> diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c index d9f8a2d..d2fbab3 100644 --- a/lib/csu/arm/crt1.c +++ b/lib/csu/arm/crt1.c @@ -123,7 +123,7 @@ static const struct { char desc[sizeof(MACHINE_ARCH)]; } archtag __attribute__ ((section (NOTE_SECTION), aligned(4))) __used = { .namesz = sizeof(NOTE_FREEBSD_VENDOR), - .descsz = sizeof(int32_t), + .descsz = sizeof(MACHINE_ARCH), .type = ARCH_NOTETYPE, .name = NOTE_FREEBSD_VENDOR, .desc = MACHINE_ARCH diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile index 4ec21f9..16a485a 100644 --- a/lib/libarchive/test/Makefile +++ b/lib/libarchive/test/Makefile @@ -2,7 +2,7 @@ LIBARCHIVEDIR= ${.CURDIR}/../../../contrib/libarchive -NO_MAN=yes +MAN= PROG=libarchive_test INTERNALPROG=yes # Don't install this; it's just for testing diff --git a/lib/libauditd/Makefile b/lib/libauditd/Makefile index 2487383..cee1850 100644 --- a/lib/libauditd/Makefile +++ b/lib/libauditd/Makefile @@ -19,6 +19,6 @@ CFLAGS+= -I${OPENBSMDIR} -I${LIBBSMDIR} WARNS?= 3 -NO_MAN= +MAN= .include <bsd.lib.mk> diff --git a/lib/libbsdstat/Makefile b/lib/libbsdstat/Makefile new file mode 100644 index 0000000..aef0ec2 --- /dev/null +++ b/lib/libbsdstat/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +LIB= bsdstat +SHLIB_MAJOR= 1 +PRIVATELIB= + +SRCS= bsdstat.c +INCS= bsdstat.h + +.include <bsd.lib.mk> diff --git a/lib/libbsdstat/bsdstat.c b/lib/libbsdstat/bsdstat.c new file mode 100644 index 0000000..96fba00 --- /dev/null +++ b/lib/libbsdstat/bsdstat.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + * $FreeBSD$ + */ + +#include <stdio.h> +#include <string.h> + +#include "bsdstat.h" + +static void +bsdstat_setfmt(struct bsdstat *sf, const char *fmt0) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + char fmt[4096]; + char *fp, *tok; + int i, j; + + j = 0; + strlcpy(fmt, fmt0, sizeof(fmt)); + for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { + for (i = 0; i < sf->nstats; i++) + if (strcasecmp(tok, sf->stats[i].name) == 0) + break; + if (i >= sf->nstats) { + fprintf(stderr, "%s: unknown statistic name \"%s\" " + "skipped\n", sf->name, tok); + continue; + } + if (j+3 > (int) sizeof(sf->fmts)) { + fprintf(stderr, "%s: not enough room for all stats; " + "stopped at %s\n", sf->name, tok); + break; + } + if (j != 0) + sf->fmts[j++] = ' '; + sf->fmts[j++] = FMTS_IS_STAT; + sf->fmts[j++] = i & 0xff; + sf->fmts[j++] = (i >> 8) & 0xff; + } + sf->fmts[j] = '\0'; +#undef N +} + +static void +bsdstat_collect(struct bsdstat *sf) +{ + fprintf(stderr, "%s: don't know how to collect data\n", sf->name); +} + +static void +bsdstat_update_tot(struct bsdstat *sf) +{ + fprintf(stderr, "%s: don't know how to update total data\n", sf->name); +} + +static int +bsdstat_get(struct bsdstat *sf, int s, char b[] __unused, size_t bs __unused) +{ + fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); + return 0; +} + +static void +bsdstat_print_header(struct bsdstat *sf, FILE *fd) +{ + const unsigned char *cp; + int i; + const struct fmt *f; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + fprintf(fd, "%*s", f->width, f->label); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +bsdstat_print_current(struct bsdstat *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + int i; + const struct fmt *f; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + if (sf->get_curstat(sf, i, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +bsdstat_print_total(struct bsdstat *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + const struct fmt *f; + int i; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + if (sf->get_totstat(sf, i, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +bsdstat_print_verbose(struct bsdstat *sf, FILE *fd) +{ + const struct fmt *f; + char s[32]; + int i, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (f->width > width) + width = f->width; + } + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) + fprintf(fd, "%-*s %s\n", width, s, f->desc); + } +} + +static void +bsdstat_print_fields(struct bsdstat *sf, FILE *fd) +{ + int i, w, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + w = strlen(sf->stats[i].name); + if (w > width) + width = w; + } + for (i = 0; i < sf->nstats; i++) { + const struct fmt *f = &sf->stats[i]; + if (f->width != 0) + fprintf(fd, "%-*s %s\n", width, f->name, f->desc); + } +} + +void +bsdstat_init(struct bsdstat *sf, const char *name, const struct fmt *stats, int nstats) +{ + sf->name = name; + sf->stats = stats; + sf->nstats = nstats; + sf->setfmt = bsdstat_setfmt; + sf->collect_cur = bsdstat_collect; + sf->collect_tot = bsdstat_collect; + sf->update_tot = bsdstat_update_tot; + sf->get_curstat = bsdstat_get; + sf->get_totstat = bsdstat_get; + sf->print_header = bsdstat_print_header; + sf->print_current = bsdstat_print_current; + sf->print_total = bsdstat_print_total; + sf->print_verbose = bsdstat_print_verbose; + sf->print_fields = bsdstat_print_fields; +} diff --git a/lib/libbsdstat/bsdstat.h b/lib/libbsdstat/bsdstat.h new file mode 100644 index 0000000..ef97210 --- /dev/null +++ b/lib/libbsdstat/bsdstat.h @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + * $FreeBSD$ + */ + +#ifndef _BSDSTAT_H_ +#define _BSDSTAT_H_ +/* + * Base class for managing+displaying periodically collected statistics. + */ + +/* + * Statistic definition/description. The are defined + * for stats that correspond 1-1 w/ a collected stat + * and for stats that are calculated indirectly. + */ +struct fmt { + int width; /* printed field width */ + const char* name; /* stat field name referenced by user */ + const char* label; /* printed header label */ + const char* desc; /* verbose description */ +}; + +#define BSDSTAT_DECL_METHODS(_p) \ + /* set the format of the statistics to display */ \ + void (*setfmt)(_p, const char *); \ + /* collect+store ``current statistics'' */ \ + void (*collect_cur)(_p); \ + /* collect+store ``total statistics'' */ \ + void (*collect_tot)(_p); \ + /* update ``total statistics'' if necessary from current */ \ + void (*update_tot)(_p); \ + /* format a statistic from the current stats */ \ + int (*get_curstat)(_p, int, char [], size_t); \ + /* format a statistic from the total stats */ \ + int (*get_totstat)(_p, int, char [], size_t); \ + /* print field headers terminated by a \n */ \ + void (*print_header)(_p, FILE *); \ + /* print current statistics terminated by a \n */ \ + void (*print_current)(_p, FILE *); \ + /* print total statistics terminated by a \n */ \ + void (*print_total)(_p, FILE *); \ + /* print total statistics in a verbose (1 stat/line) format */ \ + void (*print_verbose)(_p, FILE *); \ + /* print available statistics */ \ + void (*print_fields)(_p, FILE *) + +/* + * Statistics base class. This class is not usable; only + * classes derived from it are useful. + */ +struct bsdstat { + const char *name; /* statistics name, e.g. wlanstats */ + const struct fmt *stats; /* statistics in class */ + int nstats; /* number of stats */ +#define FMTS_IS_STAT 0x80 /* the following two bytes are the stat id */ + unsigned char fmts[4096]; /* private: compiled stats to display */ + + BSDSTAT_DECL_METHODS(struct bsdstat *); +}; + +extern void bsdstat_init(struct bsdstat *, const char *name, + const struct fmt *stats, int nstats); + +#define BSDSTAT_DEFINE_BOUNCE(_t) \ +static void _t##_setfmt(struct _t *wf, const char *fmt0) \ + { wf->base.setfmt(&wf->base, fmt0); } \ +static void _t##_collect_cur(struct _t *wf) \ + { wf->base.collect_cur(&wf->base); } \ +static void _t##_collect_tot(struct _t *wf) \ + { wf->base.collect_tot(&wf->base); } \ +static void _t##_update_tot(struct _t *wf) \ + { wf->base.update_tot(&wf->base); } \ +static int _t##_get_curstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_curstat(&wf->base, s, b, bs); } \ +static int _t##_get_totstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_totstat(&wf->base, s, b, bs); } \ +static void _t##_print_header(struct _t *wf, FILE *fd) \ + { wf->base.print_header(&wf->base, fd); } \ +static void _t##_print_current(struct _t *wf, FILE *fd) \ + { wf->base.print_current(&wf->base, fd); } \ +static void _t##_print_total(struct _t *wf, FILE *fd) \ + { wf->base.print_total(&wf->base, fd); } \ +static void _t##_print_verbose(struct _t *wf, FILE *fd) \ + { wf->base.print_verbose(&wf->base, fd); } \ +static void _t##_print_fields(struct _t *wf, FILE *fd) \ + { wf->base.print_fields(&wf->base, fd); } + +#define BSDSTAT_BOUNCE(_p, _t) do { \ + _p->base.setfmt = _t##_setfmt; \ + _p->base.collect_cur = _t##_collect_cur; \ + _p->base.collect_tot = _t##_collect_tot; \ + _p->base.update_tot = _t##_update_tot; \ + _p->base.get_curstat = _t##_get_curstat; \ + _p->base.get_totstat = _t##_get_totstat; \ + _p->base.print_header = _t##_print_header; \ + _p->base.print_current = _t##_print_current; \ + _p->base.print_total = _t##_print_total; \ + _p->base.print_verbose = _t##_print_verbose; \ + _p->base.print_fields = _t##_print_fields; \ +} while (0) +#endif /* _BSDSTAT_H_ */ diff --git a/lib/libc++/Makefile b/lib/libc++/Makefile index 567144a..1e7dfaf 100644 --- a/lib/libc++/Makefile +++ b/lib/libc++/Makefile @@ -25,8 +25,10 @@ SRCS+= algorithm.cpp\ memory.cpp\ mutex.cpp\ new.cpp\ + optional.cpp\ random.cpp\ regex.cpp\ + shared_mutex.cpp\ stdexcept.cpp\ string.cpp\ strstream.cpp\ @@ -61,7 +63,7 @@ CXXFLAGS+= -std=c++0x DPADD= ${LIBCXXRT} LDADD= -lcxxrt LDFLAGS+= --verbose -INCSGROUPS= STD EXT +INCSGROUPS= STD EXP EXT STD_HEADERS= __bit_reference\ __config\ @@ -140,6 +142,7 @@ STD_HEADERS= __bit_reference\ regex\ scoped_allocator\ set\ + shared_mutex\ sstream\ stack\ stdexcept\ @@ -172,6 +175,14 @@ STD+= ${LIBCXXRTDIR}/${hdr} .endfor STDDIR= ${CXXINCLUDEDIR} +EXP_HEADERS= dynarray\ + optional + +.for hdr in ${EXP_HEADERS} +EXP+= ${HDRDIR}/experimental/${hdr} +.endfor +EXPDIR= ${CXXINCLUDEDIR}/experimental + EXT_HEADERS= __hash\ hash_map\ hash_set diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 39d8202..6f88dac 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -5,11 +5,13 @@ SHLIBDIR?= /lib .include <bsd.own.mk> +LIBC_SRCTOP?= ${.CURDIR} + # Pick the current architecture directory for libc. In general, this is # named MACHINE_CPUARCH, but some ABIs are different enough to require # their own libc, so allow a directory named MACHINE_ARCH to override this. -.if exists(${.CURDIR}/${MACHINE_ARCH}) +.if exists(${LIBC_SRCTOP}/${MACHINE_ARCH}) LIBC_ARCH=${MACHINE_ARCH} .else LIBC_ARCH=${MACHINE_CPUARCH} @@ -25,8 +27,8 @@ LIB=c SHLIB_MAJOR= 7 SHLIB_LDSCRIPT=libc.ldscript WARNS?= 2 -CFLAGS+=-I${.CURDIR}/include -I${.CURDIR}/../../include -CFLAGS+=-I${.CURDIR}/${LIBC_ARCH} +CFLAGS+=-I${LIBC_SRCTOP}/include -I${LIBC_SRCTOP}/../../include +CFLAGS+=-I${LIBC_SRCTOP}/${LIBC_ARCH} .if ${MK_NLS} != "no" CFLAGS+=-DNLS .endif @@ -40,16 +42,19 @@ CFLAGS+=${CANCELPOINTS_CFLAGS} .endif # -# Only link with static libgcc.a (no libgcc_eh.a). +# Link with static libcompiler_rt.a. # -DPADD+= ${LIBGCC} +DPADD+= ${LIBCOMPILER_RT} LDFLAGS+= -nodefaultlibs -LDADD+= -lgcc +LDADD+= -lcompiler_rt .if ${MK_SSP} != "no" LDADD+= -lssp_nonshared .endif +# Extras that live in either libc.a or libc_nonshared.a +LIBC_NONSHARED_SRCS= + # Define (empty) variables so that make doesn't give substitution # errors if the included makefiles don't change these: MDSRCS= @@ -58,49 +63,50 @@ MDASM= MIASM= NOASM= -.include "${.CURDIR}/${LIBC_ARCH}/Makefile.inc" -.include "${.CURDIR}/db/Makefile.inc" -.include "${.CURDIR}/compat-43/Makefile.inc" -.include "${.CURDIR}/gdtoa/Makefile.inc" -.include "${.CURDIR}/gen/Makefile.inc" -.include "${.CURDIR}/gmon/Makefile.inc" +.include "${LIBC_SRCTOP}/${LIBC_ARCH}/Makefile.inc" +.include "${LIBC_SRCTOP}/db/Makefile.inc" +.include "${LIBC_SRCTOP}/compat-43/Makefile.inc" +.include "${LIBC_SRCTOP}/gdtoa/Makefile.inc" +.include "${LIBC_SRCTOP}/gen/Makefile.inc" +.include "${LIBC_SRCTOP}/gmon/Makefile.inc" .if ${MK_ICONV} != "no" -.include "${.CURDIR}/iconv/Makefile.inc" -.endif -.include "${.CURDIR}/inet/Makefile.inc" -.include "${.CURDIR}/isc/Makefile.inc" -.include "${.CURDIR}/locale/Makefile.inc" -.include "${.CURDIR}/nameser/Makefile.inc" -.include "${.CURDIR}/net/Makefile.inc" -.include "${.CURDIR}/nls/Makefile.inc" -.include "${.CURDIR}/posix1e/Makefile.inc" +.include "${LIBC_SRCTOP}/iconv/Makefile.inc" +.endif +.include "${LIBC_SRCTOP}/inet/Makefile.inc" +.include "${LIBC_SRCTOP}/isc/Makefile.inc" +.include "${LIBC_SRCTOP}/locale/Makefile.inc" +.include "${LIBC_SRCTOP}/nameser/Makefile.inc" +.include "${LIBC_SRCTOP}/net/Makefile.inc" +.include "${LIBC_SRCTOP}/nls/Makefile.inc" +.include "${LIBC_SRCTOP}/posix1e/Makefile.inc" .if ${LIBC_ARCH} != "amd64" && \ ${LIBC_ARCH} != "ia64" && \ ${LIBC_ARCH} != "powerpc64" && \ ${LIBC_ARCH} != "sparc64" && \ ${MACHINE_ARCH:Mmipsn32*} == "" && \ ${MACHINE_ARCH:Mmips64*} == "" -.include "${.CURDIR}/quad/Makefile.inc" -.endif -.include "${.CURDIR}/regex/Makefile.inc" -.include "${.CURDIR}/resolv/Makefile.inc" -.include "${.CURDIR}/stdio/Makefile.inc" -.include "${.CURDIR}/stdlib/Makefile.inc" -.include "${.CURDIR}/stdlib/jemalloc/Makefile.inc" -.include "${.CURDIR}/stdtime/Makefile.inc" -.include "${.CURDIR}/string/Makefile.inc" -.include "${.CURDIR}/sys/Makefile.inc" -.include "${.CURDIR}/rpc/Makefile.inc" -.include "${.CURDIR}/uuid/Makefile.inc" -.include "${.CURDIR}/xdr/Makefile.inc" -.if ${LIBC_ARCH} == "arm" || ${LIBC_ARCH} == "mips" -.include "${.CURDIR}/softfloat/Makefile.inc" +.include "${LIBC_SRCTOP}/quad/Makefile.inc" +.endif +.include "${LIBC_SRCTOP}/regex/Makefile.inc" +.include "${LIBC_SRCTOP}/resolv/Makefile.inc" +.include "${LIBC_SRCTOP}/stdio/Makefile.inc" +.include "${LIBC_SRCTOP}/stdlib/Makefile.inc" +.include "${LIBC_SRCTOP}/stdlib/jemalloc/Makefile.inc" +.include "${LIBC_SRCTOP}/stdtime/Makefile.inc" +.include "${LIBC_SRCTOP}/string/Makefile.inc" +.include "${LIBC_SRCTOP}/sys/Makefile.inc" +.include "${LIBC_SRCTOP}/rpc/Makefile.inc" +.include "${LIBC_SRCTOP}/uuid/Makefile.inc" +.include "${LIBC_SRCTOP}/xdr/Makefile.inc" +.if (${LIBC_ARCH} == "arm" && ${MACHINE_ARCH} != "armv6hf") ||\ + ${LIBC_ARCH} == "mips" +.include "${LIBC_SRCTOP}/softfloat/Makefile.inc" .endif .if ${MK_NIS} != "no" CFLAGS+= -DYP -.include "${.CURDIR}/yp/Makefile.inc" +.include "${LIBC_SRCTOP}/yp/Makefile.inc" .endif -.include "${.CURDIR}/capability/Makefile.inc" +.include "${LIBC_SRCTOP}/capability/Makefile.inc" .if ${MK_HESIOD} != "no" CFLAGS+= -DHESIOD .endif @@ -114,7 +120,9 @@ CFLAGS+= -DNS_CACHING CFLAGS+=-D_FREEFALL_CONFIG .endif -VERSION_DEF=${.CURDIR}/Versions.def +STATICOBJS+=${LIBC_NONSHARED_SRCS:S/.c$/.o/} + +VERSION_DEF=${LIBC_SRCTOP}/Versions.def SYMBOL_MAPS=${SYM_MAPS} CFLAGS+= -DSYMBOL_VERSIONING @@ -142,7 +150,7 @@ KSRCS= bcmp.c ffs.c ffsl.c fls.c flsl.c mcount.c strcat.c strchr.c \ libkern: libkern.gen libkern.${LIBC_ARCH} libkern.gen: ${KQSRCS} ${KSRCS} - cp -p ${.CURDIR}/quad/quad.h ${.ALLSRC} ${DESTDIR}/sys/libkern + cp -p ${LIBC_SRCTOP}/quad/quad.h ${.ALLSRC} ${DESTDIR}/sys/libkern libkern.${LIBC_ARCH}:: ${KMSRCS} .if defined(KMSRCS) && !empty(KMSRCS) diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def index bbd59a4..8452c7d 100644 --- a/lib/libc/Versions.def +++ b/lib/libc/Versions.def @@ -23,6 +23,11 @@ FBSD_1.2 { FBSD_1.3 { } FBSD_1.2; +# This version was first added to 11.0-current. +FBSD_1.4 { +} FBSD_1.3; + + # This is our private namespace. Any global interfaces that are # strictly for use only by other FreeBSD applications and libraries # are listed here. We use a separate namespace so we can write @@ -30,4 +35,4 @@ FBSD_1.3 { # # Please do NOT increment the version of this namespace. FBSDprivate_1.0 { -} FBSD_1.3; +} FBSD_1.4; diff --git a/lib/libc/amd64/Makefile.inc b/lib/libc/amd64/Makefile.inc index e4c0900..95fddef 100644 --- a/lib/libc/amd64/Makefile.inc +++ b/lib/libc/amd64/Makefile.inc @@ -6,4 +6,4 @@ # Long double is 80 bits GDTOASRCS+=strtorx.c MDSRCS+=machdep_ldisx.c -SYM_MAPS+=${.CURDIR}/amd64/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/amd64/Symbol.map diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h index a232383..3d9108e 100644 --- a/lib/libc/amd64/SYS.h +++ b/lib/libc/amd64/SYS.h @@ -36,20 +36,17 @@ #include <sys/syscall.h> #include <machine/asm.h> -#define RSYSCALL(x) ENTRY(__CONCAT(__sys_,x)); \ - .weak CNAME(x); \ - .set CNAME(x),CNAME(__CONCAT(__sys_,x)); \ - .weak CNAME(__CONCAT(_,x)); \ - .set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \ - mov __CONCAT($SYS_,x),%eax; KERNCALL; \ +#define RSYSCALL(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ jb HIDENAME(cerror); ret; \ - END(__CONCAT(__sys_,x)) + END(__sys_##name) -#define PSEUDO(x) ENTRY(__CONCAT(__sys_,x)); \ - .weak CNAME(__CONCAT(_,x)); \ - .set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \ - mov __CONCAT($SYS_,x),%eax; KERNCALL; \ +#define PSEUDO(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ jb HIDENAME(cerror); ret; \ - END(__CONCAT(__sys_,x)) + END(__sys_##name) -#define KERNCALL movq %rcx, %r10; syscall +#define KERNCALL movq %rcx, %r10; syscall diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S index 9035632..57079a1 100644 --- a/lib/libc/amd64/gen/_setjmp.S +++ b/lib/libc/amd64/gen/_setjmp.S @@ -63,8 +63,7 @@ ENTRY(_setjmp) ret END(_setjmp) - .weak CNAME(_longjmp) - .set CNAME(_longjmp),CNAME(___longjmp) + WEAK_REFERENCE(___longjmp, _longjmp) ENTRY(___longjmp) movq %rdi,%rdx /* Restore the mxcsr, but leave exception flags intact. */ diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S index 47772be..c26f52f 100644 --- a/lib/libc/amd64/gen/setjmp.S +++ b/lib/libc/amd64/gen/setjmp.S @@ -73,8 +73,7 @@ ENTRY(setjmp) ret END(setjmp) - .weak CNAME(longjmp) - .set CNAME(longjmp),CNAME(__longjmp) + WEAK_REFERENCE(__longjmp, longjmp) ENTRY(__longjmp) pushq %rdi pushq %rsi diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S index ef90bc6..02b154c 100644 --- a/lib/libc/amd64/gen/sigsetjmp.S +++ b/lib/libc/amd64/gen/sigsetjmp.S @@ -80,8 +80,7 @@ ENTRY(sigsetjmp) ret END(sigsetjmp) - .weak CNAME(siglongjmp) - .set CNAME(siglongjmp),CNAME(__siglongjmp) + WEAK_REFERENCE(__siglongjmp, siglongjmp) ENTRY(__siglongjmp) cmpl $0,88(%rdi) jz 2f diff --git a/lib/libc/amd64/sys/Makefile.inc b/lib/libc/amd64/sys/Makefile.inc index 51583d3..8e0d614 100644 --- a/lib/libc/amd64/sys/Makefile.inc +++ b/lib/libc/amd64/sys/Makefile.inc @@ -11,6 +11,6 @@ MDASM= vfork.S brk.S cerror.S exect.S getcontext.S pipe.S ptrace.S \ NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/amd64/sys/getcontext.S b/lib/libc/amd64/sys/getcontext.S index 1128796..b11e65c 100644 --- a/lib/libc/amd64/sys/getcontext.S +++ b/lib/libc/amd64/sys/getcontext.S @@ -34,10 +34,8 @@ __FBSDID("$FreeBSD$"); * Otherwise, the setcontext() syscall will return here and we'll * pop off the return address and go to the *setcontext* call. */ - .weak _getcontext - .set _getcontext,__sys_getcontext - .weak getcontext - .set getcontext,__sys_getcontext + WEAK_REFERENCE(__sys_getcontext, _getcontext) + WEAK_REFERENCE(__sys_getcontext, getcontext) ENTRY(__sys_getcontext) movq (%rsp),%rsi /* save getcontext return address */ mov $SYS_getcontext,%rax diff --git a/lib/libc/amd64/sys/pipe.S b/lib/libc/amd64/sys/pipe.S index 8d089db..806c9ae 100644 --- a/lib/libc/amd64/sys/pipe.S +++ b/lib/libc/amd64/sys/pipe.S @@ -38,10 +38,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" - .weak _pipe - .set _pipe,__sys_pipe - .weak pipe - .set pipe,__sys_pipe + WEAK_REFERENCE(__sys_pipe, _pipe) + WEAK_REFERENCE(__sys_pipe, pipe) ENTRY(__sys_pipe) mov $SYS_pipe,%rax KERNCALL diff --git a/lib/libc/amd64/sys/reboot.S b/lib/libc/amd64/sys/reboot.S index fd04ef4..b9ad1c6 100644 --- a/lib/libc/amd64/sys/reboot.S +++ b/lib/libc/amd64/sys/reboot.S @@ -38,10 +38,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" - .weak _reboot - .set _reboot,__sys_reboot - .weak reboot - .set reboot,__sys_reboot + WEAK_REFERENCE(__sys_reboot, _reboot) + WEAK_REFERENCE(__sys_reboot, reboot) ENTRY(__sys_reboot) mov $SYS_reboot,%rax KERNCALL diff --git a/lib/libc/amd64/sys/setlogin.S b/lib/libc/amd64/sys/setlogin.S index 73b5364..a0d127d 100644 --- a/lib/libc/amd64/sys/setlogin.S +++ b/lib/libc/amd64/sys/setlogin.S @@ -40,10 +40,8 @@ __FBSDID("$FreeBSD$"); .globl CNAME(_logname_valid) /* in _getlogin() */ - .weak _setlogin - .set _setlogin,__sys_setlogin - .weak setlogin - .set setlogin,__sys_setlogin + WEAK_REFERENCE(__sys_setlogin, _setlogin) + WEAK_REFERENCE(__sys_setlogin, setlogin) ENTRY(__sys_setlogin) mov $SYS_setlogin,%rax KERNCALL diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S index 2afba58..62dc71e 100644 --- a/lib/libc/amd64/sys/vfork.S +++ b/lib/libc/amd64/sys/vfork.S @@ -38,10 +38,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" - .weak _vfork - .set _vfork,__sys_vfork - .weak vfork - .set vfork,__sys_vfork + WEAK_REFERENCE(__sys_vfork, _vfork) + WEAK_REFERENCE(__sys_vfork, vfork) ENTRY(__sys_vfork) popq %rsi /* fetch return address (%rsi preserved) */ mov $SYS_vfork,%rax diff --git a/lib/libc/arm/Makefile.inc b/lib/libc/arm/Makefile.inc index 1ae1298..6e61dcd 100644 --- a/lib/libc/arm/Makefile.inc +++ b/lib/libc/arm/Makefile.inc @@ -7,12 +7,12 @@ SOFTFLOAT_BITS=32 # Long double is just double precision. MDSRCS+=machdep_ldisd.c -SYM_MAPS+=${.CURDIR}/arm/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol.map .if ${MK_ARM_EABI} == "no" # This contains the symbols that were removed when moving to the ARM EABI -SYM_MAPS+=${.CURDIR}/arm/Symbol_oabi.map +SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol_oabi.map .else -.include "${.CURDIR}/arm/aeabi/Makefile.inc" +.include "${LIBC_SRCTOP}/arm/aeabi/Makefile.inc" .endif diff --git a/lib/libc/arm/Symbol.map b/lib/libc/arm/Symbol.map index d652bc8..746db23 100644 --- a/lib/libc/arm/Symbol.map +++ b/lib/libc/arm/Symbol.map @@ -80,4 +80,6 @@ FBSDprivate_1.0 { __fixunsdfsi; __extendsfdf2; __truncdfsf2; + + _libc_arm_fpu_present; }; diff --git a/lib/libc/arm/aeabi/Makefile.inc b/lib/libc/arm/aeabi/Makefile.inc index 379eb23..8f9e19e 100644 --- a/lib/libc/arm/aeabi/Makefile.inc +++ b/lib/libc/arm/aeabi/Makefile.inc @@ -1,17 +1,23 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/arm/aeabi +.PATH: ${LIBC_SRCTOP}/arm/aeabi SRCS+= aeabi_atexit.c \ - aeabi_double.c \ - aeabi_float.c \ aeabi_unwind_cpp.c +.if ${MACHINE_ARCH} != "armv6hf" +SRCS+= aeabi_double.c \ + aeabi_float.c +.endif +.if ${MACHINE_ARCH:Marmv6*} +SRCS+= aeabi_vfp_double.S \ + aeabi_vfp_float.S +.endif # Add the aeabi_mem* functions. While they live in compiler-rt they call into # libc. This causes issues when other parts of libc call these functions. # We work around this by including these functions in libc but mark them as # hidden so users of libc will not pick up these versions. -.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/arm +.PATH: ${LIBC_SRCTOP}/../../contrib/compiler-rt/lib/arm SRCS+= aeabi_memcmp.S \ aeabi_memcpy.S \ @@ -26,5 +32,5 @@ CFLAGS.aeabi_memset.S= -DVISIBILITY_HIDDEN CFLAGS+= ${CFLAGS.${.IMPSRC:T}} -SYM_MAPS+=${.CURDIR}/arm/aeabi/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/arm/aeabi/Symbol.map diff --git a/lib/libc/arm/aeabi/aeabi_double.c b/lib/libc/arm/aeabi/aeabi_double.c index 5f9065c..274279d 100644 --- a/lib/libc/arm/aeabi/aeabi_double.c +++ b/lib/libc/arm/aeabi/aeabi_double.c @@ -32,70 +32,45 @@ __FBSDID("$FreeBSD$"); #include "milieu.h" #include "softfloat.h" -flag __unorddf2(float64, float64); - -int __aeabi_dcmpeq(float64 a, float64 b) -{ - return float64_eq(a, b); -} - -int __aeabi_dcmplt(float64 a, float64 b) -{ - return float64_lt(a, b); -} - -int __aeabi_dcmple(float64 a, float64 b) -{ - return float64_le(a, b); -} - -int __aeabi_dcmpge(float64 a, float64 b) -{ - return float64_le(b, a); -} - -int __aeabi_dcmpgt(float64 a, float64 b) -{ - return float64_lt(b, a); -} - -int __aeabi_dcmpun(float64 a, float64 b) -{ - return __unorddf2(a, b); -} +#include "aeabi_vfp.h" -int __aeabi_d2iz(float64 a) -{ - return float64_to_int32_round_to_zero(a); -} +extern int _libc_arm_fpu_present; -float32 __aeabi_d2f(float64 a) -{ - return float64_to_float32(a); -} - -float64 __aeabi_i2d(int a) -{ - return int32_to_float64(a); -} - -float64 __aeabi_dadd(float64 a, float64 b) -{ - return float64_add(a, b); -} - -float64 __aeabi_ddiv(float64 a, float64 b) -{ - return float64_div(a, b); -} +flag __unorddf2(float64, float64); -float64 __aeabi_dmul(float64 a, float64 b) -{ - return float64_mul(a, b); -} +/* These are written in asm and are only called from this file */ +int __aeabi_dcmpeq_vfp(float64, float64); +int __aeabi_dcmplt_vfp(float64, float64); +int __aeabi_dcmple_vfp(float64, float64); +int __aeabi_dcmpgt_vfp(float64, float64); +int __aeabi_dcmpge_vfp(float64, float64); +int __aeabi_dcmpun_vfp(float64, float64); +int __aeabi_d2iz_vfp(float64); +float32 __aeabi_d2f_vfp(float64); +float64 __aeabi_i2d_vfp(int); +float64 __aeabi_dadd_vfp(float64, float64); +float64 __aeabi_ddiv_vfp(float64, float64); +float64 __aeabi_dmul_vfp(float64, float64); +float64 __aeabi_dsub_vfp(float64, float64); -float64 __aeabi_dsub(float64 a, float64 b) -{ - return float64_sub(a, b); -} +/* + * Depending on the target these will: + * On armv6 with a vfp call the above function, or + * Call the softfloat function in the 3rd argument. + */ +int AEABI_FUNC2(dcmpeq, float64, float64_eq) +int AEABI_FUNC2(dcmplt, float64, float64_lt) +int AEABI_FUNC2(dcmple, float64, float64_le) +int AEABI_FUNC2_REV(dcmpge, float64, float64_le) +int AEABI_FUNC2_REV(dcmpgt, float64, float64_lt) +int AEABI_FUNC2(dcmpun, float64, __unorddf2) + +int AEABI_FUNC(d2iz, float64, float64_to_int32_round_to_zero) +float32 AEABI_FUNC(d2f, float64, float64_to_float32) +float64 AEABI_FUNC(i2d, int, int32_to_float64) + +float64 AEABI_FUNC2(dadd, float64, float64_add) +float64 AEABI_FUNC2(ddiv, float64, float64_div) +float64 AEABI_FUNC2(dmul, float64, float64_mul) +float64 AEABI_FUNC2(dsub, float64, float64_sub) diff --git a/lib/libc/arm/aeabi/aeabi_float.c b/lib/libc/arm/aeabi/aeabi_float.c index 97751ad..be7a6d6 100644 --- a/lib/libc/arm/aeabi/aeabi_float.c +++ b/lib/libc/arm/aeabi/aeabi_float.c @@ -32,70 +32,45 @@ __FBSDID("$FreeBSD$"); #include "milieu.h" #include "softfloat.h" -flag __unordsf2(float32, float32); - -int __aeabi_fcmpeq(float32 a, float32 b) -{ - return float32_eq(a, b); -} - -int __aeabi_fcmplt(float32 a, float32 b) -{ - return float32_lt(a, b); -} - -int __aeabi_fcmple(float32 a, float32 b) -{ - return float32_le(a, b); -} - -int __aeabi_fcmpge(float32 a, float32 b) -{ - return float32_le(b, a); -} - -int __aeabi_fcmpgt(float32 a, float32 b) -{ - return float32_lt(b, a); -} - -int __aeabi_fcmpun(float32 a, float32 b) -{ - return __unordsf2(a, b); -} +#include "aeabi_vfp.h" -int __aeabi_f2iz(float32 a) -{ - return float32_to_int32_round_to_zero(a); -} +extern int _libc_arm_fpu_present; -float32 __aeabi_f2d(float32 a) -{ - return float32_to_float64(a); -} - -float32 __aeabi_i2f(int a) -{ - return int32_to_float32(a); -} - -float32 __aeabi_fadd(float32 a, float32 b) -{ - return float32_add(a, b); -} - -float32 __aeabi_fdiv(float32 a, float32 b) -{ - return float32_div(a, b); -} +flag __unordsf2(float32, float32); -float32 __aeabi_fmul(float32 a, float32 b) -{ - return float32_mul(a, b); -} +/* These are written in asm and are only called from this file */ +int __aeabi_fcmpeq_vfp(float32, float32); +int __aeabi_fcmplt_vfp(float32, float32); +int __aeabi_fcmple_vfp(float32, float32); +int __aeabi_fcmpgt_vfp(float32, float32); +int __aeabi_fcmpge_vfp(float32, float32); +int __aeabi_fcmpun_vfp(float32, float32); +int __aeabi_f2iz_vfp(float32); +float64 __aeabi_f2d_vfp(float32); +float32 __aeabi_i2f_vfp(int); +float32 __aeabi_fadd_vfp(float32, float32); +float32 __aeabi_fdiv_vfp(float32, float32); +float32 __aeabi_fmul_vfp(float32, float32); +float32 __aeabi_fsub_vfp(float32, float32); -float32 __aeabi_fsub(float32 a, float32 b) -{ - return float32_sub(a, b); -} +/* + * Depending on the target these will: + * On armv6 with a vfp call the above function, or + * Call the softfloat function in the 3rd argument. + */ +int AEABI_FUNC2(fcmpeq, float32, float32_eq) +int AEABI_FUNC2(fcmplt, float32, float32_lt) +int AEABI_FUNC2(fcmple, float32, float32_le) +int AEABI_FUNC2_REV(fcmpge, float32, float32_le) +int AEABI_FUNC2_REV(fcmpgt, float32, float32_lt) +int AEABI_FUNC2(fcmpun, float32, __unordsf2) + +int AEABI_FUNC(f2iz, float32, float32_to_int32_round_to_zero) +float64 AEABI_FUNC(f2d, float32, float32_to_float64) +float32 AEABI_FUNC(i2f, int, int32_to_float32) + +float32 AEABI_FUNC2(fadd, float32, float32_add) +float32 AEABI_FUNC2(fdiv, float32, float32_div) +float32 AEABI_FUNC2(fmul, float32, float32_mul) +float32 AEABI_FUNC2(fsub, float32, float32_sub) diff --git a/lib/libc/arm/aeabi/aeabi_vfp.h b/lib/libc/arm/aeabi/aeabi_vfp.h new file mode 100644 index 0000000..76c2ff0 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef AEABI_VFP_H +#define AEABI_VFP_H + +/* + * ASM helper macros. These allow the functions to be changed depending on + * the endian-ness we are building for. + */ + +/* Allow the name of the function to be changed depending on the ABI */ +#ifndef __ARM_PCS_VFP +#define AEABI_ENTRY(x) ENTRY(__aeabi_ ## x ## _vfp) +#define AEABI_END(x) END(__aeabi_ ## x ## _vfp) +#else +#define AEABI_ENTRY(x) ENTRY(__aeabi_ ## x) +#define AEABI_END(x) END(__aeabi_ ## x) +#endif + +/* + * These should be used when a function either takes, or returns a floating + * point falue. They will load the data from an ARM to a VFP register(s), + * or from a VFP to an ARM register + */ +#ifdef __ARMEB__ +#define LOAD_DREG(vreg, reg0, reg1) vmov vreg, reg1, reg0 +#define UNLOAD_DREG(reg0, reg1, vreg) vmov reg1, reg0, vreg +#else +#define LOAD_DREG(vreg, reg0, reg1) vmov vreg, reg0, reg1 +#define UNLOAD_DREG(reg0, reg1, vreg) vmov reg0, reg1, vreg +#endif + +#define LOAD_SREGS(vreg0, vreg1, reg0, reg1) vmov vreg0, vreg1, reg0, reg1 +#define LOAD_SREG(vreg, reg) vmov vreg, reg +#define UNLOAD_SREG(reg, vreg) vmov reg, vreg + +/* + * C Helper macros + */ + +#if defined(__FreeBSD_ARCH_armv6__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 6) +/* + * Generate a function that will either call into the VFP implementation, + * or the soft float version for a given __aeabi_* helper. The function + * will take a single argument of the type given by in_type. + */ +#define AEABI_FUNC(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a); \ + else \ + return soft_func (a); \ +} + +/* As above, but takes two arguments of the same type */ +#define AEABI_FUNC2(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a, b); \ + else \ + return soft_func (a, b); \ +} + +/* As above, but with the soft float arguments reversed */ +#define AEABI_FUNC2_REV(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a, b); \ + else \ + return soft_func (b, a); \ +} +#else +/* + * Helper macros for when we are only able to use the softfloat + * version of these functions, i.e. on arm before armv6. + */ +#define AEABI_FUNC(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a) \ +{ \ + return soft_func (a); \ +} + +/* As above, but takes two arguments of the same type */ +#define AEABI_FUNC2(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + return soft_func (a, b); \ +} + +/* As above, but with the soft float arguments reversed */ +#define AEABI_FUNC2_REV(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + return soft_func (b, a); \ +} +#endif + +#endif + diff --git a/lib/libc/arm/aeabi/aeabi_vfp_double.S b/lib/libc/arm/aeabi/aeabi_vfp_double.S new file mode 100644 index 0000000..842412b --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp_double.S @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2013 Andrew Turner + * 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. + * + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +#include "aeabi_vfp.h" + +.fpu vfp +.syntax unified + +/* int __aeabi_dcmpeq(double, double) */ +AEABI_ENTRY(dcmpeq) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movne r0, #0 + moveq r0, #1 + RET +AEABI_END(dcmpeq) + +/* int __aeabi_dcmplt(double, double) */ +AEABI_ENTRY(dcmplt) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movcs r0, #0 + movlt r0, #1 + RET +AEABI_END(dcmplt) + +/* int __aeabi_dcmple(double, double) */ +AEABI_ENTRY(dcmple) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movhi r0, #0 + movls r0, #1 + RET +AEABI_END(dcmple) + +/* int __aeabi_dcmpge(double, double) */ +AEABI_ENTRY(dcmpge) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movlt r0, #0 + movge r0, #1 + RET +AEABI_END(dcmpge) + +/* int __aeabi_dcmpgt(double, double) */ +AEABI_ENTRY(dcmpgt) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movle r0, #0 + movgt r0, #1 + RET +AEABI_END(dcmpgt) + +/* int __aeabi_dcmpun(double, double) */ +AEABI_ENTRY(dcmpun) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + movvc r0, #0 + movvs r0, #1 + RET +AEABI_END(dcmpun) + +/* int __aeabi_d2iz(double) */ +AEABI_ENTRY(d2iz) + LOAD_DREG(d0, r0, r1) +#if 0 + /* + * This should be the correct instruction, but binutils incorrectly + * encodes it as the version that used FPSCR to determine the rounding. + * When binutils is fixed we can use this again. + */ + vcvt.s32.f64 s0, d0 +#else + ftosizd s0, d0 +#endif + vmov r0, s0 + RET +AEABI_END(d2iz) + +/* float __aeabi_d2f(double) */ +AEABI_ENTRY(d2f) + LOAD_DREG(d0, r0, r1) + vcvt.f32.f64 s0, d0 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(d2f) + +/* double __aeabi_i2d(int) */ +AEABI_ENTRY(i2d) + vmov s0, r0 + vcvt.f64.s32 d0, s0 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(i2d) + +/* double __aeabi_dadd(double, double) */ +AEABI_ENTRY(dadd) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vadd.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dadd) + +/* double __aeabi_ddiv(double, double) */ +AEABI_ENTRY(ddiv) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vdiv.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(ddiv) + +/* double __aeabi_dmul(double, double) */ +AEABI_ENTRY(dmul) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vmul.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dmul) + +/* double __aeabi_dsub(double, double) */ +AEABI_ENTRY(dsub) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vsub.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dsub) + diff --git a/lib/libc/arm/aeabi/aeabi_vfp_float.S b/lib/libc/arm/aeabi/aeabi_vfp_float.S new file mode 100644 index 0000000..d81b2b2 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp_float.S @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2013 Andrew Turner + * 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. + * + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +#include "aeabi_vfp.h" + +.fpu vfp +.syntax unified + +/* int __aeabi_fcmpeq(float, float) */ +AEABI_ENTRY(fcmpeq) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movne r0, #0 + moveq r0, #1 + RET +AEABI_END(fcmpeq) + +/* int __aeabi_fcmplt(float, float) */ +AEABI_ENTRY(fcmplt) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movcs r0, #0 + movlt r0, #1 + RET +AEABI_END(fcmplt) + +/* int __aeabi_fcmple(float, float) */ +AEABI_ENTRY(fcmple) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movhi r0, #0 + movls r0, #1 + RET +AEABI_END(fcmple) + +/* int __aeabi_fcmpge(float, float) */ +AEABI_ENTRY(fcmpge) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movlt r0, #0 + movge r0, #1 + RET +AEABI_END(fcmpge) + +/* int __aeabi_fcmpgt(float, float) */ +AEABI_ENTRY(fcmpgt) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movle r0, #0 + movgt r0, #1 + RET +AEABI_END(fcmpgt) + +/* int __aeabi_fcmpun(float, float) */ +AEABI_ENTRY(fcmpun) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + movvc r0, #0 + movvs r0, #1 + RET +AEABI_END(fcmpun) + +/* int __aeabi_f2iz(float) */ +AEABI_ENTRY(f2iz) + LOAD_SREG(s0, r0) +#if 0 + /* + * This should be the correct instruction, but binutils incorrectly + * encodes it as the version that used FPSCR to determine the rounding. + * When binutils is fixed we can use this again. + */ + vcvt.s32.f32 s0, s0 +#else + ftosizs s0, s0 +#endif + vmov r0, s0 + RET +AEABI_END(f2iz) + +/* double __aeabi_f2d(float) */ +AEABI_ENTRY(f2d) + LOAD_SREG(s0, r0) + vcvt.f64.f32 d0, s0 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(f2d) + +/* float __aeabi_i2f(int) */ +AEABI_ENTRY(i2f) + vmov s0, r0 + vcvt.f32.s32 s0, s0 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(i2f) + +/* float __aeabi_fadd(float, float) */ +AEABI_ENTRY(fadd) + LOAD_SREGS(s0, s1, r0, r1) + vadd.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fadd) + +/* float __aeabi_fmul(float, float) */ +AEABI_ENTRY(fdiv) + LOAD_SREGS(s0, s1, r0, r1) + vdiv.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fdiv) + +/* float __aeabi_fmul(float, float) */ +AEABI_ENTRY(fmul) + LOAD_SREGS(s0, s1, r0, r1) + vmul.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fmul) + +/* float __aeabi_fsub(float, float) */ +AEABI_ENTRY(fsub) + LOAD_SREGS(s0, s1, r0, r1) + vsub.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fsub) + diff --git a/lib/libc/arm/gen/Makefile.inc b/lib/libc/arm/gen/Makefile.inc index cfc8a46..5fd52c2 100644 --- a/lib/libc/arm/gen/Makefile.inc +++ b/lib/libc/arm/gen/Makefile.inc @@ -9,3 +9,8 @@ SRCS+= _ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.c \ .if ${MK_ARM_EABI} == "no" SRCS+= divsi3.S .endif + +.if ${MACHINE_ARCH} == "armv6hf" +SRCS+= fpgetmask_vfp.c fpgetround_vfp.c fpgetsticky_vfp.c fpsetmask_vfp.c \ + fpsetround_vfp.c fpsetsticky_vfp.c +.endif diff --git a/lib/libc/arm/gen/flt_rounds.c b/lib/libc/arm/gen/flt_rounds.c index 81ab08b..86509d2 100644 --- a/lib/libc/arm/gen/flt_rounds.c +++ b/lib/libc/arm/gen/flt_rounds.c @@ -30,20 +30,32 @@ __FBSDID("$FreeBSD$"); #include <fenv.h> #include <float.h> +#ifndef __ARM_PCS_VFP #include "softfloat-for-gcc.h" #include "milieu.h" #include "softfloat.h" +#endif int __flt_rounds(void) { + int mode; -#ifndef ARM_HARD_FLOAT +#ifndef __ARM_PCS_VFP /* * Translate our rounding modes to the unnamed * manifest constants required by C99 et. al. */ - switch (__softfloat_float_rounding_mode) { + mode = __softfloat_float_rounding_mode; +#else /* __ARM_PCS_VFP */ + /* + * Read the floating-point status and control register + */ + __asm __volatile("vmrs %0, fpscr" : "=&r"(mode)); + mode &= _ROUND_MASK; +#endif /* __ARM_PCS_VFP */ + + switch (mode) { case FE_TOWARDZERO: return (0); case FE_TONEAREST: @@ -54,12 +66,4 @@ __flt_rounds(void) return (3); } return (-1); -#else /* ARM_HARD_FLOAT */ - /* - * Apparently, the rounding mode is specified as part of the - * instruction format on ARM, so the dynamic rounding mode is - * indeterminate. Some FPUs may differ. - */ - return (-1); -#endif /* ARM_HARD_FLOAT */ } diff --git a/lib/libc/arm/gen/fpgetmask_vfp.c b/lib/libc/arm/gen/fpgetmask_vfp.c new file mode 100644 index 0000000..7c4d76f --- /dev/null +++ b/lib/libc/arm/gen/fpgetmask_vfp.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpgetmask,_fpgetmask) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpgetmask(void) +{ + fp_except mask; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(mask)); + + return ((mask >> 8) & FP_X_MASK); +} + diff --git a/lib/libelf/elf_kind.c b/lib/libc/arm/gen/fpgetround_vfp.c index 88888da..ed94388 100644 --- a/lib/libelf/elf_kind.c +++ b/lib/libc/arm/gen/fpgetround_vfp.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2006 Joseph Koshy +/* + * Copyright (C) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,22 +22,26 @@ * 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. + * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <libelf.h> +#include <sys/types.h> +#include <ieeefp.h> -#include "_libelf.h" +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif -Elf_Kind -elf_kind(Elf *e) +fp_rnd_t +fpgetround(void) { - if (e == NULL) - return (ELF_K_NONE); - if (e->e_kind == ELF_K_AR || - e->e_kind == ELF_K_ELF) - return (e->e_kind); - return (ELF_K_NONE); + uint32_t fpscr; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(fpscr)); + + return ((fpscr >> 22) & 3); } + diff --git a/lib/libelf/elf_getbase.c b/lib/libc/arm/gen/fpgetsticky_vfp.c index 863c858..f1e0ba5 100644 --- a/lib/libelf/elf_getbase.c +++ b/lib/libc/arm/gen/fpgetsticky_vfp.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2006 Joseph Koshy +/* + * Copyright (C) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,26 +22,28 @@ * 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. + * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <libelf.h> +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif -#include "_libelf.h" +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) -off_t -elf_getbase(Elf *e) +fp_except +fpgetsticky(void) { - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return ((off_t) -1); - } + fp_except old; - if (e->e_parent == NULL) - return ((off_t) 0); + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); - return ((off_t) ((uintptr_t) e->e_rawfile - - (uintptr_t) e->e_parent->e_rawfile)); + return (old & FP_X_MASK); } + diff --git a/lib/libelf/elf_errno.c b/lib/libc/arm/gen/fpsetmask_vfp.c index 44feae3..061c033 100644 --- a/lib/libelf/elf_errno.c +++ b/lib/libc/arm/gen/fpsetmask_vfp.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2006 Joseph Koshy +/* + * Copyright (C) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,37 +22,31 @@ * 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. + * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <libelf.h> - -#include "_libelf.h" - -int -elf_errno(void) -{ - int old; +#include <sys/types.h> +#include <ieeefp.h> - old = LIBELF_PRIVATE(error); - LIBELF_PRIVATE(error) = 0; - return (old & LIBELF_ELF_ERROR_MASK); -} +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif -#if defined(LIBELF_TEST_HOOKS) +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) -int -_libelf_get_max_error(void) +fp_except_t +fpsetmask(fp_except_t mask) { - return ELF_E_NUM; -} + fp_except old, new; -void -_libelf_set_error(int error) -{ - LIBELF_PRIVATE(error) = error; + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + mask = (mask & FP_X_MASK) << 8; + new = (old & ~(FP_X_MASK << 8)) | mask; + __asm __volatile("vmsr fpscr, %0" : : "r"(old)); + + return ((old >> 8) & FP_X_MASK); } -#endif /* LIBELF_TEST_HOOKS */ diff --git a/lib/libelf/elf_rawfile.c b/lib/libc/arm/gen/fpsetround_vfp.c index 5143ad7..dc65a2e 100644 --- a/lib/libelf/elf_rawfile.c +++ b/lib/libc/arm/gen/fpsetround_vfp.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2006 Joseph Koshy +/* + * Copyright (C) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,31 +22,29 @@ * 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. + * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <libelf.h> +#include <sys/types.h> +#include <ieeefp.h> -#include "_libelf.h" +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif -char * -elf_rawfile(Elf *e, size_t *sz) +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) { - char *ptr; - size_t size; - - size = e ? e->e_rawsize : 0; - ptr = NULL; + uint32_t old, new; - if (e == NULL) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) - LIBELF_SET_ERROR(SEQUENCE, 0); + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(3 << 22); + new |= rnd_dir << 22; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); - if (sz) - *sz = size; - - return (ptr); + return ((old >> 22) & 3); } + diff --git a/lib/libelf/elf_hash.c b/lib/libc/arm/gen/fpsetsticky_vfp.c index 6091450..ddc1593 100644 --- a/lib/libelf/elf_hash.c +++ b/lib/libc/arm/gen/fpsetsticky_vfp.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 2006 Joseph Koshy +/* + * Copyright (C) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,33 +22,31 @@ * 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. + * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <libelf.h> +#include <sys/types.h> +#include <ieeefp.h> -/* - * This elf_hash function is defined by the System V ABI. It must be - * kept compatible with "src/libexec/rtld-elf/rtld.c". - */ +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif -unsigned long -elf_hash(const char *name) -{ - unsigned long h, t; - const unsigned char *s; +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) - s = (const unsigned char *) name; - h = t = 0; +fp_except +fpsetsticky(fp_except except) +{ + fp_except old, new; - for (; *s != '\0'; h = h & ~t) { - h = (h << 4) + *s++; - t = h & 0xF0000000UL; - if (t) - h ^= t >> 24; - } + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(FP_X_MASK); + new &= ~except; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); - return (h); + return (old & except); } + diff --git a/lib/libc/arm/sys/Makefile.inc b/lib/libc/arm/sys/Makefile.inc index fd251c8..069aad3 100644 --- a/lib/libc/arm/sys/Makefile.inc +++ b/lib/libc/arm/sys/Makefile.inc @@ -8,6 +8,6 @@ MDASM= Ovfork.S brk.S cerror.S pipe.S ptrace.S sbrk.S shmat.S sigreturn.S syscal NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o PSEUDO= _exit.o _getlogin.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/capability/Makefile.inc b/lib/libc/capability/Makefile.inc index 934fc8b..d4b6562 100644 --- a/lib/libc/capability/Makefile.inc +++ b/lib/libc/capability/Makefile.inc @@ -1,19 +1,18 @@ # $FreeBSD$ # capability sources -.PATH: ${.CURDIR}/../../sys/kern +.PATH: ${LIBC_SRCTOP}/../../sys/kern ${LIBC_SRCTOP}/capability SRCS+= subr_capability.c -SYM_MAPS+= ${.CURDIR}/capability/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/capability/Symbol.map -#MAN+= cap_rights_init.3 - -#MLINKS+=cap_rights_init.3 cap_rights_set.3 -#MLINKS+=cap_rights_init.3 cap_rights_clear.3 -#MLINKS+=cap_rights_init.3 cap_rights_is_set.3 -#MLINKS+=cap_rights_init.3 cap_rights_is_valid.3 -#MLINKS+=cap_rights_init.3 cap_rights_merge.3 -#MLINKS+=cap_rights_init.3 cap_rights_remove.3 -#MLINKS+=cap_rights_init.3 cap_rights_contains.3 +MAN+= cap_rights_init.3 +MLINKS+=cap_rights_init.3 cap_rights_set.3 +MLINKS+=cap_rights_init.3 cap_rights_clear.3 +MLINKS+=cap_rights_init.3 cap_rights_is_set.3 +MLINKS+=cap_rights_init.3 cap_rights_is_valid.3 +MLINKS+=cap_rights_init.3 cap_rights_merge.3 +MLINKS+=cap_rights_init.3 cap_rights_remove.3 +MLINKS+=cap_rights_init.3 cap_rights_contains.3 diff --git a/lib/libc/capability/cap_rights_init.3 b/lib/libc/capability/cap_rights_init.3 new file mode 100644 index 0000000..464184e --- /dev/null +++ b/lib/libc/capability/cap_rights_init.3 @@ -0,0 +1,241 @@ +.\" +.\" Copyright (c) 2013 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 27, 2014 +.Dt CAP_RIGHTS_INIT 3 +.Os +.Sh NAME +.Nm cap_rights_init , +.Nm cap_rights_set , +.Nm cap_rights_clear , +.Nm cap_rights_is_set , +.Nm cap_rights_is_valid , +.Nm cap_rights_merge , +.Nm cap_rights_remove , +.Nm cap_rights_contains +.Nd manage cap_rights_t structure +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/capsicum.h +.Ft cap_rights_t * +.Fn cap_rights_init "cap_rights_t *rights" "..." +.Ft cap_rights_t * +.Fn cap_rights_set "cap_rights_t *rights" "..." +.Ft cap_rights_t * +.Fn cap_rights_clear "cap_rights_t *rights" "..." +.Ft bool +.Fn cap_rights_is_set "const cap_rights_t *rights" "..." +.Ft bool +.Fn cap_rights_is_valid "const cap_rights_t *rights" +.Ft cap_rights_t * +.Fn cap_rights_merge "cap_rights_t *dst" "const cap_rights_t *src" +.Ft cap_rights_t * +.Fn cap_rights_remove "cap_rights_t *dst" "const cap_rights_t *src" +.Ft bool +.Fn cap_rights_contains "const cap_rights_t *big" "const cap_rights_t *little" +.Sh DESCRIPTION +The functions documented here allow to manage the +.Vt cap_rights_t +structure. +.Pp +Capability rights should be separated with comma when passed to the +.Fn cap_rights_init , +.Fn cap_rights_set , +.Fn cap_rights_clear +and +.Fn cap_rights_is_set +functions. +For example: +.Bd -literal +cap_rights_set(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT, CAP_SEEK); +.Ed +.Pp +The complete list of the capability rights can be found in the +.Xr rights 4 +manual page. +.Pp +The +.Fn cap_rights_init +function initialize provided +.Vt cap_rights_t +structure. +Only properly initialized structure can be passed to the remaining functions. +For convenience the structure can be filled with capability rights instead of +calling the +.Fn cap_rights_set +function later. +For even more convenience pointer to the given structure is returned, so it can +be directly passed to +.Xr cap_rights_limit 2 : +.Bd -literal +cap_rights_t rights; + +if (cap_rights_limit(fd, cap_rights_init(&rights, CAP_READ, CAP_WRITE)) < 0) + err(1, "Unable to limit capability rights"); +.Ed +.Pp +The +.Fn cap_rights_set +function adds the given capability rights to the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_clear +function removes the given capability rights from the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_is_set +function checks if all the given capability rights are set for the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_is_valid +function verifies if the given +.Vt cap_rights_t +structure is valid. +.Pp +The +.Fn cap_rights_merge +function merges all capability rights present in the +.Fa src +structure into the +.Fa dst +structure. +.Pp +The +.Fn cap_rights_remove +function removes all capability rights present in the +.Fa src +structure from the +.Fa dst +structure. +.Pp +The +.Fn cap_rights_contains +function checks if the +.Fa big +structure contains all capability rights present in the +.Fa little +structure. +.Sh RETURN VALUES +The functions never fail. +In case an invalid capability right or an invalid +.Vt cap_rights_t +structure is given as an argument, the program will be aborted. +.Pp +The +.Fn cap_rights_init , +.Fn cap_rights_set +and +.Fn cap_rights_clear +functions return pointer to the +.Vt cap_rights_t +structure given in the +.Fa rights +argument. +.Pp +The +.Fn cap_rights_merge +and +.Fn cap_rights_remove +functions return pointer to the +.Vt cap_rights_t +structure given in the +.Fa dst +argument. +.Pp +The +.Fn cap_rights_is_set +returns +.Va true +if all the given capability rights are set in the +.Fa rights +argument. +.Pp +The +.Fn cap_rights_is_valid +function performs various checks to see if the given +.Vt cap_rights_t +structure is valid and returns +.Va true +if it is. +.Pp +The +.Fn cap_rights_contains +function returns +.Va true +if all capability rights set in the +.Fa little +structure are also present in the +.Fa big +structure. +.Sh EXAMPLES +The following example demonstrates how to prepare a +.Vt cap_rights_t +structure to be passed to the +.Xr cap_rights_limit 2 +system call. +.Bd -literal +cap_rights_t rights; +int fd; + +fd = open("/tmp/foo", O_RDWR); +if (fd < 0) + err(1, "open() failed"); + +cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + +if (allow_write_and_seek) + cap_rights_set(&rights, CAP_WRITE, CAP_SEEK); + +if (dont_allow_seek) + cap_rights_clear(&rights, CAP_SEEK); + +if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit() failed"); +.Ed +.Sh SEE ALSO +.Xr cap_rights_limit 2 , +.Xr open 2 , +.Xr capsicum 4 , +.Xr rights 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh AUTHORS +This family of functions was created by +.An Pawel Jakub Dawidek Aq pawel@dawidek.net +under sponsorship from the FreeBSD Foundation. diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc index 867a9d9..597a0f8 100644 --- a/lib/libc/compat-43/Makefile.inc +++ b/lib/libc/compat-43/Makefile.inc @@ -2,12 +2,12 @@ # $FreeBSD$ # compat-43 sources -.PATH: ${.CURDIR}/${LIBC_ARCH}/compat-43 ${.CURDIR}/compat-43 +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/compat-43 ${LIBC_SRCTOP}/compat-43 SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \ setrgid.c setruid.c sigcompat.c -SYM_MAPS+=${.CURDIR}/compat-43/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/compat-43/Symbol.map MAN+= creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2 MAN+= gethostid.3 setruid.3 diff --git a/lib/libc/db/Makefile.inc b/lib/libc/db/Makefile.inc index bbfb7e7..a8905ef 100644 --- a/lib/libc/db/Makefile.inc +++ b/lib/libc/db/Makefile.inc @@ -3,11 +3,11 @@ # CFLAGS+=-D__DBINTERFACE_PRIVATE -.include "${.CURDIR}/db/btree/Makefile.inc" -.include "${.CURDIR}/db/db/Makefile.inc" -.include "${.CURDIR}/db/hash/Makefile.inc" -.include "${.CURDIR}/db/man/Makefile.inc" -.include "${.CURDIR}/db/mpool/Makefile.inc" -.include "${.CURDIR}/db/recno/Makefile.inc" +.include "${LIBC_SRCTOP}/db/btree/Makefile.inc" +.include "${LIBC_SRCTOP}/db/db/Makefile.inc" +.include "${LIBC_SRCTOP}/db/hash/Makefile.inc" +.include "${LIBC_SRCTOP}/db/man/Makefile.inc" +.include "${LIBC_SRCTOP}/db/mpool/Makefile.inc" +.include "${LIBC_SRCTOP}/db/recno/Makefile.inc" -SYM_MAPS+=${.CURDIR}/db/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/db/Symbol.map diff --git a/lib/libc/db/btree/Makefile.inc b/lib/libc/db/btree/Makefile.inc index 76c2238..b630573 100644 --- a/lib/libc/db/btree/Makefile.inc +++ b/lib/libc/db/btree/Makefile.inc @@ -1,7 +1,7 @@ # from @(#)Makefile.inc 8.2 (Berkeley) 7/14/94 # $FreeBSD$ -.PATH: ${.CURDIR}/db/btree +.PATH: ${LIBC_SRCTOP}/db/btree SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \ bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \ diff --git a/lib/libc/db/btree/bt_put.c b/lib/libc/db/btree/bt_put.c index e4016c0..d4bc3aa 100644 --- a/lib/libc/db/btree/bt_put.c +++ b/lib/libc/db/btree/bt_put.c @@ -55,7 +55,7 @@ static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *); * dbp: pointer to access method * key: key * data: data - * flag: R_NOOVERWRITE + * flag: R_NOOVERWRITE, R_SETCURSOR, R_CURSOR * * Returns: * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the @@ -91,6 +91,7 @@ __bt_put(const DB *dbp, DBT *key, const DBT *data, u_int flags) switch (flags) { case 0: case R_NOOVERWRITE: + case R_SETCURSOR: break; case R_CURSOR: /* diff --git a/lib/libc/db/db/Makefile.inc b/lib/libc/db/db/Makefile.inc index 2bbac4e..8dcf9fe 100644 --- a/lib/libc/db/db/Makefile.inc +++ b/lib/libc/db/db/Makefile.inc @@ -1,6 +1,6 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/db/db +.PATH: ${LIBC_SRCTOP}/db/db SRCS+= db.c diff --git a/lib/libc/db/hash/Makefile.inc b/lib/libc/db/hash/Makefile.inc index 2ecb817..e1be7a5 100644 --- a/lib/libc/db/hash/Makefile.inc +++ b/lib/libc/db/hash/Makefile.inc @@ -1,7 +1,7 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/db/hash +.PATH: ${LIBC_SRCTOP}/db/hash SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ hash_page.c ndbm.c diff --git a/lib/libc/db/man/Makefile.inc b/lib/libc/db/man/Makefile.inc index 349b029..7c2db8b 100644 --- a/lib/libc/db/man/Makefile.inc +++ b/lib/libc/db/man/Makefile.inc @@ -1,7 +1,7 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/db/man +.PATH: ${LIBC_SRCTOP}/db/man MAN+= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 recno.3 diff --git a/lib/libc/db/mpool/Makefile.inc b/lib/libc/db/mpool/Makefile.inc index 832e54d..bab7e6d 100644 --- a/lib/libc/db/mpool/Makefile.inc +++ b/lib/libc/db/mpool/Makefile.inc @@ -1,6 +1,6 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/db/mpool +.PATH: ${LIBC_SRCTOP}/db/mpool SRCS+= mpool.c mpool-compat.c diff --git a/lib/libc/db/recno/Makefile.inc b/lib/libc/db/recno/Makefile.inc index 6e08e3f..744109f 100644 --- a/lib/libc/db/recno/Makefile.inc +++ b/lib/libc/db/recno/Makefile.inc @@ -1,7 +1,7 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/db/recno +.PATH: ${LIBC_SRCTOP}/db/recno SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \ rec_seq.c rec_utils.c diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc index 0d6832f..c46f898 100644 --- a/lib/libc/gdtoa/Makefile.inc +++ b/lib/libc/gdtoa/Makefile.inc @@ -1,20 +1,20 @@ # $FreeBSD$ # netlib gdtoa sources -.PATH: ${.CURDIR}/gdtoa +.PATH: ${LIBC_SRCTOP}/gdtoa MISRCS+=_hdtoa.c _hldtoa.c _ldtoa.c glue.c GDTOASRCS+=dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c \ hd_init.c hexnan.c misc.c smisc.c \ strtod.c strtodg.c strtof.c strtord.c sum.c ulp.c -SYM_MAPS+=${.CURDIR}/gdtoa/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/gdtoa/Symbol.map -CFLAGS+=-I${.CURDIR}/../../contrib/gdtoa +CFLAGS+=-I${LIBC_SRCTOP}/../../contrib/gdtoa .for src in ${GDTOASRCS} MISRCS+=gdtoa_${src} CLEANFILES+=gdtoa_${src} gdtoa_${src}: - ln -sf ${.CURDIR}/../../contrib/gdtoa/${src} ${.TARGET} + ln -sf ${LIBC_SRCTOP}/../../contrib/gdtoa/${src} ${.TARGET} .endfor diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index a88150c..f64caf0 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # machine-independent gen sources -.PATH: ${.CURDIR}/${LIBC_ARCH}/gen ${.CURDIR}/gen +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/gen ${LIBC_SRCTOP}/gen SRCS+= __getosreldate.c \ __xuname.c \ @@ -145,11 +145,11 @@ SRCS+= __getosreldate.c \ waitid.c \ wordexp.c -.PATH: ${.CURDIR}/../../contrib/libc-pwcache +.PATH: ${LIBC_SRCTOP}/../../contrib/libc-pwcache SRCS+= pwcache.c pwcache.h -.PATH: ${.CURDIR}/../../contrib/libc-vis -CFLAGS+= -I${.CURDIR}/../../contrib/libc-vis +.PATH: ${LIBC_SRCTOP}/../../contrib/libc-vis +CFLAGS+= -I${LIBC_SRCTOP}/../../contrib/libc-vis SRCS+= unvis.c vis.c MISRCS+=modf.c @@ -159,17 +159,18 @@ CANCELPOINTS_SRCS=sem.c sem_new.c SRCS+=cancelpoints_${src} CLEANFILES+=cancelpoints_${src} cancelpoints_${src}: - ln -sf ${.CURDIR}/gen/${src} ${.TARGET} + ln -sf ${LIBC_SRCTOP}/gen/${src} ${.TARGET} .endfor -SYM_MAPS+=${.CURDIR}/gen/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/gen/Symbol.map # machine-dependent gen sources -.sinclude "${.CURDIR}/${LIBC_ARCH}/gen/Makefile.inc" +.sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/gen/Makefile.inc" MAN+= alarm.3 \ arc4random.3 \ basename.3 \ + cap_rights_get.3 \ cap_sandboxed.3 \ check_utility_compat.3 \ clock.3 \ @@ -303,8 +304,9 @@ MLINKS+=devname.3 fdevname.3 MLINKS+=devname.3 fdevname_r.3 MLINKS+=directory.3 closedir.3 \ directory.3 dirfd.3 \ - directory.3 opendir.3 \ + directory.3 fdclosedir.3 \ directory.3 fdopendir.3 \ + directory.3 opendir.3 \ directory.3 readdir.3 \ directory.3 readdir_r.3 \ directory.3 rewinddir.3 \ diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 5885420..77413d6 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -409,6 +409,10 @@ FBSD_1.3 { waitid; }; +FBSD_1.4 { + scandir_b; +}; + FBSDprivate_1.0 { /* needed by thread libraries */ __thr_jtable; diff --git a/lib/libc/gen/cap_rights_get.3 b/lib/libc/gen/cap_rights_get.3 new file mode 100644 index 0000000..bc6fb24 --- /dev/null +++ b/lib/libc/gen/cap_rights_get.3 @@ -0,0 +1,119 @@ +.\" +.\" Copyright (c) 2013 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 27, 2014 +.Dt CAP_RIGHTS_GET 3 +.Os +.Sh NAME +.Nm cap_rights_get +.Nd obtain capability rights +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/capsicum.h +.Ft int +.Fn cap_rights_get "int fd" "cap_rights_t *rights" +.Sh DESCRIPTION +The +.Nm cap_rights_get +function allows to obtain current capability rights for the given descriptor. +The function will fill the +.Fa rights +argument with all capability rights if they were not limited or capability +rights configured during the last successful call of +.Xr cap_rights_limit 2 +on the given descriptor. +.Pp +The +.Fa rights +argument can be inspected using +.Xr cap_rights_init 3 +family of functions. +.Pp +The complete list of the capability rights can be found in the +.Xr rights 4 +manual page. +.Sh RETURN VALUES +.Rv -std +.Sh EXAMPLES +The following example demonstrates how to limit file descriptor capability +rights and how to obtain them. +.Bd -literal +cap_rights_t setrights, getrights; +int fd; + +memset(&setrights, 0, sizeof(setrights)); +memset(&getrights, 0, sizeof(getrights)); + +fd = open("/tmp/foo", O_RDONLY); +if (fd < 0) + err(1, "open() failed"); + +cap_rights_init(&setrights, CAP_FSTAT, CAP_READ); +if (cap_rights_limit(fd, &setrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit() failed"); + +if (cap_rights_get(fd, &getrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_get() failed"); + +assert(memcmp(&setrights, &getrights, sizeof(setrights)) == 0); +.Ed +.Sh ERRORS +.Fn cap_rights_get +succeeds unless: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument is not a valid active descriptor. +.It Bq Er EFAULT +The +.Fa rights +argument points at an invalid address. +.El +.Sh SEE ALSO +.Xr cap_rights_limit 2 , +.Xr cap_rights_init 3 , +.Xr errno 2 , +.Xr open 2 , +.Xr assert 3 , +.Xr err 3 , +.Xr memcmp 3 , +.Xr memset 3 , +.Xr capsicum 4 , +.Xr rights 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh AUTHORS +This function was created by +.An Pawel Jakub Dawidek Aq pawel@dawidek.net +under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/gen/cap_sandboxed.3 b/lib/libc/gen/cap_sandboxed.3 index 067d6d2..7019bfb 100644 --- a/lib/libc/gen/cap_sandboxed.3 +++ b/lib/libc/gen/cap_sandboxed.3 @@ -1,3 +1,4 @@ +.\" .\" Copyright (c) 2012 The FreeBSD Foundation .\" All rights reserved. .\" @@ -27,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 18, 2012 +.Dd March 27, 2014 .Dt CAP_SANDBOXED 3 .Os .Sh NAME @@ -36,7 +37,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/capability.h +.In sys/capsicum.h .In stdbool.h .Ft bool .Fn cap_sandboxed "void" diff --git a/lib/libc/gen/cap_sandboxed.c b/lib/libc/gen/cap_sandboxed.c index baa9b3f..ec2d4db 100644 --- a/lib/libc/gen/cap_sandboxed.c +++ b/lib/libc/gen/cap_sandboxed.c @@ -30,7 +30,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/capability.h> +#include <sys/capsicum.h> #include <assert.h> #include <errno.h> diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index 9133e37..2464d41 100644 --- a/lib/libc/gen/fts.3 +++ b/lib/libc/gen/fts.3 @@ -28,7 +28,7 @@ .\" @(#)fts.3 8.5 (Berkeley) 4/16/94 .\" $FreeBSD$ .\" -.Dd May 21, 2013 +.Dd January 12, 2014 .Dt FTS 3 .Os .Sh NAME @@ -304,7 +304,6 @@ file is a member. A parent structure for the initial entry point is provided as well, however, only the .Fa fts_level , -.Fa fts_bignum , .Fa fts_number and .Fa fts_pointer @@ -366,13 +365,6 @@ The .Fa fts_name field is always .Dv NUL Ns -terminated . -.Pp -Note that the use of -.Fa fts_bignum -is mutually exclusive with the use of -.Fa fts_number -or -.Fa fts_pointer . .Sh FTS_OPEN The .Fn fts_open diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index d15be06..7635fbc 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -62,7 +62,7 @@ static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static FTSENT *fts_sort(FTS *, FTSENT *, size_t); -static int fts_stat(FTS *, FTSENT *, int); +static int fts_stat(FTS *, FTSENT *, int, int); static int fts_safe_changedir(FTS *, FTSENT *, int, char *); static int fts_ufslinks(FTS *, const FTSENT *); @@ -161,17 +161,13 @@ fts_open(argv, options, compar) /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { - /* Don't allow zero-length paths. */ - if ((len = strlen(*argv)) == 0) { - errno = ENOENT; - goto mem3; - } + len = strlen(*argv); p = fts_alloc(sp, *argv, len); p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; - p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) @@ -326,7 +322,7 @@ fts_read(FTS *sp) /* Any type of file may be re-visited; re-stat and re-turn. */ if (instr == FTS_AGAIN) { - p->fts_info = fts_stat(sp, p, 0); + p->fts_info = fts_stat(sp, p, 0, -1); return (p); } @@ -338,7 +334,7 @@ fts_read(FTS *sp) */ if (instr == FTS_FOLLOW && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { - p->fts_info = fts_stat(sp, p, 1); + p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { @@ -406,8 +402,6 @@ fts_read(FTS *sp) /* Move to the next node on this level. */ next: tmp = p; if ((p = p->fts_link) != NULL) { - free(tmp); - /* * If reached the top, return to the original directory (or * the root of the tree), and load the paths for the next root. @@ -417,6 +411,7 @@ next: tmp = p; SET(FTS_STOP); return (NULL); } + free(tmp); fts_load(sp, p); return (sp->fts_cur = p); } @@ -426,10 +421,12 @@ next: tmp = p; * ignore. If followed, get a file descriptor so we can * get back if necessary. */ - if (p->fts_instr == FTS_SKIP) + if (p->fts_instr == FTS_SKIP) { + free(tmp); goto next; + } if (p->fts_instr == FTS_FOLLOW) { - p->fts_info = fts_stat(sp, p, 1); + p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { @@ -441,6 +438,8 @@ next: tmp = p; p->fts_instr = FTS_NOINSTR; } + free(tmp); + name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); @@ -449,13 +448,13 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); /* Move up to the parent node. */ p = tmp->fts_parent; - free(tmp); if (p->fts_level == FTS_ROOTPARENTLEVEL) { /* * Done; free everything up and set errno to 0 so the user * can distinguish between error and EOF. */ + free(tmp); free(p); errno = 0; return (sp->fts_cur = NULL); @@ -488,6 +487,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); SET(FTS_STOP); return (NULL); } + free(tmp); p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } @@ -800,10 +800,11 @@ mem1: saved_errno = errno; if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; memmove(cp, p->fts_name, p->fts_namelen + 1); - } else + p->fts_info = fts_stat(sp, p, 0, _dirfd(dirp)); + } else { p->fts_accpath = p->fts_name; - /* Stat it. */ - p->fts_info = fts_stat(sp, p, 0); + p->fts_info = fts_stat(sp, p, 0, -1); + } /* Decrement link count if applicable. */ if (nlinks > 0 && (p->fts_info == FTS_D || @@ -868,13 +869,19 @@ mem1: saved_errno = errno; } static int -fts_stat(FTS *sp, FTSENT *p, int follow) +fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) { FTSENT *t; dev_t dev; ino_t ino; struct stat *sbp, sb; int saved_errno; + const char *path; + + if (dfd == -1) + path = p->fts_accpath, dfd = AT_FDCWD; + else + path = p->fts_name; /* If user needs stat info, stat buffer already allocated. */ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; @@ -896,16 +903,16 @@ fts_stat(FTS *sp, FTSENT *p, int follow) * fail, set the errno from the stat call. */ if (ISSET(FTS_LOGICAL) || follow) { - if (stat(p->fts_accpath, sbp)) { + if (fstatat(dfd, path, sbp, 0)) { saved_errno = errno; - if (!lstat(p->fts_accpath, sbp)) { + if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { errno = 0; return (FTS_SLNONE); } p->fts_errno = saved_errno; goto err; } - } else if (lstat(p->fts_accpath, sbp)) { + } else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(struct stat)); return (FTS_NS); diff --git a/lib/libc/gen/getlogin.c b/lib/libc/gen/getlogin.c index 4dab3cb..7ab4cba 100644 --- a/lib/libc/gen/getlogin.c +++ b/lib/libc/gen/getlogin.c @@ -87,11 +87,16 @@ getlogin_r(char *logname, int namelen) char *result; int len; int status; - + + if (namelen < 1) + return (ERANGE); + logname[0] = '\0'; + THREAD_LOCK(); result = getlogin_basic(&status); - if (status == 0) { - if ((len = strlen(result) + 1) > namelen) + if (status == 0 && result != NULL) { + len = strlen(result) + 1; + if (len > namelen) status = ERANGE; else strncpy(logname, result, len); diff --git a/lib/libc/gen/getttyent.c b/lib/libc/gen/getttyent.c index b82c30a..d104305 100644 --- a/lib/libc/gen/getttyent.c +++ b/lib/libc/gen/getttyent.c @@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$"); #include <ctype.h> #include <string.h> +#include <sys/types.h> +#include <sys/sysctl.h> + static char zapchar; static FILE *tf; static size_t lbsize; @@ -64,6 +67,36 @@ getttynam(const char *tty) return (t); } +static int +auto_tty_status(const char *ty_name) +{ + size_t len; + char *buf, *cons, *nextcons; + + /* Check if this is an enabled kernel console line */ + buf = NULL; + if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1) + return (0); /* Errors mean don't enable */ + buf = malloc(len); + if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1) + goto done; + + if ((cons = strchr(buf, '/')) == NULL) + goto done; + *cons = '\0'; + nextcons = buf; + while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) { + if (strcmp(cons, ty_name) == 0) { + free(buf); + return (TTY_ON); + } + } + +done: + free(buf); + return (0); +} + struct ttyent * getttyent(void) { @@ -126,6 +159,8 @@ getttyent(void) tty.ty_status &= ~TTY_ON; else if (scmp(_TTYS_ON)) tty.ty_status |= TTY_ON; + else if (scmp(_TTYS_ONIFCONSOLE)) + tty.ty_status |= auto_tty_status(tty.ty_name); else if (scmp(_TTYS_SECURE)) tty.ty_status |= TTY_SECURE; else if (scmp(_TTYS_INSECURE)) diff --git a/lib/libc/gen/getutxent.c b/lib/libc/gen/getutxent.c index 20e8859..1679aa4 100644 --- a/lib/libc/gen/getutxent.c +++ b/lib/libc/gen/getutxent.c @@ -122,9 +122,20 @@ getfutxent(struct futx *fu) if (udb == UTXDB_LOG) { uint16_t len; +retry: if (fread(&len, sizeof(len), 1, uf) != 1) return (-1); len = be16toh(len); + if (len == 0) { + /* + * XXX: Though zero-size records are valid in theory, + * they can never occur in practice. Zero-size records + * indicate file corruption. Seek one byte forward, to + * see if we can find a record there. + */ + ungetc('\0', uf); + goto retry; + } if (len > sizeof *fu) { /* Forward compatibility. */ if (fread(fu, sizeof(*fu), 1, uf) != 1) diff --git a/lib/libc/gen/pmadvise.c b/lib/libc/gen/pmadvise.c index 60cef63..0dc77e3 100644 --- a/lib/libc/gen/pmadvise.c +++ b/lib/libc/gen/pmadvise.c @@ -8,9 +8,19 @@ __FBSDID("$FreeBSD$"); #include <sys/mman.h> +#include <errno.h> int posix_madvise(void *address, size_t size, int how) { - return madvise(address, size, how); + int ret, saved_errno; + + saved_errno = errno; + if (madvise(address, size, how) == -1) { + ret = errno; + errno = saved_errno; + } else { + ret = 0; + } + return (ret); } diff --git a/lib/libc/gen/popen.c b/lib/libc/gen/popen.c index b0597c8..e54bb5c 100644 --- a/lib/libc/gen/popen.c +++ b/lib/libc/gen/popen.c @@ -90,7 +90,7 @@ popen(command, type) (type[1] && (type[1] != 'e' || type[2]))) return (NULL); } - if ((cloexec ? pipe2(pdes, O_CLOEXEC) : pipe(pdes)) < 0) + if (pipe2(pdes, O_CLOEXEC) < 0) return (NULL); if ((cur = malloc(sizeof(struct pid))) == NULL) { @@ -123,29 +123,20 @@ popen(command, type) * the compiler is free to corrupt all the local * variables. */ - if (!cloexec) - (void)_close(pdes[0]); if (pdes[1] != STDOUT_FILENO) { (void)_dup2(pdes[1], STDOUT_FILENO); - if (!cloexec) - (void)_close(pdes[1]); if (twoway) (void)_dup2(STDOUT_FILENO, STDIN_FILENO); } else if (twoway && (pdes[1] != STDIN_FILENO)) { (void)_dup2(pdes[1], STDIN_FILENO); - if (cloexec) - (void)_fcntl(pdes[1], F_SETFD, 0); - } else if (cloexec) + (void)_fcntl(pdes[1], F_SETFD, 0); + } else (void)_fcntl(pdes[1], F_SETFD, 0); } else { if (pdes[0] != STDIN_FILENO) { (void)_dup2(pdes[0], STDIN_FILENO); - if (!cloexec) - (void)_close(pdes[0]); - } else if (cloexec) + } else (void)_fcntl(pdes[0], F_SETFD, 0); - if (!cloexec) - (void)_close(pdes[1]); } SLIST_FOREACH(p, &pidlist, next) (void)_close(fileno(p->fp)); @@ -171,6 +162,14 @@ popen(command, type) SLIST_INSERT_HEAD(&pidlist, cur, next); THREAD_UNLOCK(); + /* + * To guard against undesired fd passing with concurrent calls, + * only clear the close-on-exec flag after linking the file into + * the list which will cause an explicit close. + */ + if (!cloexec) + (void)_fcntl(*type == 'r' ? pdes[0] : pdes[1], F_SETFD, 0); + return (iop); } diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3 index b3e0a7e..eaba754 100644 --- a/lib/libc/gen/scandir.3 +++ b/lib/libc/gen/scandir.3 @@ -42,6 +42,8 @@ .Ft int .Fn scandir "const char *dirname" "struct dirent ***namelist" "int \*(lp*select\*(rp\*(lpconst struct dirent *\*(rp" "int \*(lp*compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp" .Ft int +.Fn scandir_b "const char *dirname" "struct dirent ***namelist" "int \*(lp*select\^(rp\*(lpconst struct dirent *\*(rp" "int \*(lp^compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp" +.Ft int .Fn alphasort "const struct dirent **d1" "const struct dirent **d2" .Sh DESCRIPTION The @@ -87,6 +89,15 @@ argument to sort the array alphabetically using The memory allocated for the array can be deallocated with .Xr free 3 , by freeing each pointer in the array and then the array itself. +.Pp +The +.Fn scandir_b +function behaves in the same way as +.Fn scandir , +but takes blocks as arguments instead of function pointers and calls +.Fn qsort_b +rather than +.Fn qsort . .Sh DIAGNOSTICS Returns \-1 if the directory cannot be opened for reading or if .Xr malloc 3 diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c index 93bc852..d81acc8 100644 --- a/lib/libc/gen/scandir.c +++ b/lib/libc/gen/scandir.c @@ -46,6 +46,17 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include "un-namespace.h" +#ifdef I_AM_SCANDIR_B +#include "block_abi.h" +#define SELECT(x) CALL_BLOCK(select, x) +#ifndef __BLOCKS__ +void +qsort_b(void *, size_t, size_t, void*); +#endif +#else +#define SELECT(x) select(x) +#endif + static int alphasort_thunk(void *thunk, const void *p1, const void *p2); /* @@ -60,9 +71,15 @@ static int alphasort_thunk(void *thunk, const void *p1, const void *p2); (((dp)->d_namlen + 1 + 3) &~ 3)) int +#ifdef I_AM_SCANDIR_B +scandir_b(const char *dirname, struct dirent ***namelist, + DECLARE_BLOCK(int, select, const struct dirent *), + DECLARE_BLOCK(int, dcomp, const struct dirent **, const struct dirent **)) +#else scandir(const char *dirname, struct dirent ***namelist, int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **, const struct dirent **)) +#endif { struct dirent *d, *p, **names = NULL; size_t nitems = 0; @@ -78,7 +95,7 @@ scandir(const char *dirname, struct dirent ***namelist, goto fail; while ((d = readdir(dirp)) != NULL) { - if (select != NULL && !(*select)(d)) + if (select != NULL && !SELECT(d)) continue; /* just selected names */ /* * Make a minimum size copy of the data @@ -111,8 +128,12 @@ scandir(const char *dirname, struct dirent ***namelist, } closedir(dirp); if (nitems && dcomp != NULL) +#ifdef I_AM_SCANDIR_B + qsort_b(names, nitems, sizeof(struct dirent *), (void*)dcomp); +#else qsort_r(names, nitems, sizeof(struct dirent *), &dcomp, alphasort_thunk); +#endif *namelist = names; return (nitems); diff --git a/lib/libc/gen/scandir_b.c b/lib/libc/gen/scandir_b.c new file mode 100644 index 0000000..6310a91 --- /dev/null +++ b/lib/libc/gen/scandir_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#define I_AM_SCANDIR_B +#include "scandir.c" diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c index 1bf84ea..9a2ab27 100644 --- a/lib/libc/gen/sem_new.c +++ b/lib/libc/gen/sem_new.c @@ -381,6 +381,7 @@ _sem_timedwait(sem_t * __restrict sem, return (-1); retval = 0; + _pthread_testcancel(); for (;;) { while ((val = sem->_kern._count) > 0) { if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 6357761..3a5cafe 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -341,9 +341,9 @@ connectlog(void) struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ if (LogFile == -1) { - if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, + 0)) == -1) return; - (void)_fcntl(LogFile, F_SETFD, FD_CLOEXEC); } if (LogFile != -1 && status == NOCONN) { SyslogAddr.sun_len = sizeof(SyslogAddr); diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c index 466f957..4b083da 100644 --- a/lib/libc/gen/tls.c +++ b/lib/libc/gen/tls.c @@ -40,9 +40,9 @@ #include "libc_private.h" /* Provided by jemalloc to avoid bootstrapping issues. */ -void *__jemalloc_a0malloc(size_t size); -void *__jemalloc_a0calloc(size_t num, size_t size); -void __jemalloc_a0free(void *ptr); +void *__je_a0malloc(size_t size); +void *__je_a0calloc(size_t num, size_t size); +void __je_a0free(void *ptr); __weak_reference(__libc_allocate_tls, _rtld_allocate_tls); __weak_reference(__libc_free_tls, _rtld_free_tls); @@ -125,8 +125,8 @@ __libc_free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused) tls = (Elf_Addr **)((Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE); dtv = tls[0]; - __jemalloc_a0free(dtv); - __jemalloc_a0free(tcb); + __je_a0free(dtv); + __je_a0free(tcb); } /* @@ -142,18 +142,18 @@ __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign __unused) if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) return (oldtcb); - tcb = __jemalloc_a0calloc(1, tls_static_space + tcbsize - TLS_TCB_SIZE); + tcb = __je_a0calloc(1, tls_static_space + tcbsize - TLS_TCB_SIZE); tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE); if (oldtcb != NULL) { memcpy(tls, oldtcb, tls_static_space); - __jemalloc_a0free(oldtcb); + __je_a0free(oldtcb); /* Adjust the DTV. */ dtv = tls[0]; dtv[2] = (Elf_Addr)tls + TLS_TCB_SIZE; } else { - dtv = __jemalloc_a0malloc(3 * sizeof(Elf_Addr)); + dtv = __je_a0malloc(3 * sizeof(Elf_Addr)); tls[0] = dtv; dtv[0] = 1; dtv[1] = 1; @@ -194,8 +194,8 @@ __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign) dtv = ((Elf_Addr**)tcb)[1]; tlsend = (Elf_Addr) tcb; tlsstart = tlsend - size; - __jemalloc_a0free((void*) tlsstart); - __jemalloc_a0free(dtv); + __je_a0free((void*) tlsstart); + __je_a0free(dtv); } /* @@ -213,8 +213,8 @@ __libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) if (tcbsize < 2 * sizeof(Elf_Addr)) tcbsize = 2 * sizeof(Elf_Addr); - tls = __jemalloc_a0calloc(1, size + tcbsize); - dtv = __jemalloc_a0malloc(3 * sizeof(Elf_Addr)); + tls = __je_a0calloc(1, size + tcbsize); + dtv = __je_a0malloc(3 * sizeof(Elf_Addr)); segbase = (Elf_Addr)(tls + size); ((Elf_Addr*)segbase)[0] = segbase; diff --git a/lib/libc/gmon/Makefile.inc b/lib/libc/gmon/Makefile.inc index 98c7395..3e3dede 100644 --- a/lib/libc/gmon/Makefile.inc +++ b/lib/libc/gmon/Makefile.inc @@ -2,11 +2,11 @@ # $FreeBSD$ # gmon sources -.PATH: ${.CURDIR}/gmon +.PATH: ${LIBC_SRCTOP}/gmon SRCS+= gmon.c mcount.c -SYM_MAPS+=${.CURDIR}/gmon/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/gmon/Symbol.map MAN+= moncontrol.3 diff --git a/lib/libc/i386/Makefile.inc b/lib/libc/i386/Makefile.inc index ba8e502..627311c 100644 --- a/lib/libc/i386/Makefile.inc +++ b/lib/libc/i386/Makefile.inc @@ -3,4 +3,4 @@ # Long double is 80 bits GDTOASRCS+=strtorx.c MDSRCS+=machdep_ldisx.c -SYM_MAPS+=${.CURDIR}/i386/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/i386/Symbol.map diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h index 355b117..9a4856a 100644 --- a/lib/libc/i386/SYS.h +++ b/lib/libc/i386/SYS.h @@ -36,22 +36,19 @@ #include <sys/syscall.h> #include <machine/asm.h> -#define SYSCALL(x) ENTRY(__CONCAT(__sys_,x)); \ - .weak CNAME(x); \ - .set CNAME(x),CNAME(__CONCAT(__sys_,x)); \ - .weak CNAME(__CONCAT(_,x)); \ - .set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \ - mov __CONCAT($SYS_,x),%eax; KERNCALL; \ - jb HIDENAME(cerror) +#define SYSCALL(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ + jb HIDENAME(cerror) -#define RSYSCALL(x) SYSCALL(x); ret; END(__CONCAT(__sys_,x)) +#define RSYSCALL(name) SYSCALL(name); ret; END(__sys_##name) -#define PSEUDO(x) ENTRY(__CONCAT(__sys_,x)); \ - .weak CNAME(__CONCAT(_,x)); \ - .set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \ - mov __CONCAT($SYS_,x),%eax; KERNCALL; \ - jb HIDENAME(cerror); ret; \ - END(__CONCAT(__sys_,x)) +#define PSEUDO(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ + jb HIDENAME(cerror); ret; \ + END(__sys_##name) /* gas messes up offset -- although we don't currently need it, do for BCS */ #define LCALL(x,y) .byte 0x9a ; .long y; .word x diff --git a/lib/libc/i386/gen/_setjmp.S b/lib/libc/i386/gen/_setjmp.S index 3d9fdb4..c5996c6 100644 --- a/lib/libc/i386/gen/_setjmp.S +++ b/lib/libc/i386/gen/_setjmp.S @@ -60,8 +60,7 @@ ENTRY(_setjmp) ret END(_setjmp) - .weak CNAME(_longjmp) - .set CNAME(_longjmp),CNAME(___longjmp) + WEAK_REFERENCE(___longjmp, _longjmp) ENTRY(___longjmp) movl 4(%esp),%edx movl 8(%esp),%eax diff --git a/lib/libc/i386/gen/setjmp.S b/lib/libc/i386/gen/setjmp.S index a409e35..6e15868 100644 --- a/lib/libc/i386/gen/setjmp.S +++ b/lib/libc/i386/gen/setjmp.S @@ -78,8 +78,7 @@ ENTRY(setjmp) ret END(setjmp) - .weak CNAME(longjmp) - .set CNAME(longjmp),CNAME(__longjmp) + WEAK_REFERENCE(__longjmp, longjmp) ENTRY(__longjmp) movl 4(%esp),%edx PIC_PROLOGUE diff --git a/lib/libc/i386/gen/sigsetjmp.S b/lib/libc/i386/gen/sigsetjmp.S index 936edba..0920b6d 100644 --- a/lib/libc/i386/gen/sigsetjmp.S +++ b/lib/libc/i386/gen/sigsetjmp.S @@ -87,8 +87,7 @@ ENTRY(sigsetjmp) ret END(sigsetjmp) - .weak CNAME(siglongjmp); - .set CNAME(siglongjmp),CNAME(__siglongjmp) + WEAK_REFERENCE(__siglongjmp, siglongjmp) ENTRY(__siglongjmp) movl 4(%esp),%edx cmpl $0,44(%edx) diff --git a/lib/libc/i386/string/strchr.S b/lib/libc/i386/string/strchr.S index f57c2cd..83aa87f 100644 --- a/lib/libc/i386/string/strchr.S +++ b/lib/libc/i386/string/strchr.S @@ -63,6 +63,6 @@ L2: ret END(strchr) -WEAK_ALIAS(index, strchr) +WEAK_REFERENCE(strchr, index) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strrchr.S b/lib/libc/i386/string/strrchr.S index 5ec5287..5e250b0 100644 --- a/lib/libc/i386/string/strrchr.S +++ b/lib/libc/i386/string/strrchr.S @@ -64,6 +64,6 @@ L2: ret END(strrchr) -WEAK_ALIAS(rindex, strrchr) +WEAK_REFERENCE(strrchr, rindex) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc index 9eefabc..b56183c 100644 --- a/lib/libc/i386/sys/Makefile.inc +++ b/lib/libc/i386/sys/Makefile.inc @@ -15,7 +15,7 @@ MDASM= Ovfork.S brk.S cerror.S exect.S getcontext.S pipe.S ptrace.S \ NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/i386/sys/Ovfork.S b/lib/libc/i386/sys/Ovfork.S index 3ef7169..b364920 100644 --- a/lib/libc/i386/sys/Ovfork.S +++ b/lib/libc/i386/sys/Ovfork.S @@ -38,10 +38,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" - .weak _vfork - .set _vfork,__sys_vfork - .weak vfork - .set vfork,__sys_vfork + WEAK_REFERENCE(__sys_vfork, _vfork) + WEAK_REFERENCE(__sys_vfork, vfork) ENTRY(__sys_vfork) popl %ecx /* my rta into ecx */ mov $SYS_vfork,%eax diff --git a/lib/libc/i386/sys/getcontext.S b/lib/libc/i386/sys/getcontext.S index 7114689..4923382 100644 --- a/lib/libc/i386/sys/getcontext.S +++ b/lib/libc/i386/sys/getcontext.S @@ -34,10 +34,8 @@ __FBSDID("$FreeBSD$"); * Otherwise, the setcontext() syscall will return here and we'll * pop off the return address and go to the *setcontext* call. */ - .weak _getcontext - .set _getcontext,__sys_getcontext - .weak getcontext - .set getcontext,__sys_getcontext + WEAK_REFERENCE(__sys_getcontext, _getcontext) + WEAK_REFERENCE(__sys_getcontext, getcontext) ENTRY(__sys_getcontext) movl (%esp),%ecx /* save getcontext return address */ mov $SYS_getcontext,%eax diff --git a/lib/libc/ia64/Makefile.inc b/lib/libc/ia64/Makefile.inc index b451f85..16565c6 100644 --- a/lib/libc/ia64/Makefile.inc +++ b/lib/libc/ia64/Makefile.inc @@ -6,4 +6,4 @@ # Long double is 80 bits GDTOASRCS+=strtorx.c MDSRCS+=machdep_ldisx.c -SYM_MAPS+=${.CURDIR}/ia64/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/ia64/Symbol.map diff --git a/lib/libc/ia64/sys/Makefile.inc b/lib/libc/ia64/sys/Makefile.inc index 2846590..b3bacd4 100644 --- a/lib/libc/ia64/sys/Makefile.inc +++ b/lib/libc/ia64/sys/Makefile.inc @@ -9,6 +9,6 @@ MDASM+= Ovfork.S brk.S cerror.S exect.S fork.S getcontext.S pipe.S ptrace.S \ NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/iconv/Makefile.inc b/lib/libc/iconv/Makefile.inc index 8c43a20..5442f79 100644 --- a/lib/libc/iconv/Makefile.inc +++ b/lib/libc/iconv/Makefile.inc @@ -1,7 +1,7 @@ # $FreeBSD$ # iconv sources -.PATH: ${.CURDIR}/iconv +.PATH: ${LIBC_SRCTOP}/iconv MAN+= iconv.3 iconvctl.3 iconv_canonicalize.3 iconvlist.3 __iconv_get_list.3 MLINKS+= iconv.3 iconv_open.3 \ @@ -14,5 +14,9 @@ SRCS+= citrus_bcs.c citrus_bcs_strtol.c citrus_bcs_strtoul.c \ citrus_esdb.c citrus_hash.c citrus_iconv.c citrus_lookup.c \ citrus_lookup_factory.c citrus_mapper.c citrus_memstream.c \ citrus_mmap.c citrus_module.c citrus_none.c citrus_pivot_factory.c \ - citrus_prop.c citrus_stdenc.c iconv.c -SYM_MAPS+= ${.CURDIR}/iconv/Symbol.map + citrus_prop.c citrus_stdenc.c bsd_iconv.c iconv_compat.c +SYM_MAPS+= ${LIBC_SRCTOP}/iconv/Symbol.map + +.if ${MK_ICONV} == yes +.include "${LIBC_SRCTOP}/../libc_nonshared/Makefile.iconv" +.endif diff --git a/lib/libc/iconv/Symbol.map b/lib/libc/iconv/Symbol.map index 05df2ea..8a9a75d 100644 --- a/lib/libc/iconv/Symbol.map +++ b/lib/libc/iconv/Symbol.map @@ -2,30 +2,18 @@ * $FreeBSD$ */ -FBSD_1.2 { - __iconv; - __iconv_free_list; - __iconv_get_list; - _libiconv_version; - iconv_canonicalize; - libiconv; - libiconv_close; - libiconv_open; - libiconv_open_into; - libiconv_set_relocation_prefix; - libiconvctl; - libiconvlist; -}; - FBSD_1.3 { - _iconv_version; - iconv; - iconv_open; - iconv_close; - iconv_open_into; - iconv_set_relocation_prefix; - iconvctl; - iconvlist; + __bsd___iconv; + __bsd___iconv_free_list; + __bsd___iconv_get_list; + __bsd_iconv; + __bsd_iconv_canonicalize; + __bsd_iconv_close; + __bsd_iconv_open; + __bsd_iconv_open_into; + __bsd_iconv_set_relocation_prefix; + __bsd_iconvctl; + __bsd_iconvlist; }; FBSDprivate_1.0 { diff --git a/lib/libelf/elf_getarhdr.c b/lib/libc/iconv/__iconv.c index 31b1f34..c9bee3f 100644 --- a/lib/libelf/elf_getarhdr.c +++ b/lib/libc/iconv/__iconv.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Joseph Koshy + * Copyright (c) 2013 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,27 +22,17 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" -Elf_Arhdr * -elf_getarhdr(Elf *e) +size_t +__iconv(iconv_t a, const char **b, size_t *c, char **d, + size_t *e, __uint32_t f, size_t *g) { - Elf_Arhdr *arh; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((arh = e->e_arhdr) != NULL) - return (arh); - - return (_libelf_ar_gethdr(e)); + return __bsd___iconv(a, b, c, d, e, f, g); } diff --git a/lib/libc/iconv/__iconv_free_list.c b/lib/libc/iconv/__iconv_free_list.c new file mode 100644 index 0000000..de9701e --- /dev/null +++ b/lib/libc/iconv/__iconv_free_list.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +void +__iconv_free_list(char **a, size_t b) +{ + __bsd___iconv_free_list(a, b); +} diff --git a/lib/libc/iconv/__iconv_get_list.3 b/lib/libc/iconv/__iconv_get_list.3 index 7c8d015..4db88d8 100644 --- a/lib/libc/iconv/__iconv_get_list.3 +++ b/lib/libc/iconv/__iconv_get_list.3 @@ -89,7 +89,7 @@ and functions are non-standard interfaces, which appeared in the implementation of the Citrus Project. The iconv implementation of the Citrus Project was adopted in -.Fx 9 . +.Fx 9.0 . .Sh AUTHORS This manual page was written by .An Gabor Kovesdan Aq gabor@FreeBSD.org . diff --git a/lib/libc/iconv/__iconv_get_list.c b/lib/libc/iconv/__iconv_get_list.c new file mode 100644 index 0000000..437d413 --- /dev/null +++ b/lib/libc/iconv/__iconv_get_list.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +int +__iconv_get_list(char ***a, size_t *b, __iconv_bool c) +{ + return __bsd___iconv_get_list(a, b, c); +} diff --git a/lib/libc/iconv/bsd_iconv.c b/lib/libc/iconv/bsd_iconv.c new file mode 100644 index 0000000..40a1a4e --- /dev/null +++ b/lib/libc/iconv/bsd_iconv.c @@ -0,0 +1,318 @@ +/* $FreeBSD$ */ +/* $NetBSD: iconv.c,v 1.11 2009/03/03 16:22:33 explorer Exp $ */ + +/*- + * Copyright (c) 2003 Citrus Project, + * Copyright (c) 2009, 2010 Gabor Kovesdan <gabor@FreeBSD.org>, + * 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. + */ + +#include <sys/cdefs.h> +#include <sys/queue.h> +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <iconv.h> +#include <limits.h> +#include <paths.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "citrus_types.h" +#include "citrus_module.h" +#include "citrus_esdb.h" +#include "citrus_hash.h" +#include "citrus_iconv.h" + +#include "iconv-internal.h" + +#define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1) + +static iconv_t +__bsd___iconv_open(const char *out, const char *in, struct _citrus_iconv *handle) +{ + const char *out_slashes; + char *out_noslashes; + int ret; + + /* + * Remove anything following a //, as these are options (like + * //ignore, //translate, etc) and we just don't handle them. + * This is for compatibility with software that uses these + * blindly. + */ + out_slashes = strstr(out, "//"); + if (out_slashes != NULL) { + out_noslashes = strndup(out, out_slashes - out); + if (out_noslashes == NULL) { + errno = ENOMEM; + return ((iconv_t)-1); + } + ret = _citrus_iconv_open(&handle, in, out_noslashes); + free(out_noslashes); + } else { + ret = _citrus_iconv_open(&handle, in, out); + } + + if (ret) { + errno = ret == ENOENT ? EINVAL : ret; + return ((iconv_t)-1); + } + + handle->cv_shared->ci_discard_ilseq = strcasestr(out, "//IGNORE"); + handle->cv_shared->ci_hooks = NULL; + + return ((iconv_t)(void *)handle); +} + +iconv_t +__bsd_iconv_open(const char *out, const char *in) +{ + + return (__bsd___iconv_open(out, in, NULL)); +} + +int +__bsd_iconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr) +{ + struct _citrus_iconv *handle; + + handle = (struct _citrus_iconv *)ptr; + return ((__bsd___iconv_open(out, in, handle) == (iconv_t)-1) ? -1 : 0); +} + +int +__bsd_iconv_close(iconv_t handle) +{ + + if (ISBADF(handle)) { + errno = EBADF; + return (-1); + } + + _citrus_iconv_close((struct _citrus_iconv *)(void *)handle); + + return (0); +} + +size_t +__bsd_iconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout) +{ + size_t ret; + int err; + + if (ISBADF(handle)) { + errno = EBADF; + return ((size_t)-1); + } + + err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, + in, szin, out, szout, 0, &ret); + if (err) { + errno = err; + ret = (size_t)-1; + } + + return (ret); +} + +size_t +__bsd___iconv(iconv_t handle, const char **in, size_t *szin, char **out, + size_t *szout, uint32_t flags, size_t *invalids) +{ + size_t ret; + int err; + + if (ISBADF(handle)) { + errno = EBADF; + return ((size_t)-1); + } + + err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, + in, szin, out, szout, flags, &ret); + if (invalids) + *invalids = ret; + if (err) { + errno = err; + ret = (size_t)-1; + } + + return (ret); +} + +int +__bsd___iconv_get_list(char ***rlist, size_t *rsz, bool sorted) +{ + int ret; + + ret = _citrus_esdb_get_list(rlist, rsz, sorted); + if (ret) { + errno = ret; + return (-1); + } + + return (0); +} + +void +__bsd___iconv_free_list(char **list, size_t sz) +{ + + _citrus_esdb_free_list(list, sz); +} + +/* + * GNU-compatibile non-standard interfaces. + */ +static int +qsort_helper(const void *first, const void *second) +{ + const char * const *s1; + const char * const *s2; + + s1 = first; + s2 = second; + return (strcmp(*s1, *s2)); +} + +void +__bsd_iconvlist(int (*do_one) (unsigned int, const char * const *, + void *), void *data) +{ + char **list, **names; + const char * const *np; + char *curitem, *curkey, *slashpos; + size_t sz; + unsigned int i, j; + + i = 0; + + if (__bsd___iconv_get_list(&list, &sz, true)) + list = NULL; + qsort((void *)list, sz, sizeof(char *), qsort_helper); + while (i < sz) { + j = 0; + slashpos = strchr(list[i], '/'); + curkey = (char *)malloc(slashpos - list[i] + 2); + names = (char **)malloc(sz * sizeof(char *)); + if ((curkey == NULL) || (names == NULL)) { + __bsd___iconv_free_list(list, sz); + return; + } + strlcpy(curkey, list[i], slashpos - list[i] + 1); + names[j++] = strdup(curkey); + for (; (i < sz) && (memcmp(curkey, list[i], strlen(curkey)) == 0); i++) { + slashpos = strchr(list[i], '/'); + curitem = (char *)malloc(strlen(slashpos) + 1); + if (curitem == NULL) { + __bsd___iconv_free_list(list, sz); + return; + } + strlcpy(curitem, &slashpos[1], strlen(slashpos) + 1); + if (strcmp(curkey, curitem) == 0) { + continue; + } + names[j++] = strdup(curitem); + } + np = (const char * const *)names; + do_one(j, np, data); + free(names); + } + + __bsd___iconv_free_list(list, sz); +} + +__inline const char * +__bsd_iconv_canonicalize(const char *name) +{ + + return (_citrus_iconv_canonicalize(name)); +} + +int +__bsd_iconvctl(iconv_t cd, int request, void *argument) +{ + struct _citrus_iconv *cv; + struct iconv_hooks *hooks; + const char *convname; + char src[PATH_MAX], *dst; + int *i; + + cv = (struct _citrus_iconv *)(void *)cd; + hooks = (struct iconv_hooks *)argument; + i = (int *)argument; + + if (ISBADF(cd)) { + errno = EBADF; + return (-1); + } + + switch (request) { + case ICONV_TRIVIALP: + convname = cv->cv_shared->ci_convname; + dst = strchr(convname, '/'); + + strlcpy(src, convname, dst - convname + 1); + dst++; + if ((convname == NULL) || (src == NULL) || (dst == NULL)) + return (-1); + *i = strcmp(src, dst) == 0 ? 1 : 0; + return (0); + case ICONV_GET_TRANSLITERATE: + *i = 1; + return (0); + case ICONV_SET_TRANSLITERATE: + return ((*i == 1) ? 0 : -1); + case ICONV_GET_DISCARD_ILSEQ: + *i = cv->cv_shared->ci_discard_ilseq ? 1 : 0; + return (0); + case ICONV_SET_DISCARD_ILSEQ: + cv->cv_shared->ci_discard_ilseq = *i; + return (0); + case ICONV_SET_HOOKS: + cv->cv_shared->ci_hooks = hooks; + return (0); + case ICONV_SET_FALLBACKS: + errno = EOPNOTSUPP; + return (-1); + case ICONV_GET_ILSEQ_INVALID: + *i = cv->cv_shared->ci_ilseq_invalid ? 1 : 0; + return (0); + case ICONV_SET_ILSEQ_INVALID: + cv->cv_shared->ci_ilseq_invalid = *i; + return (0); + default: + errno = EINVAL; + return (-1); + } +} + +void +__bsd_iconv_set_relocation_prefix(const char *orig_prefix __unused, + const char *curr_prefix __unused) +{ + +} diff --git a/lib/libc/iconv/citrus_bcs_strtol.c b/lib/libc/iconv/citrus_bcs_strtol.c index 4073622..ac874a3 100644 --- a/lib/libc/iconv/citrus_bcs_strtol.c +++ b/lib/libc/iconv/citrus_bcs_strtol.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_bcs_strtol.c,v 1.2 2009/01/11 02:46:24 christos Exp $ */ +/* $NetBSD: citrus_bcs_strtol.c,v 1.4 2013/04/26 21:20:47 joerg Exp $ */ /*- * Copyright (c) 2005 The DragonFly Project. All rights reserved. diff --git a/lib/libc/iconv/citrus_bcs_strtoul.c b/lib/libc/iconv/citrus_bcs_strtoul.c index d9fa97c..b33334a 100644 --- a/lib/libc/iconv/citrus_bcs_strtoul.c +++ b/lib/libc/iconv/citrus_bcs_strtoul.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_bcs_strtoul.c,v 1.3 2009/01/11 02:46:24 christos Exp $ */ +/* $NetBSD: citrus_bcs_strtoul.c,v 1.5 2013/04/26 21:20:48 joerg Exp $ */ /*- * Copyright (c) 2005 The DragonFly Project. All rights reserved. diff --git a/lib/libc/iconv/citrus_csmapper.c b/lib/libc/iconv/citrus_csmapper.c index e2d10d5..353adc9 100644 --- a/lib/libc/iconv/citrus_csmapper.c +++ b/lib/libc/iconv/citrus_csmapper.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_csmapper.c,v 1.10 2009/01/11 02:46:24 christos Exp $ */ +/* $NetBSD: citrus_csmapper.c,v 1.11 2011/11/20 07:43:52 tnozaki Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -140,6 +140,7 @@ find_best_pivot_pvdb(const char *src, const char *dst, char *pivot, if (ret) goto quit3; if (_db_lookup_by_s(db3, dst, &r2, NULL) != 0) + /* don't break the loop, test all src/dst pairs. */ goto quit4; /* r2: norm among pivot and dst */ ret = get32(&r2, &val32); diff --git a/lib/libc/iconv/citrus_csmapper.h b/lib/libc/iconv/citrus_csmapper.h index dd178da..cb1c4f1 100644 --- a/lib/libc/iconv/citrus_csmapper.h +++ b/lib/libc/iconv/citrus_csmapper.h @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_csmapper.h,v 1.2 2008/02/09 14:56:20 junyoung Exp $ */ +/* $NetBSD: citrus_csmapper.h,v 1.3 2013/06/24 17:28:35 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -28,7 +28,7 @@ */ #ifndef _CITRUS_CSMAPPER_H_ -#define _CITRUS_CSMAPPER_H +#define _CITRUS_CSMAPPER_H_ #define _citrus_csmapper _citrus_mapper #define _citrus_csmapper_close _citrus_mapper_close diff --git a/lib/libc/iconv/citrus_db_factory.c b/lib/libc/iconv/citrus_db_factory.c index 9a3edf2..e9823ab 100644 --- a/lib/libc/iconv/citrus_db_factory.c +++ b/lib/libc/iconv/citrus_db_factory.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_db_factory.c,v 1.9 2008/02/09 14:56:20 junyoung Exp $ */ +/* $NetBSD: citrus_db_factory.c,v 1.10 2013/09/14 13:05:51 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -228,15 +228,6 @@ put8(struct _region *r, size_t *rofs, uint8_t val) } static __inline void -put16(struct _region *r, size_t *rofs, uint16_t val) -{ - - val = htons(val); - memcpy(_region_offset(r, *rofs), &val, 2); - *rofs += 2; -} - -static __inline void put32(struct _region *r, size_t *rofs, uint32_t val) { diff --git a/lib/libc/iconv/citrus_iconv.c b/lib/libc/iconv/citrus_iconv.c index e4bd24f..df2ed73 100644 --- a/lib/libc/iconv/citrus_iconv.c +++ b/lib/libc/iconv/citrus_iconv.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_iconv.c,v 1.7 2008/07/25 14:05:25 christos Exp $ */ +/* $NetBSD: citrus_iconv.c,v 1.10 2011/11/19 18:34:21 tnozaki Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -169,8 +169,10 @@ open_shared(struct _citrus_iconv_shared * __restrict * __restrict rci, ci->ci_ops->io_uninit_shared == NULL || ci->ci_ops->io_init_context == NULL || ci->ci_ops->io_uninit_context == NULL || - ci->ci_ops->io_convert == NULL) + ci->ci_ops->io_convert == NULL) { + ret = EINVAL; goto err; + } /* initialize the converter */ ret = (*ci->ci_ops->io_init_shared)(ci, src, dst); diff --git a/lib/libc/iconv/citrus_iconv_local.h b/lib/libc/iconv/citrus_iconv_local.h index e673c9a..12d2fa3 100644 --- a/lib/libc/iconv/citrus_iconv_local.h +++ b/lib/libc/iconv/citrus_iconv_local.h @@ -99,6 +99,7 @@ struct _citrus_iconv_shared { char *ci_convname; bool ci_discard_ilseq; struct iconv_hooks *ci_hooks; + bool ci_ilseq_invalid; }; struct _citrus_iconv { diff --git a/lib/libc/iconv/citrus_lookup.c b/lib/libc/iconv/citrus_lookup.c index 09b1298..bb9934a 100644 --- a/lib/libc/iconv/citrus_lookup.c +++ b/lib/libc/iconv/citrus_lookup.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_lookup.c,v 1.6 2009/02/03 04:58:38 lukem Exp $ */ +/* $NetBSD: citrus_lookup.c,v 1.7 2012/05/04 16:45:05 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, diff --git a/lib/libc/iconv/citrus_mapper.c b/lib/libc/iconv/citrus_mapper.c index b1ee8fb..ea65ae9 100644 --- a/lib/libc/iconv/citrus_mapper.c +++ b/lib/libc/iconv/citrus_mapper.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_mapper.c,v 1.7 2008/07/25 14:05:25 christos Exp $ */ +/* $NetBSD: citrus_mapper.c,v 1.10 2012/06/08 07:49:42 martin Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -244,8 +244,10 @@ mapper_open(struct _citrus_mapper_area *__restrict ma, if (!cm->cm_ops->mo_init || !cm->cm_ops->mo_uninit || !cm->cm_ops->mo_convert || - !cm->cm_ops->mo_init_state) + !cm->cm_ops->mo_init_state) { + ret = EINVAL; goto err; + } /* allocate traits structure */ cm->cm_traits = malloc(sizeof(*cm->cm_traits)); @@ -381,7 +383,9 @@ _citrus_mapper_close(struct _citrus_mapper *cm) _CITRUS_HASH_REMOVE(cm, cm_entry); free(cm->cm_key); } + UNLOCK(&cm_lock); mapper_close(cm); + return; quit: UNLOCK(&cm_lock); } diff --git a/lib/libc/iconv/citrus_memstream.c b/lib/libc/iconv/citrus_memstream.c index d7ad4fd..f99a19d 100644 --- a/lib/libc/iconv/citrus_memstream.c +++ b/lib/libc/iconv/citrus_memstream.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_memstream.c,v 1.4 2009/02/03 05:02:12 lukem Exp $ */ +/* $NetBSD: citrus_memstream.c,v 1.5 2012/03/13 21:13:31 christos Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -44,8 +44,7 @@ _citrus_memory_stream_getln(struct _citrus_memory_stream * __restrict ms, size_t * __restrict rlen) { const uint8_t *h, *p; - size_t ret; - int i; + size_t i, ret; if (ms->ms_pos>=_region_size(&ms->ms_region)) return (NULL); diff --git a/lib/libc/iconv/citrus_mmap.c b/lib/libc/iconv/citrus_mmap.c index 2aaf73c..f8e96d1 100644 --- a/lib/libc/iconv/citrus_mmap.c +++ b/lib/libc/iconv/citrus_mmap.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_mmap.c,v 1.3 2005/01/19 00:52:37 mycroft Exp $ */ +/* $NetBSD: citrus_mmap.c,v 1.4 2011/10/15 23:00:01 christos Exp $ */ /*- * Copyright (c)2003 Citrus Project, diff --git a/lib/libc/iconv/citrus_prop.c b/lib/libc/iconv/citrus_prop.c index c2d4829..28318de 100644 --- a/lib/libc/iconv/citrus_prop.c +++ b/lib/libc/iconv/citrus_prop.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_prop.c,v 1.3 2006/11/22 23:47:21 tnozaki Exp $ */ +/* $NetBSD: citrus_prop.c,v 1.4 2011/03/30 08:22:01 jruoho Exp $ */ /*- * Copyright (c)2006 Citrus Project, @@ -339,7 +339,7 @@ name_found: static int _citrus_prop_parse_element(struct _memstream * __restrict ms, - const _citrus_prop_hint_t * __restrict hints, void ** __restrict context) + const _citrus_prop_hint_t * __restrict hints, void * __restrict context) { int ch, errnum; #define _CITRUS_PROP_HINT_NAME_LEN_MAX 255 @@ -435,8 +435,7 @@ _citrus_prop_parse_variable(const _citrus_prop_hint_t * __restrict hints, if (ch == EOF || ch == '\0') break; _memstream_ungetc(&ms, ch); - errnum = _citrus_prop_parse_element( - &ms, hints, (void ** __restrict)context); + errnum = _citrus_prop_parse_element(&ms, hints, context); if (errnum != 0) return (errnum); } diff --git a/lib/libc/iconv/citrus_prop.h b/lib/libc/iconv/citrus_prop.h index db087a4..48fc066 100644 --- a/lib/libc/iconv/citrus_prop.h +++ b/lib/libc/iconv/citrus_prop.h @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_prop.h,v 1.3 2006/11/23 13:59:03 tnozaki Exp $ */ +/* $NetBSD: citrus_prop.h,v 1.5 2011/05/23 14:52:32 joerg Exp $ */ /*- * Copyright (c)2006 Citrus Project, @@ -42,7 +42,7 @@ typedef struct _citrus_prop_hint_t _citrus_prop_hint_t; #define _CITRUS_PROP_CB0_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_); \ + (void * __restrict, const char *, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; @@ -52,7 +52,7 @@ _CITRUS_PROP_CB0_T(str, const char *) #define _CITRUS_PROP_CB1_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_, _type_); \ + (void * __restrict, const char *, _type_, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; @@ -82,7 +82,7 @@ struct _citrus_prop_hint_t { #define _CITRUS_PROP_HINT_NUM(name, cb) \ { name, _CITRUS_PROP_NUM, { .num = { cb } } } #define _CITRUS_PROP_HINT_END \ - { NULL, _CITRUS_PROP_NUM, { .num = { 0 } } } + { .name = NULL } __BEGIN_DECLS int _citrus_prop_parse_variable(const _citrus_prop_hint_t * __restrict, diff --git a/lib/libc/iconv/citrus_stdenc.c b/lib/libc/iconv/citrus_stdenc.c index b6562f8..cef530e 100644 --- a/lib/libc/iconv/citrus_stdenc.c +++ b/lib/libc/iconv/citrus_stdenc.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_stdenc.c,v 1.3 2005/10/29 18:02:04 tshiozak Exp $ */ +/* $NetBSD: citrus_stdenc.c,v 1.4 2011/11/19 18:39:58 tnozaki Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -102,8 +102,10 @@ _citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce, ce->ce_ops->eo_cstomb == NULL || ce->ce_ops->eo_mbtowc == NULL || ce->ce_ops->eo_wctomb == NULL || - ce->ce_ops->eo_get_state_desc == NULL) + ce->ce_ops->eo_get_state_desc == NULL) { + ret = EINVAL; goto bad; + } /* allocate traits */ ce->ce_traits = malloc(sizeof(*ce->ce_traits)); diff --git a/lib/libkse/thread/thr_attr_get_np.c b/lib/libc/iconv/iconv-internal.h index fea3565..9a6b3d9 100644 --- a/lib/libkse/thread/thr_attr_get_np.c +++ b/lib/libc/iconv/iconv-internal.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> +/*- + * Copyright (c) 2013 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,32 +26,20 @@ * $FreeBSD$ */ -#include "namespace.h" -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_get_np, pthread_attr_get_np); - -int -_pthread_attr_get_np(pthread_t pid, pthread_attr_t *dst) -{ - struct pthread *curthread; - struct pthread_attr attr; - int ret; - - if (pid == NULL || dst == NULL || *dst == NULL) - return (EINVAL); - - curthread = _get_curthread(); - if ((ret = _thr_ref_add(curthread, pid, /*include dead*/0)) != 0) - return (ret); - attr = pid->attr; - _thr_ref_delete(curthread, pid); - memcpy(*dst, &attr, sizeof(struct pthread_attr)); - - return (0); -} +/* + * Interal prototypes for our back-end functions. + */ +size_t __bsd___iconv(iconv_t, const char **, size_t *, char **, + size_t *, __uint32_t, size_t *); +void __bsd___iconv_free_list(char **, size_t); +int __bsd___iconv_get_list(char ***, size_t *, __iconv_bool); +size_t __bsd_iconv(iconv_t, const char ** __restrict, + size_t * __restrict, char ** __restrict, + size_t * __restrict); +const char *__bsd_iconv_canonicalize(const char *); +int __bsd_iconv_close(iconv_t); +iconv_t __bsd_iconv_open(const char *, const char *); +int __bsd_iconv_open_into(const char *, const char *, iconv_allocation_t *); +void __bsd_iconv_set_relocation_prefix(const char *, const char *); +int __bsd_iconvctl(iconv_t, int, void *); +void __bsd_iconvlist(int (*) (unsigned int, const char * const *, void *), void *); diff --git a/lib/libc/iconv/iconv.c b/lib/libc/iconv/iconv.c index f388e8b..d13c1df 100644 --- a/lib/libc/iconv/iconv.c +++ b/lib/libc/iconv/iconv.c @@ -1,9 +1,5 @@ -/* $FreeBSD$ */ -/* $NetBSD: iconv.c,v 1.11 2009/03/03 16:22:33 explorer Exp $ */ - /*- - * Copyright (c) 2003 Citrus Project, - * Copyright (c) 2009, 2010 Gabor Kovesdan <gabor@FreeBSD.org>, + * Copyright (c) 2013 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,302 +22,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <sys/cdefs.h> -#include <sys/queue.h> #include <sys/types.h> - -#include <assert.h> -#include <errno.h> #include <iconv.h> -#include <limits.h> -#include <paths.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include "citrus_types.h" -#include "citrus_module.h" -#include "citrus_esdb.h" -#include "citrus_hash.h" -#include "citrus_iconv.h" - -#include <_libiconv_compat.h> -#ifdef __LIBICONV_COMPAT -__weak_reference(iconv, libiconv); -__weak_reference(iconv_open, libiconv_open); -__weak_reference(iconv_open_into, libiconv_open_into); -__weak_reference(iconv_close, libiconv_close); -__weak_reference(iconvlist, libiconvlist); -__weak_reference(iconvctl, libiconvctl); -__weak_reference(iconv_set_relocation_prefix, libiconv_set_relocation_prefix); -__weak_reference(_iconv_version, _libiconv_version); -#endif - -#define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1) - -int _iconv_version = _ICONV_VERSION; - -iconv_t _iconv_open(const char *out, const char *in, - struct _citrus_iconv *prealloc); - -iconv_t -_iconv_open(const char *out, const char *in, struct _citrus_iconv *handle) -{ - const char *out_slashes; - char *out_noslashes; - int ret; - - /* - * Remove anything following a //, as these are options (like - * //ignore, //translate, etc) and we just don't handle them. - * This is for compatibility with software that uses these - * blindly. - */ - out_slashes = strstr(out, "//"); - if (out_slashes != NULL) { - out_noslashes = strndup(out, out_slashes - out); - if (out_noslashes == NULL) { - errno = ENOMEM; - return ((iconv_t)-1); - } - ret = _citrus_iconv_open(&handle, in, out_noslashes); - free(out_noslashes); - } else { - ret = _citrus_iconv_open(&handle, in, out); - } - - if (ret) { - errno = ret == ENOENT ? EINVAL : ret; - return ((iconv_t)-1); - } - - handle->cv_shared->ci_discard_ilseq = strcasestr(out, "//IGNORE"); - handle->cv_shared->ci_hooks = NULL; - - return ((iconv_t)(void *)handle); -} - -iconv_t -iconv_open(const char *out, const char *in) -{ - - return (_iconv_open(out, in, NULL)); -} - -int -iconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr) -{ - struct _citrus_iconv *handle; - - handle = (struct _citrus_iconv *)ptr; - return ((_iconv_open(out, in, handle) == (iconv_t)-1) ? -1 : 0); -} - -int -iconv_close(iconv_t handle) -{ - - if (ISBADF(handle)) { - errno = EBADF; - return (-1); - } - - _citrus_iconv_close((struct _citrus_iconv *)(void *)handle); - - return (0); -} +#include "iconv-internal.h" size_t -iconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout) -{ - size_t ret; - int err; - - if (ISBADF(handle)) { - errno = EBADF; - return ((size_t)-1); - } - - err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, - in, szin, out, szout, 0, &ret); - if (err) { - errno = err; - ret = (size_t)-1; - } - - return (ret); -} - -size_t -__iconv(iconv_t handle, const char **in, size_t *szin, char **out, - size_t *szout, uint32_t flags, size_t *invalids) -{ - size_t ret; - int err; - - if (ISBADF(handle)) { - errno = EBADF; - return ((size_t)-1); - } - - err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, - in, szin, out, szout, flags, &ret); - if (invalids) - *invalids = ret; - if (err) { - errno = err; - ret = (size_t)-1; - } - - return (ret); -} - -int -__iconv_get_list(char ***rlist, size_t *rsz, bool sorted) -{ - int ret; - - ret = _citrus_esdb_get_list(rlist, rsz, sorted); - if (ret) { - errno = ret; - return (-1); - } - - return (0); -} - -void -__iconv_free_list(char **list, size_t sz) -{ - - _citrus_esdb_free_list(list, sz); -} - -/* - * GNU-compatibile non-standard interfaces. - */ -static int -qsort_helper(const void *first, const void *second) -{ - const char * const *s1; - const char * const *s2; - - s1 = first; - s2 = second; - return (strcmp(*s1, *s2)); -} - -void -iconvlist(int (*do_one) (unsigned int, const char * const *, - void *), void *data) +iconv(iconv_t a, const char ** __restrict b, + size_t * __restrict c, char ** __restrict d, + size_t * __restrict e) { - char **list, **names; - const char * const *np; - char *curitem, *curkey, *slashpos; - size_t sz; - unsigned int i, j; - - i = 0; - - if (__iconv_get_list(&list, &sz, true)) - list = NULL; - qsort((void *)list, sz, sizeof(char *), qsort_helper); - while (i < sz) { - j = 0; - slashpos = strchr(list[i], '/'); - curkey = (char *)malloc(slashpos - list[i] + 2); - names = (char **)malloc(sz * sizeof(char *)); - if ((curkey == NULL) || (names == NULL)) { - __iconv_free_list(list, sz); - return; - } - strlcpy(curkey, list[i], slashpos - list[i] + 1); - names[j++] = strdup(curkey); - for (; (i < sz) && (memcmp(curkey, list[i], strlen(curkey)) == 0); i++) { - slashpos = strchr(list[i], '/'); - curitem = (char *)malloc(strlen(slashpos) + 1); - if (curitem == NULL) { - __iconv_free_list(list, sz); - return; - } - strlcpy(curitem, &slashpos[1], strlen(slashpos) + 1); - if (strcmp(curkey, curitem) == 0) { - continue; - } - names[j++] = strdup(curitem); - } - np = (const char * const *)names; - do_one(j, np, data); - free(names); - } - - __iconv_free_list(list, sz); -} - -__inline const char -*iconv_canonicalize(const char *name) -{ - - return (_citrus_iconv_canonicalize(name)); -} - -int -iconvctl(iconv_t cd, int request, void *argument) -{ - struct _citrus_iconv *cv; - struct iconv_hooks *hooks; - const char *convname; - char src[PATH_MAX], *dst; - int *i; - - cv = (struct _citrus_iconv *)(void *)cd; - hooks = (struct iconv_hooks *)argument; - i = (int *)argument; - - if (ISBADF(cd)) { - errno = EBADF; - return (-1); - } - - switch (request) { - case ICONV_TRIVIALP: - convname = cv->cv_shared->ci_convname; - dst = strchr(convname, '/'); - - strlcpy(src, convname, dst - convname + 1); - dst++; - if ((convname == NULL) || (src == NULL) || (dst == NULL)) - return (-1); - *i = strcmp(src, dst) == 0 ? 1 : 0; - return (0); - case ICONV_GET_TRANSLITERATE: - *i = 1; - return (0); - case ICONV_SET_TRANSLITERATE: - return ((*i == 1) ? 0 : -1); - case ICONV_GET_DISCARD_ILSEQ: - *i = cv->cv_shared->ci_discard_ilseq ? 1 : 0; - return (0); - case ICONV_SET_DISCARD_ILSEQ: - cv->cv_shared->ci_discard_ilseq = *i; - return (0); - case ICONV_SET_HOOKS: - cv->cv_shared->ci_hooks = hooks; - return (0); - case ICONV_SET_FALLBACKS: - errno = EOPNOTSUPP; - return (-1); - default: - errno = EINVAL; - return (-1); - } -} - -void -iconv_set_relocation_prefix(const char *orig_prefix __unused, - const char *curr_prefix __unused) -{ - + return __bsd_iconv(a, b, c, d, e); } diff --git a/lib/libc/iconv/iconv_canonicalize.3 b/lib/libc/iconv/iconv_canonicalize.3 index 3c52ae2..a5d3e77 100644 --- a/lib/libc/iconv/iconv_canonicalize.3 +++ b/lib/libc/iconv/iconv_canonicalize.3 @@ -67,7 +67,7 @@ The .Nm function is a non-standard extension, which appeared in the GNU implementation and was adopted in -.Fx 9 +.Fx 9.0 for compatibility's sake. .Sh AUTHORS This manual page was written by diff --git a/lib/libc/iconv/iconv_canonicalize.c b/lib/libc/iconv/iconv_canonicalize.c new file mode 100644 index 0000000..702a416 --- /dev/null +++ b/lib/libc/iconv/iconv_canonicalize.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +const char * +iconv_canonicalize(const char *a) +{ + return __bsd_iconv_canonicalize(a); +} diff --git a/lib/libelf/elf_fill.c b/lib/libc/iconv/iconv_close.c index 3dae25d..1adbb8c 100644 --- a/lib/libelf/elf_fill.c +++ b/lib/libc/iconv/iconv_close.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Joseph Koshy + * Copyright (c) 2013 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,17 +22,16 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" -void -elf_fill(int fill) +int +iconv_close(iconv_t a) { - LIBELF_PRIVATE(fillchar) = fill; + return __bsd_iconv_close(a); } diff --git a/lib/libc/iconv/iconv_compat.c b/lib/libc/iconv/iconv_compat.c new file mode 100644 index 0000000..dea968f --- /dev/null +++ b/lib/libc/iconv/iconv_compat.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * These are ABI implementations for when the raw iconv_* symbol + * space was exposed via libc.so.7 in its early life. This is + * a transition aide, these wrappers will not normally ever be + * executed except via __sym_compat() references. + */ +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +size_t +__iconv_compat(iconv_t a, const char ** b, size_t * c, char ** d, + size_t * e, __uint32_t f, size_t *g) +{ + return __bsd___iconv(a, b, c, d, e, f, g); +} + +void +__iconv_free_list_compat(char ** a, size_t b) +{ + __bsd___iconv_free_list(a, b); +} + +int +__iconv_get_list_compat(char ***a, size_t *b, __iconv_bool c) +{ + return __bsd___iconv_get_list(a, b, c); +} + +size_t +iconv_compat(iconv_t a, const char ** __restrict b, + size_t * __restrict c, char ** __restrict d, + size_t * __restrict e) +{ + return __bsd_iconv(a, b, c, d, e); +} + +const char * +iconv_canonicalize_compat(const char *a) +{ + return __bsd_iconv_canonicalize(a); +} + +int +iconv_close_compat(iconv_t a) +{ + return __bsd_iconv_close(a); +} + +iconv_t +iconv_open_compat(const char *a, const char *b) +{ + return __bsd_iconv_open(a, b); +} + +int +iconv_open_into_compat(const char *a, const char *b, iconv_allocation_t *c) +{ + return __bsd_iconv_open_into(a, b, c); +} + +void +iconv_set_relocation_prefix_compat(const char *a, const char *b) +{ + return __bsd_iconv_set_relocation_prefix(a, b); +} + +int +iconvctl_compat(iconv_t a, int b, void *c) +{ + return __bsd_iconvctl(a, b, c); +} + +void +iconvlist_compat(int (*a) (unsigned int, const char * const *, void *), void *b) +{ + return __bsd_iconvlist(a, b); +} + +int _iconv_version_compat = 0x0108; /* Magic - not used */ + +__sym_compat(__iconv, __iconv_compat, FBSD_1.2); +__sym_compat(__iconv_free_list, __iconv_free_list_compat, FBSD_1.2); +__sym_compat(__iconv_get_list, __iconv_get_list_compat, FBSD_1.2); +__sym_compat(_iconv_version, _iconv_version_compat, FBSD_1.3); +__sym_compat(iconv, iconv_compat, FBSD_1.3); +__sym_compat(iconv_canonicalize, iconv_canonicalize_compat, FBSD_1.2); +__sym_compat(iconv_close, iconv_close_compat, FBSD_1.3); +__sym_compat(iconv_open, iconv_open_compat, FBSD_1.3); +__sym_compat(iconv_open_into, iconv_open_into_compat, FBSD_1.3); +__sym_compat(iconv_set_relocation_prefix, iconv_set_relocation_prefix_compat, FBSD_1.3); +__sym_compat(iconvctl, iconvctl_compat, FBSD_1.3); +__sym_compat(iconvlist, iconvlist_compat, FBSD_1.3); diff --git a/lib/libc/iconv/iconv_open.c b/lib/libc/iconv/iconv_open.c new file mode 100644 index 0000000..f14925c --- /dev/null +++ b/lib/libc/iconv/iconv_open.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +iconv_t +iconv_open(const char *a, const char *b) +{ + return __bsd_iconv_open(a, b); +} diff --git a/lib/libc/iconv/iconv_open_into.c b/lib/libc/iconv/iconv_open_into.c new file mode 100644 index 0000000..8a1278b --- /dev/null +++ b/lib/libc/iconv/iconv_open_into.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +int +iconv_open_into(const char *a, const char *b, iconv_allocation_t *c) +{ + return __bsd_iconv_open_into(a, b, c); +} diff --git a/lib/libc/iconv/iconv_set_relocation_prefix.c b/lib/libc/iconv/iconv_set_relocation_prefix.c new file mode 100644 index 0000000..7615c94 --- /dev/null +++ b/lib/libc/iconv/iconv_set_relocation_prefix.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +void +iconv_set_relocation_prefix(const char *a, const char *b) +{ + return __bsd_iconv_set_relocation_prefix(a, b); +} diff --git a/lib/libc/iconv/iconvctl.3 b/lib/libc/iconv/iconvctl.3 index f012157..5728ad3 100644 --- a/lib/libc/iconv/iconvctl.3 +++ b/lib/libc/iconv/iconvctl.3 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 7, 2009 +.Dd November 25, 2009 .Dt ICONVCTL 3 .Os .Sh NAME @@ -110,6 +110,31 @@ variable, which is passed to via .Fa argument by its address. +.It ICONV_GET_ILSEQ_INVALID +Determines if a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +The answer is stored in +.Fa argument , +which is of +.Ft int * . +It will be set to 1 if this feature is enabled or set to 0 otherwise. +.It ICONV_SET_ILSEQ_INVALID +Sets whether a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +If +.Fa argument , +which is of +.Ft int * +is set to 1 it will be enabled, +and if +.Fa argument +is set to 0 it will be disabled. .El .\" XXX: fallbacks are unimplemented and trying to set them will always .\" return EOPNOTSUPP but definitions are provided for source-level @@ -150,7 +175,7 @@ The .Nm facility is a non-standard extension, which appeared in the GNU implementation and was adopted in -.Fx 9 +.Fx 9.0 for compatibility's sake. .Sh AUTHORS This manual page was written by diff --git a/lib/libelf/gelf_getclass.c b/lib/libc/iconv/iconvctl.c index badd8ff..50c108c 100644 --- a/lib/libelf/gelf_getclass.c +++ b/lib/libc/iconv/iconvctl.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Joseph Koshy + * Copyright (c) 2013 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,17 +22,16 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> - -#include "_libelf.h" +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" int -gelf_getclass(Elf *e) +iconvctl(iconv_t a, int b, void *c) { - return (e != NULL ? e->e_class : ELFCLASSNONE); + return __bsd_iconvctl(a, b, c); } diff --git a/lib/libc/iconv/iconvlist.3 b/lib/libc/iconv/iconvlist.3 index d474d9b..ff9ea6b 100644 --- a/lib/libc/iconv/iconvlist.3 +++ b/lib/libc/iconv/iconvlist.3 @@ -86,7 +86,7 @@ The .Nm function is a non-standard extension, which appeared in the GNU implementation and was adopted in -.Fx 9 +.Fx 9.0 for compatibility's sake. .Sh AUTHORS This manual page was written by diff --git a/lib/libc/iconv/iconvlist.c b/lib/libc/iconv/iconvlist.c new file mode 100644 index 0000000..418b4a7 --- /dev/null +++ b/lib/libc/iconv/iconvlist.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <iconv.h> +#include "iconv-internal.h" + +void +iconvlist(int (*a) (unsigned int, const char * const *, void *), void *b) +{ + return __bsd_iconvlist(a, b); +} diff --git a/lib/libkse/arch/powerpc/powerpc/enter_uts.S b/lib/libc/include/block_abi.h index 7cc4d7f..b0d6e57 100644 --- a/lib/libkse/arch/powerpc/powerpc/enter_uts.S +++ b/lib/libc/include/block_abi.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2004 Peter Grehan. +/*- + * Copyright (c) 2014 David T Chisnall * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,19 +22,42 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -/* - * _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - * long stacksz); - * - * Call (*uts)(km) on the requested stack. This function doesn't - * return. The km parameter stays in %r3. +#ifdef __BLOCKS__ +/** + * Declares a block variable. This macro is defined in the trivial way for + * compilers that support blocks and exposing the ABI in the source for other + * compilers. + */ +#define DECLARE_BLOCK(retTy, name, argTys, ...)\ + retTy(^name)(argTys, ## __VA_ARGS__) +/** + * Calls a block variable. This macro is defined in the trivial way for + * compilers that support blocks and exposing the ABI in the source for other + * compilers. + */ +#define CALL_BLOCK(name, ...) name(__VA_ARGS__) +#else // !__BLOCKS__ +#define DECLARE_BLOCK(retTy, name, argTys, ...)\ + struct {\ + void *isa;\ + int flags;\ + int reserved;\ + retTy (*invoke)(void *, ...);\ + } *name +#define CALL_BLOCK(name, ...) (name)->invoke(name, __VA_ARGS__) +#endif // __BLOCKS__ +/** + * Returns the pointer to the block-invoke function. This is used for passing + * blocks to functions that want a function pointer and a data pointer. */ -ENTRY(_ppc32_enter_uts) - add %r1,%r5,%r6 /* new stack = stack + stacksz */ - mtlr %r4 /* link register = uts */ - blrl /* (*uts)(km) */ +#define GET_BLOCK_FUNCTION(x) \ + (((struct {\ + void *isa;\ + int flags;\ + int reserved;\ + void (*invoke)(void *, ...);\ + }*)(void*)x)->invoke) diff --git a/lib/libc/include/port_before.h b/lib/libc/include/port_before.h index 304dd66..9e7525b 100644 --- a/lib/libc/include/port_before.h +++ b/lib/libc/include/port_before.h @@ -5,7 +5,7 @@ #define _LIBC 1 #define DO_PTHREADS 1 -#define USE_KQUEUE 1 +#define USE_POLL 1 #define ISC_SOCKLEN_T socklen_t #define ISC_FORMAT_PRINTF(fmt, args) \ diff --git a/lib/libc/inet/Makefile.inc b/lib/libc/inet/Makefile.inc index 0e6cc39..c957b11 100644 --- a/lib/libc/inet/Makefile.inc +++ b/lib/libc/inet/Makefile.inc @@ -1,11 +1,11 @@ # $FreeBSD$ # inet sources -.PATH: ${.CURDIR}/inet +.PATH: ${LIBC_SRCTOP}/inet SRCS+= inet_addr.c inet_cidr_ntop.c inet_cidr_pton.c inet_lnaof.c \ inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \ inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ inet_pton.c nsap_addr.c -SYM_MAPS+= ${.CURDIR}/inet/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/inet/Symbol.map diff --git a/lib/libc/inet/inet_ntop.c b/lib/libc/inet/inet_ntop.c index 6d21027..d57e6ab 100644 --- a/lib/libc/inet/inet_ntop.c +++ b/lib/libc/inet/inet_ntop.c @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size); static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size); -/* char * +/* const char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: @@ -169,8 +169,10 @@ inet_ntop6(const u_char *src, char *dst, socklen_t size) if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) { + errno = ENOSPC; return (NULL); + } tp += strlen(tp); break; } diff --git a/lib/libc/isc/Makefile.inc b/lib/libc/isc/Makefile.inc index 48c90f7..aa63ecd 100644 --- a/lib/libc/isc/Makefile.inc +++ b/lib/libc/isc/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ # isc sources -.PATH: ${.CURDIR}/isc +.PATH: ${LIBC_SRCTOP}/isc SRCS+= ev_streams.c ev_timers.c diff --git a/lib/libc/libc.ldscript b/lib/libc/libc.ldscript index a5c8a27..02e4d96 100644 --- a/lib/libc/libc.ldscript +++ b/lib/libc/libc.ldscript @@ -1,2 +1,2 @@ /* $FreeBSD$ */ -GROUP ( @@SHLIB@@ @@LIBDIR@@/libssp_nonshared.a ) +GROUP ( @@SHLIB@@ @@LIBDIR@@/libc_nonshared.a @@LIBDIR@@/libssp_nonshared.a ) diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc index c2f2f4e..d28355b 100644 --- a/lib/libc/locale/Makefile.inc +++ b/lib/libc/locale/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # locale sources -.PATH: ${.CURDIR}/${LIBC_ARCH}/locale ${.CURDIR}/locale +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/locale ${LIBC_SRCTOP}/locale SRCS+= ascii.c big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c \ gb18030.c gb2312.c gbk.c ctype.c isctype.c iswctype.c \ @@ -29,7 +29,7 @@ SRCS+= c16rtomb_iconv.c c32rtomb_iconv.c mbrtoc16_iconv.c mbrtoc32_iconv.c SRCS+= c16rtomb.c c32rtomb.c mbrtoc16.c mbrtoc32.c .endif -SYM_MAPS+=${.CURDIR}/locale/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/locale/Symbol.map MAN+= btowc.3 \ ctype_l.3 \ diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c index 49e6f6e..0a0943f 100644 --- a/lib/libc/locale/setrunelocale.c +++ b/lib/libc/locale/setrunelocale.c @@ -202,6 +202,8 @@ __set_thread_rune_locale(locale_t loc) if (loc == NULL) { _ThreadRuneLocale = &_DefaultRuneLocale; + } else if (loc == LC_GLOBAL_LOCALE) { + _ThreadRuneLocale = 0; } else { _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes; } diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c index e114bac..f9b7db1 100644 --- a/lib/libc/locale/xlocale.c +++ b/lib/libc/locale/xlocale.c @@ -154,23 +154,24 @@ __get_locale(void) static void set_thread_locale(locale_t loc) { + locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc; _once(&once_control, init_key); - if (NULL != loc) { - xlocale_retain((struct xlocale_refcounted*)loc); + if (NULL != l) { + xlocale_retain((struct xlocale_refcounted*)l); } locale_t old = pthread_getspecific(locale_info_key); - if ((NULL != old) && (loc != old)) { + if ((NULL != old) && (l != old)) { xlocale_release((struct xlocale_refcounted*)old); } if (fake_tls) { - thread_local_locale = loc; + thread_local_locale = l; } else { - pthread_setspecific(locale_info_key, loc); + pthread_setspecific(locale_info_key, l); } #ifndef __NO_TLS - __thread_locale = loc; + __thread_locale = l; __set_thread_rune_locale(loc); #endif } @@ -361,9 +362,6 @@ locale_t uselocale(locale_t loc) { locale_t old = get_thread_locale(); if (NULL != loc) { - if (LC_GLOBAL_LOCALE == loc) { - loc = NULL; - } set_thread_locale(loc); } return (old ? old : LC_GLOBAL_LOCALE); diff --git a/lib/libc/mips/Makefile.inc b/lib/libc/mips/Makefile.inc index a02ca01..4ec20d4 100644 --- a/lib/libc/mips/Makefile.inc +++ b/lib/libc/mips/Makefile.inc @@ -4,4 +4,4 @@ CFLAGS+=-DSOFTFLOAT MDSRCS+= machdep_ldisd.c -SYM_MAPS+= ${.CURDIR}/mips/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map diff --git a/lib/libc/mips/sys/Makefile.inc b/lib/libc/mips/sys/Makefile.inc index fc11349..c754f36 100644 --- a/lib/libc/mips/sys/Makefile.inc +++ b/lib/libc/mips/sys/Makefile.inc @@ -10,6 +10,6 @@ NOASM= break.o exit.o ftruncate.o getlogin.o lseek.o mmap.o \ openbsd_poll.o pread.o pwrite.o sstk.o truncate.o vfork.o yield.o PSEUDO= _exit.o _getlogin.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/nameser/Makefile.inc b/lib/libc/nameser/Makefile.inc index 05b4f55..cbb2122 100644 --- a/lib/libc/nameser/Makefile.inc +++ b/lib/libc/nameser/Makefile.inc @@ -1,8 +1,8 @@ # $FreeBSD$ # nameser sources -.PATH: ${.CURDIR}/nameser +.PATH: ${LIBC_SRCTOP}/nameser SRCS+= ns_name.c ns_netint.c ns_parse.c ns_print.c ns_samedomain.c ns_ttl.c -SYM_MAPS+= ${.CURDIR}/nameser/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/nameser/Symbol.map diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc index e61021b..59cbdea 100644 --- a/lib/libc/net/Makefile.inc +++ b/lib/libc/net/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # machine-independent net sources -.PATH: ${.CURDIR}/net +.PATH: ${LIBC_SRCTOP}/net SRCS+= base64.c ether_addr.c eui64.c \ gai_strerror.c getaddrinfo.c \ @@ -20,7 +20,7 @@ SRCS+= base64.c ether_addr.c eui64.c \ SRCS+= nscache.c nscachedcli.c .endif -SYM_MAPS+=${.CURDIR}/net/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/net/Symbol.map .if ${MK_INET6_SUPPORT} != "no" CFLAGS+=-DINET6 @@ -29,7 +29,7 @@ CFLAGS+=-DINET6 CFLAGS+=-I${.OBJDIR} # name6.c refers res_private.h -CFLAGS+=-I${.CURDIR}/resolv +CFLAGS+=-I${LIBC_SRCTOP}/resolv YFLAGS+=-p_nsyy LFLAGS+=-P_nsyy diff --git a/lib/libc/net/ether_addr.c b/lib/libc/net/ether_addr.c index 5d72606..19d10ac 100644 --- a/lib/libc/net/ether_addr.c +++ b/lib/libc/net/ether_addr.c @@ -72,11 +72,13 @@ ether_line(const char *l, struct ether_addr *e, char *hostname) i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], &o[3], &o[4], &o[5], hostname); - if (i != 7) - return (i); - for (i=0; i<6; i++) - e->octet[i] = o[i]; - return (0); + if (i == 7) { + for (i = 0; i < 6; i++) + e->octet[i] = o[i]; + return (0); + } else { + return (-1); + } } /* diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 495ebc1..00ab796 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -170,12 +170,14 @@ static const struct explore explore[] = { { PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 }, { PF_INET6, SOCK_STREAM, IPPROTO_SCTP, 0x03 }, { PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 }, + { PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 }, { PF_INET6, SOCK_RAW, ANY, 0x05 }, #endif { PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07 }, { PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07 }, { PF_INET, SOCK_STREAM, IPPROTO_SCTP, 0x03 }, { PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 }, + { PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 }, { PF_INET, SOCK_RAW, ANY, 0x05 }, { -1, 0, 0, 0 }, }; @@ -1477,6 +1479,9 @@ get_port(struct addrinfo *ai, const char *servname, int matchonly) case IPPROTO_SCTP: proto = "sctp"; break; + case IPPROTO_UDPLITE: + proto = "udplite"; + break; default: proto = NULL; break; diff --git a/lib/libc/net/ip6opt.c b/lib/libc/net/ip6opt.c index 003c625..a467758 100644 --- a/lib/libc/net/ip6opt.c +++ b/lib/libc/net/ip6opt.c @@ -45,6 +45,18 @@ __FBSDID("$FreeBSD$"); static int ip6optlen(u_int8_t *opt, u_int8_t *lim); static void inet6_insert_padopt(u_char *p, int len); +#ifndef IPV6_2292HOPOPTS +#define IPV6_2292HOPOPTS 22 +#endif +#ifndef IPV6_2292DSTOPTS +#define IPV6_2292DSTOPTS 23 +#endif + +#define is_ipv6_hopopts(x) \ + ((x) == IPV6_HOPOPTS || (x) == IPV6_2292HOPOPTS) +#define is_ipv6_dstopts(x) \ + ((x) == IPV6_DSTOPTS || (x) == IPV6_2292DSTOPTS) + /* * This function returns the number of bytes required to hold an option * when it is stored as ancillary data, including the cmsghdr structure @@ -72,9 +84,9 @@ inet6_option_init(void *bp, struct cmsghdr **cmsgp, int type) struct cmsghdr *ch = (struct cmsghdr *)bp; /* argument validation */ - if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS) + if (!is_ipv6_hopopts(type) && !is_ipv6_dstopts(type)) return(-1); - + ch->cmsg_level = IPPROTO_IPV6; ch->cmsg_type = type; ch->cmsg_len = CMSG_LEN(0); @@ -234,8 +246,8 @@ inet6_option_next(const struct cmsghdr *cmsg, u_int8_t **tptrp) u_int8_t *lim; if (cmsg->cmsg_level != IPPROTO_IPV6 || - (cmsg->cmsg_type != IPV6_HOPOPTS && - cmsg->cmsg_type != IPV6_DSTOPTS)) + (!is_ipv6_hopopts(cmsg->cmsg_type) && + !is_ipv6_dstopts(cmsg->cmsg_type))) return(-1); /* message length validation */ @@ -290,8 +302,8 @@ inet6_option_find(const struct cmsghdr *cmsg, u_int8_t **tptrp, int type) u_int8_t *optp, *lim; if (cmsg->cmsg_level != IPPROTO_IPV6 || - (cmsg->cmsg_type != IPV6_HOPOPTS && - cmsg->cmsg_type != IPV6_DSTOPTS)) + (!is_ipv6_hopopts(cmsg->cmsg_type) && + !is_ipv6_dstopts(cmsg->cmsg_type))) return(-1); /* message length validation */ @@ -381,11 +393,8 @@ inet6_opt_init(void *extbuf, socklen_t extlen) { struct ip6_ext *ext = (struct ip6_ext *)extbuf; - if (extlen < 0 || (extlen % 8)) - return(-1); - if (ext) { - if (extlen == 0) + if (extlen <= 0 || (extlen % 8)) return(-1); ext->ip6e_len = (extlen >> 3) - 1; } diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c index fda9676..a7da95c 100644 --- a/lib/libc/net/sctp_sys_calls.c +++ b/lib/libc/net/sctp_sys_calls.c @@ -233,19 +233,11 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags) break; default: /* Invalid address family specified. */ - errno = EINVAL; + errno = EAFNOSUPPORT; return (-1); } sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); } - /* - * Now if there was a port mentioned, assure that the first address - * has that port to make sure it fails or succeeds correctly. - */ - if (sport) { - sin = (struct sockaddr_in *)sa; - sin->sin_port = sport; - } argsz = sizeof(struct sctp_getaddresses) + sizeof(struct sockaddr_storage); if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) { @@ -257,6 +249,23 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags) memset(gaddrs, 0, argsz); gaddrs->sget_assoc_id = 0; memcpy(gaddrs->addr, sa, sa->sa_len); + /* + * Now, if there was a port mentioned, assure that the first + * address has that port to make sure it fails or succeeds + * correctly. + */ + if ((i == 0) && (sport != 0)) { + switch (gaddrs->addr->sa_family) { + case AF_INET: + sin = (struct sockaddr_in *)gaddrs->addr; + sin->sin_port = sport; + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)gaddrs->addr; + sin6->sin6_port = sport; + break; + } + } if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs, (socklen_t) argsz) != 0) { free(gaddrs); diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc index 962d16b..2734e51 100644 --- a/lib/libc/nls/Makefile.inc +++ b/lib/libc/nls/Makefile.inc @@ -1,11 +1,11 @@ # from $NetBSD: Makefile.inc,v 1.7 1995/02/27 13:06:20 cgd Exp $ # $FreeBSD$ -.PATH: ${.CURDIR}/nls +.PATH: ${LIBC_SRCTOP}/nls SRCS+= msgcat.c -SYM_MAPS+=${.CURDIR}/nls/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/nls/Symbol.map MAN+= catclose.3 catgets.3 catopen.3 diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index c9d3ba5..2cc4158 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -1,11 +1,11 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/posix1e +.PATH: ${LIBC_SRCTOP}/posix1e CFLAGS+=-D_ACL_PRIVATE # Copy kern/subr_acl_nfs4.c to the libc object directory. -subr_acl_nfs4.c: ${.CURDIR}/../../sys/kern/subr_acl_nfs4.c +subr_acl_nfs4.c: ${LIBC_SRCTOP}/../../sys/kern/subr_acl_nfs4.c cat ${.ALLSRC} > ${.TARGET} SRCS+= acl_branding.c \ @@ -37,7 +37,7 @@ SRCS+= acl_branding.c \ mac_set.c \ subr_acl_nfs4.c -SYM_MAPS+=${.CURDIR}/posix1e/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/posix1e/Symbol.map MAN+= acl.3 \ acl_add_flag_np.3 \ diff --git a/lib/libc/posix1e/acl.3 b/lib/libc/posix1e/acl.3 index 717df67..a39b736 100644 --- a/lib/libc/posix1e/acl.3 +++ b/lib/libc/posix1e/acl.3 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 25, 2009 +.Dd November 12, 2013 .Dt ACL 3 .Os .Sh NAME @@ -131,6 +131,10 @@ This function is described in .Xr acl_from_text 3 , and may be used to convert a text-form ACL into working ACL state, if the ACL has POSIX.1e or NFSv4 semantics. +.It Fn acl_get_brand_np +This function is described in +.Xr acl_get_brand_np 3 +and may be used to determine whether the ACL has POSIX.1e or NFSv4 semantics. .It Fn acl_get_entry This function is described in .Xr acl_get_entry 3 , @@ -202,7 +206,7 @@ This function is described in .Xr acl_set_tag_type 3 , and may be used to set the tag type of an ACL. .It Fn acl_strip_np -This function is describe din +This function is described in .Xr acl-strip_np 3 , and may be used to remove extended entries from an ACL. .It Xo @@ -248,6 +252,7 @@ library. .Xr acl_free 3 , .Xr acl_from_text 3 , .Xr acl_get 3 , +.Xr acl_get_brand_np 3 , .Xr acl_get_entry_type_np 3 , .Xr acl_get_flagset_np 3 , .Xr acl_get_permset 3 , diff --git a/lib/libc/posix1e/acl_is_trivial_np.3 b/lib/libc/posix1e/acl_is_trivial_np.3 index a9cd4df..4f5a22c 100644 --- a/lib/libc/posix1e/acl_is_trivial_np.3 +++ b/lib/libc/posix1e/acl_is_trivial_np.3 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 13, 2010 +.Dd November 12, 2013 .Dt ACL_STRIP_NP 3 .Os .Sh NAME @@ -56,9 +56,8 @@ ACL is trivial if it can be fully expressed as a file mode without losing any access rules. For POSIX.1e ACLs, ACL is trivial if it has the three required entries, one for owner, one for owning group, and one for other. -For NFSv4 ACLs, ACL is trivial if is identical to the ACL generated by -.Fn acl_strip_np 3 -from the file mode. +For NFSv4 ACLs, ACL is trivial if it is identical to the ACL generated by +.Fn acl_strip_np 3 . Files that have non-trivial ACL have a plus sign appended after mode bits in "ls -l" output. .Sh RETURN VALUES diff --git a/lib/libc/posix1e/posix1e.3 b/lib/libc/posix1e/posix1e.3 index 84ce2ec..257b6f5 100644 --- a/lib/libc/posix1e/posix1e.3 +++ b/lib/libc/posix1e/posix1e.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 7, 2009 +.Dd April 15, 2014 .Dt POSIX1E 3 .Os .Sh NAME @@ -65,6 +65,10 @@ However, does implement the .Xr libbsm audit API. +It also provides +.Xr capsicum 4 , +a lightweight OS capability and sandbox framework implementing a +hybrid capability system model. .Sh ENVIRONMENT POSIX.1e assigns security attributes to all objects, extending the security functionality described in POSIX.1. @@ -90,7 +94,9 @@ for mandatory access control labels. .Xr acl 3 , .Xr extattr 3 , .Xr libbsm 3 , +.Xr libcapsicum 3 , .Xr mac 3 , +.Xr capsicum 4 , .Xr ffs 7 , .Xr getfmac 8 , .Xr setfmac 8 , diff --git a/lib/libc/powerpc/Makefile.inc b/lib/libc/powerpc/Makefile.inc index 104f80c..f378780 100644 --- a/lib/libc/powerpc/Makefile.inc +++ b/lib/libc/powerpc/Makefile.inc @@ -4,4 +4,4 @@ SRCS+= __vdso_gettc.c # Long double is 64-bits MDSRCS+=machdep_ldisd.c -SYM_MAPS+=${.CURDIR}/powerpc/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/powerpc/Symbol.map diff --git a/lib/libc/powerpc/SYS.h b/lib/libc/powerpc/SYS.h index 0bd793f..f0665c0 100644 --- a/lib/libc/powerpc/SYS.h +++ b/lib/libc/powerpc/SYS.h @@ -36,24 +36,24 @@ #define _SYSCALL(name) \ .text; \ .align 2; \ - li 0,(__CONCAT(SYS_, name)); \ + li 0,(SYS_##name); \ sc #define SYSCALL(name) \ .text; \ .align 2; \ 2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), name); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name));\ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ _SYSCALL(name); \ bso 2b #define PSEUDO(name) \ .text; \ .align 2; \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name));\ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ _SYSCALL(name); \ bnslr; \ b PIC_PLT(CNAME(HIDENAME(cerror))) @@ -62,9 +62,9 @@ ENTRY(__CONCAT(__sys_, name)); \ .text; \ .align 2; \ 2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), name); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name));\ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ _SYSCALL(name); \ bnslr; \ b PIC_PLT(CNAME(HIDENAME(cerror))) diff --git a/lib/libc/powerpc/sys/Makefile.inc b/lib/libc/powerpc/sys/Makefile.inc index 5193cc2..ad98ba1 100644 --- a/lib/libc/powerpc/sys/Makefile.inc +++ b/lib/libc/powerpc/sys/Makefile.inc @@ -6,6 +6,6 @@ MDASM+= brk.S cerror.S exect.S pipe.S ptrace.S sbrk.S setlogin.S NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/powerpc64/Makefile.inc b/lib/libc/powerpc64/Makefile.inc index a30779d..2a080f6 100644 --- a/lib/libc/powerpc64/Makefile.inc +++ b/lib/libc/powerpc64/Makefile.inc @@ -4,4 +4,4 @@ SRCS+= __vdso_gettc.c # Long double is 64-bits MDSRCS+=machdep_ldisd.c -SYM_MAPS+=${.CURDIR}/powerpc64/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/powerpc64/Symbol.map diff --git a/lib/libc/powerpc64/SYS.h b/lib/libc/powerpc64/SYS.h index 8b3281f..486e71b 100644 --- a/lib/libc/powerpc64/SYS.h +++ b/lib/libc/powerpc64/SYS.h @@ -36,7 +36,7 @@ #define _SYSCALL(name) \ .text; \ .align 2; \ - li 0,(__CONCAT(SYS_, name)); \ + li 0,(SYS_##name); \ sc #define SYSCALL(name) \ @@ -51,17 +51,17 @@ ld %r0,16(%r1); \ mtlr %r0; \ blr; \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), name); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name)); \ - _SYSCALL(name); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ bso 2b #define PSEUDO(name) \ .text; \ .align 2; \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name)); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ _SYSCALL(name); \ bnslr; \ mflr %r0; \ @@ -77,9 +77,9 @@ ENTRY(__CONCAT(__sys_, name)); \ #define RSYSCALL(name) \ .text; \ .align 2; \ -ENTRY(__CONCAT(__sys_, name)); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), name); \ - WEAK_REFERENCE(__CONCAT(__sys_, name), __CONCAT(_, name));\ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ _SYSCALL(name); \ bnslr; \ \ diff --git a/lib/libc/powerpc64/sys/Makefile.inc b/lib/libc/powerpc64/sys/Makefile.inc index 5193cc2..ad98ba1 100644 --- a/lib/libc/powerpc64/sys/Makefile.inc +++ b/lib/libc/powerpc64/sys/Makefile.inc @@ -6,6 +6,6 @@ MDASM+= brk.S cerror.S exect.S pipe.S ptrace.S sbrk.S setlogin.S NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/quad/Makefile.inc b/lib/libc/quad/Makefile.inc index 9cef22e..1b1ab60 100644 --- a/lib/libc/quad/Makefile.inc +++ b/lib/libc/quad/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # Quad support, if needed -.PATH: ${.CURDIR}/${LIBC_ARCH}/quad ${.CURDIR}/quad +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/quad ${LIBC_SRCTOP}/quad .if ${LIBC_ARCH} == "i386" @@ -22,4 +22,4 @@ SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \ .endif -SYM_MAPS+=${.CURDIR}/quad/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/quad/Symbol.map diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc index a2e23eb..4595361 100644 --- a/lib/libc/regex/Makefile.inc +++ b/lib/libc/regex/Makefile.inc @@ -2,13 +2,13 @@ # $FreeBSD$ # regex sources -.PATH: ${.CURDIR}/regex +.PATH: ${LIBC_SRCTOP}/regex CFLAGS+=-DPOSIX_MISTAKE SRCS+= regcomp.c regerror.c regexec.c regfree.c -SYM_MAPS+=${.CURDIR}/regex/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/regex/Symbol.map MAN+= regex.3 MAN+= re_format.7 diff --git a/lib/libc/resolv/Makefile.inc b/lib/libc/resolv/Makefile.inc index cd023cf..c77a3ab 100644 --- a/lib/libc/resolv/Makefile.inc +++ b/lib/libc/resolv/Makefile.inc @@ -1,10 +1,10 @@ # $FreeBSD$ # resolv sources -.PATH: ${.CURDIR}/resolv +.PATH: ${LIBC_SRCTOP}/resolv SRCS+= herror.c h_errno.c mtctxres.c res_comp.c res_data.c res_debug.c \ res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c \ res_query.c res_send.c res_state.c res_update.c -SYM_MAPS+= ${.CURDIR}/resolv/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/resolv/Symbol.map diff --git a/lib/libc/resolv/res_send.c b/lib/libc/resolv/res_send.c index 4896fe8..f7c38c5 100644 --- a/lib/libc/resolv/res_send.c +++ b/lib/libc/resolv/res_send.c @@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$"); */ #include "port_before.h" -#ifndef USE_KQUEUE +#if !defined(USE_KQUEUE) && !defined(USE_POLL) #include "fd_setsize.h" #endif @@ -963,7 +963,7 @@ send_dg(res_state statp, timeout.tv_nsec/1000000; pollfd.fd = s; pollfd.events = POLLRDNORM; - n = poll(&pollfd, 1, polltimeout); + n = _poll(&pollfd, 1, polltimeout); #endif /* USE_POLL */ if (n == 0) { diff --git a/lib/libc/rpc/DISCLAIMER b/lib/libc/rpc/DISCLAIMER index 9a3a991..d8dcb7f 100644 --- a/lib/libc/rpc/DISCLAIMER +++ b/lib/libc/rpc/DISCLAIMER @@ -1,31 +1,60 @@ /* $NetBSD: DISCLAIMER,v 1.2 1998/01/09 04:11:51 perry Exp $ */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ diff --git a/lib/libc/rpc/LICENSE b/lib/libc/rpc/LICENSE deleted file mode 100644 index 5f1205c..0000000 --- a/lib/libc/rpc/LICENSE +++ /dev/null @@ -1,335 +0,0 @@ -$FreeBSD$ - -Sun Industry Standards Source License 1.0 - -DEFINITIONS - -1.1. "Commercial Use" means distribution or otherwise -making the Original Code available to a third party. - -1.2. "Contributor Version" means the combination of the -Original Code, and the Modifications made by that particular -Contributor. - -1.3. "Electronic Distribution Mechanism" means a mechanism -generally accepted in the software development community for -the electronic transfer of data. - -1.4. "Executable" means Original Code in any form other -than Source Code. - -1.5. "Initial Developer" means the individual or entity -identified as the Initial Developer in the Source Code -notice required by 2 (Exhibit A) - -1.6. "Larger Work" means a work which combines Original -Code or portions thereof with code not governed by the terms -of this License. - -1.7. "License" means this document. - -1.8. "Licensable" means having the right to grant, to the -maximum extent possible, whether at the time of the initial -grant or subsequently acquired, any and all of the rights -conveyed herein. - -1.9. "Modifications" means any addition to or deletion from -the substance or structure of either the Original Code or -any previous Modifications. A Modification is: - -A. Any addition to or deletion from the contents of a file -containing Original Code or previous Modifications. - -B. Any new file that contains any part of the Original Code -or previous Modifications. . - -1.10. "Original Code" means Source Code of computer -software code which is described in the Source Code notice -required by Exhibit A as Original Code. - -1.11. "Patent Claims" means any patent claims, now owned or -hereafter acquired, including without limitation, method, -process, and apparatus claims, in any patent Licensable by -grantor. - -1.12. "Source Code" means the preferred form of the -Original Code for making modifications to it, including all -modules it contains, plus any associated interface -definition files, or scripts used to control compilation and -installation of an Executable. - -1.13. "Standards" means the standard identified in Exhibit -B or a subsequent version of such standard. - -1.14. "You" or "Your" means an individual or a legal entity -exercising rights under, and complying with all of the terms -of, this License or a future version of this License issued -under Section 6.1. For legal entities, "You" includes any -entity which controls, is controlled by, or is under common -control with You. For purposes of this definition, -"control" means (a) the power, direct or indirect, to cause -the direction or management of such entity, whether by -contract or otherwise, or (b) ownership of more than fifty -percent (50%) of the outstanding shares or beneficial -ownership of such entity. - -2.0 SOURCE CODE LICENSE - -2.1 The Initial Developer Grant: The Initial Developer -hereby grants You a world-wide, royalty-free, non-exclusive -license, subject to third party intellectual property -claims: - -a) under intellectual property rights (other than patent or -trademark) Licensable by Initial Developer to use, -reproduce, modify, display, perform, sub license and -distribute the Original Code (or portions thereof )with or -without Modifications, and/or as part of a Larger Work; and - -b) under Patents Claims infringed by the making, using or -selling of Original Code, to make, have made, use, practice, -sell, and offer for sale, and/or otherwise dispose of the -Original Code (or portions thereof). - -c) the licenses granted in this Section 2.1(a ) and (b) are -effective on the date Initial Developer first distributes -Original Code under the terms of this License. - -d) Notwithstanding Section 2.1(b )above, no patent license -is granted: 1) for code that You delete from the Original -Code; 2) separate from the Original Code; or 3) for -infringements caused by: i) the modification of the -Original Code or - -ii) the combination of the Original Code with other software -or devices, including but not limited to Modifications. - -3.0 DISTRIBUTION OBLIGATIONS - -3.1 Application of License. The Source Code version of -Original Code may be distributed only under the terms of -this License or a future version of this License released -under Section 6.1, and You must include a copy of this -License with every copy of the Source Code You distribute. -You may not offer or impose any terms on any Source Code -version that alters or restricts the applicable version of -this License or the recipient's rights hereunder. Your -license for shipment of the Contributor Version is -conditioned upon your full compliance with this Section. -The Modifications which you create must comply with all -requirements set out by the Standards body in effect 120 -days before You ship the Contributor Version. In the event -that the Modifications do not meet such requirements, You -agree to publish (i) any deviation from the Standards -protocol resulting from implementation of your Modifications -and (ii) a reference implementation of Your Modifications, -and to make any such deviation and reference implementation -available to all third parties under the same terms as the -license on a royalty free basis within thirty (30) days of -Your first customer shipment of Your Modifications. - -3.2 Required Notices. You must duplicate the notice in -Exhibit A in each file of the Source Code. If it is not -possible to put such notice in a particular Source Code file -due to its structure, then You must include such notice in a -location (such as a relevant directory ) where a user would -be likely to look for such a notice. If You created one or -more Modifications ) You may add your name as a Contributor -to the notice described in Exhibit A. You must also -duplicate this License in any documentation for the Source -Code where You describe recipients' rights or ownership -rights relating to Initial Code. You may choose to offer, -and to charge a fee for, warranty, support, indemnity or -liability obligations to one or more recipients of Your -version of the Code. However, You may do so only - -on Your own behalf, and not on behalf of the Initial -Developer. You must make it absolutely clear than any such -warranty, support, indemnity or liability obligation is -offered by You alone, and You hereby agree to indemnify the -Initial Developer for any liability incurred by the Initial -Developer as a result of warranty, support, indemnity or -liability terms You offer. - -3.3 Distribution of Executable Versions. You may distribute -Original Code in Executable and Source form only if the -requirements of Section 3.1 and 3.2 have been met for that -Original Code, and if You include a notice stating that the -Source Code version of the Original Code is available under -the terms of this License. The notice must be conspicuously -included in any notice in an Executable or Source versions, -related documentation or collateral in which You describe -recipients' rights relating to the Original Code. You may -distribute the Executable and Source versions of Your -version of the Code or ownership rights under a license of -Your choice, which may contain terms different from this -License, provided that You are in compliance with the terms -of this License. If You distribute the Executable and -Source versions under a different license You must make it -absolutely clear that any terms which differ from this -License are offered by You alone, not by the Initial -Developer . You hereby agree to indemnify the Initial -Developer for any liability incurred by the Initial -Developer as a result of any such terms You offer . - -3.4 Larger Works. You may create a Larger Work by combining -Original Code with other code not governed by the terms of -this License and distribute the Larger Work as a single -product. In such a case, You must make sure the -requirements of this License are fulfilled for the Original -Code. - -4.0 INABILITY TO COMPLY DUE TO STATUTE OR REGULATION - -If it is impossible for You to comply with any of the terms -of this License with respect to some or all of the Original -Code due to statute, judicial order, or regulation then You -must: - -a) comply with the terms of this License to the maximum -extent possible; and - -b) describe the limitations and the code they affect. Such -description must be included in the LEGAL file described in -Section 3.2 and must be included with all distributions of -the Source Code. Except to the extent prohibited by statute -or regulation, such description must be sufficiently -detailed for a recipient of ordinary skill to be able to -understand it. - -5.0 APPLICATION OF THIS LICENSE This License applies to code -to which the Initial Developer has attached the notice in -Exhibit A and to related Modifications as set out in Section -3.1. - -6.0 VERSIONS OF THE LICENSE - -6.1 New Versions. Sun Microsystems, Inc. Sun may publish -revised and/or new versions of the License from time to -time. Each version will be given a distinguishing version -number . - -6.2 Effect of New Versions. Once Original Code has been -published under a particular version of the License, You may -always continue to use it under the terms of that version. -You may also choose to use such Original Code under the -terms of any subsequent version of the License published by -Sun. No one other than Sun has the right to modify the -terms applicable to Original Code. - -7. DISCLAIMER OF W ARRANTY. ORIGINAL CODE IS PROVIDED -UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF -ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT -LIMITATION, WARRANTIES THAT THE ORIGINAL CODE IS FREE OF -DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR -NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE ORIGINAL CODE IS WITH YOU. SHOULD ANY -ORIGINAL CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE -INITIAL DEVELOPER )ASSUME THE COST OF ANY NECESSARY -SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF -WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO -USE OF ANY ORIGINAL CODE IS AUTHORIZED HEREUNDER EXCEPT -UNDER THIS DISCLAIMER. - -8.0 TERMINATION - -8.1 This License and the rights granted hereunder will -terminate automatically if You fail to comply with terms -herein and fail to cure such breach within 30 days of -becoming aware of the breach. All sublicenses to the -Original Code which are properly granted shall survive any -termination of this License. Provisions which, by their -nature, must remain in effect beyond the termination of this -License shall survive. - -8.2 .In the event of termination under Section 8.1 above, -all end user license agreements (excluding distributors and -resellers) which have been validly granted by You or any -distributor hereunder prior to termination shall survive -termination. - -9.0 LIMIT OF LIABILITY UNDER NO CIRCUMSTANCES AND UNDER NO -LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE) ,CONTRACT, -OR OTHER WISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER -CONTRIBUTOR, OR ANY DISTRIBUTOR OF ORIGINAL CODE, OR ANY -SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR -ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR -LOSS OF GOOD WILL, WORK STOPPAGE, COMPUTER FAILURE OR -MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR -LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE -POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY -SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY -RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT -APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME -JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF -INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND -LIMITATION MAY NOT APPLY TO YOU. - -10.0 U .S. GOVERNMENT END USERS U.S. Government: If this -Software is being acquired by or on behalf of the U.S. -Government or by a U.S. Government prime contractor or -subcontractor (at any tier), then the Government's rights in -the Software and accompanying documentation shall be only as -set forth in this license; this is in accordance with 48 C.F -.R. 227.7201 through 227.7202-4 (for Department of Defense -(DoD) acquisitions )and with 48 C.F.R.2.101 and 12.212( for -non-DoD acquisitions). - -11.0 MISCELLANEOUS This License represents the complete -agreement concerning subject matter hereof. If any -provision of this License is held to be unenforceable, such -provision shall be reformed only to the extent necessary to -make it enforceable. This License shall be governed by -California law provisions (except to the extent applicable -law, if any, provides otherwise), excluding its -conflict-of-law provisions. With respect to disputes in -which at least one party is a citizen of, or an entity -chartered or registered to do business in the United States -of America, any litigation relating to this License shall be -subject to the jurisdiction of the Federal Courts of the -Northern District of California, with venue lying in Santa -Clara County, California, with the losing party responsible -for costs, including without limitation, court costs and -reasonable attorneys fees and expenses. The application of -the United Nations Convention on Contracts for the -International Sale of Goods is expressly excluded. Any law -or regulation which provides that the language of a contract -shall be construed against the drafter shall not apply to -this License. - -EXHIBIT A - Sun Standards - -"The contents of this file are subject to the Sun Standards -License Version 1.0 the (the "License";) You may not use -this file except in compliance with the License. You may -obtain a copy of the License at -_______________________________. - - Software distributed under the License is distributed on -an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either -express or implied. See the License for the specific -language governing rights and limitations under the License. - -The Original Code is Copyright 1998 by Sun Microsystems, Inc - -The Initial Developer of the Original Code is: Sun -Microsystems, Inc. - -Portions created by _____________________________ are -Copyright ______________________________. - -All Rights Reserved. - -Contributors: ______________________________________. - -EXHIBIT B - Sun Standards - -The Standard is defined as the following IETF RFCs: - -RFC1831: RPC: Remote Procedure Call Protocol Specification -Version 2 RFC1832: XDR: External Data REpresentation -Standard RFC1833: Binding Protocols for ONC RPC Version 2 -RFC2078: Generic Security Service Application Program -Interface, Version 2 RFC2203: RPCSEC_GSS Protocol -Specification RFC2695: Authentication Mechanisms for ONC RPC diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index 32e8f86..2f05009 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -1,7 +1,7 @@ # @(#)Makefile 5.11 (Berkeley) 9/6/90 # $FreeBSD$ -.PATH: ${.CURDIR}/rpc ${.CURDIR}/. +.PATH: ${LIBC_SRCTOP}/rpc ${LIBC_SRCTOP}/. SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \ @@ -26,10 +26,10 @@ SRCS+= rtime.c # generated sources SRCS+= crypt_clnt.c crypt_xdr.c crypt.h -SYM_MAPS+=${.CURDIR}/rpc/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/rpc/Symbol.map CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN -CFLAGS+= -I${.CURDIR}/rpc +CFLAGS+= -I${LIBC_SRCTOP}/rpc CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h diff --git a/lib/libc/rpc/auth_des.c b/lib/libc/rpc/auth_des.c index 1b45c3b..1bc2661 100644 --- a/lib/libc/rpc/auth_des.c +++ b/lib/libc/rpc/auth_des.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1988 by Sun Microsystems, Inc. diff --git a/lib/libc/rpc/auth_none.c b/lib/libc/rpc/auth_none.c index 01ad701..311fa55 100644 --- a/lib/libc/rpc/auth_none.c +++ b/lib/libc/rpc/auth_none.c @@ -1,32 +1,31 @@ /* $NetBSD: auth_none.c,v 1.13 2000/01/22 22:19:17 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/auth_unix.c b/lib/libc/rpc/auth_unix.c index 5c138d0..1ec5430 100644 --- a/lib/libc/rpc/auth_unix.c +++ b/lib/libc/rpc/auth_unix.c @@ -1,32 +1,31 @@ /* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/authdes_prot.c b/lib/libc/rpc/authdes_prot.c index 5be1f12..ae12973 100644 --- a/lib/libc/rpc/authdes_prot.c +++ b/lib/libc/rpc/authdes_prot.c @@ -4,33 +4,32 @@ static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88 #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/authunix_prot.c b/lib/libc/rpc/authunix_prot.c index f80b176..42a5fad 100644 --- a/lib/libc/rpc/authunix_prot.c +++ b/lib/libc/rpc/authunix_prot.c @@ -1,32 +1,31 @@ /* $NetBSD: authunix_prot.c,v 1.12 2000/01/22 22:19:17 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c index 75a1c8f..c8b1646 100644 --- a/lib/libc/rpc/bindresvport.c +++ b/lib/libc/rpc/bindresvport.c @@ -1,32 +1,31 @@ /* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/clnt_bcast.c b/lib/libc/rpc/clnt_bcast.c index 612007e..6ee1f90 100644 --- a/lib/libc/rpc/clnt_bcast.c +++ b/lib/libc/rpc/clnt_bcast.c @@ -1,32 +1,31 @@ /* $NetBSD: clnt_bcast.c,v 1.3 2000/07/06 03:05:20 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/clnt_dg.c b/lib/libc/rpc/clnt_dg.c index 9c52e1e..5feab88 100644 --- a/lib/libc/rpc/clnt_dg.c +++ b/lib/libc/rpc/clnt_dg.c @@ -1,32 +1,31 @@ /* $NetBSD: clnt_dg.c,v 1.4 2000/07/14 08:40:41 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c index 302a30e..0c8a425 100644 --- a/lib/libc/rpc/clnt_generic.c +++ b/lib/libc/rpc/clnt_generic.c @@ -1,49 +1,31 @@ /* $NetBSD: clnt_generic.c,v 1.18 2000/07/06 03:10:34 christos Exp $ */ -/* - * The contents of this file are subject to the Sun Standards - * License Version 1.0 the (the "License";) You may not use - * this file except in compliance with the License. You may - * obtain a copy of the License at lib/libc/rpc/LICENSE - * - * Software distributed under the License is distributed on - * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is Copyright 1998 by Sun Microsystems, Inc - * - * The Initial Developer of the Original Code is: Sun - * Microsystems, Inc. - * - * All Rights Reserved. - * - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2010, Oracle America, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* #ident "@(#)clnt_generic.c 1.40 99/04/21 SMI" */ diff --git a/lib/libc/rpc/clnt_perror.c b/lib/libc/rpc/clnt_perror.c index efe9043..5d87b0c 100644 --- a/lib/libc/rpc/clnt_perror.c +++ b/lib/libc/rpc/clnt_perror.c @@ -1,33 +1,32 @@ /* $NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c index cd3a384..26e2856 100644 --- a/lib/libc/rpc/clnt_raw.c +++ b/lib/libc/rpc/clnt_raw.c @@ -1,32 +1,31 @@ /* $NetBSD: clnt_raw.c,v 1.20 2000/12/10 04:12:03 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c index ba21d2d..3541205 100644 --- a/lib/libc/rpc/clnt_simple.c +++ b/lib/libc/rpc/clnt_simple.c @@ -1,32 +1,31 @@ /* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c index 53e393e..7cd93b3 100644 --- a/lib/libc/rpc/clnt_vc.c +++ b/lib/libc/rpc/clnt_vc.c @@ -1,32 +1,31 @@ /* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/des_crypt.c b/lib/libc/rpc/des_crypt.c index 238d55a..ace8ed6 100644 --- a/lib/libc/rpc/des_crypt.c +++ b/lib/libc/rpc/des_crypt.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * des_crypt.c, DES encryption library routines diff --git a/lib/libc/rpc/des_soft.c b/lib/libc/rpc/des_soft.c index daed265..80d8c52 100644 --- a/lib/libc/rpc/des_soft.c +++ b/lib/libc/rpc/des_soft.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index 1310e36..34be6e1 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -1,33 +1,31 @@ /* $NetBSD: getnetconfig.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/getnetpath.c b/lib/libc/rpc/getnetpath.c index 92eae95..29155c7 100644 --- a/lib/libc/rpc/getnetpath.c +++ b/lib/libc/rpc/getnetpath.c @@ -1,33 +1,31 @@ /* $NetBSD: getnetpath.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/getpublickey.c b/lib/libc/rpc/getpublickey.c index 3c95338..143c0fc 100644 --- a/lib/libc/rpc/getpublickey.c +++ b/lib/libc/rpc/getpublickey.c @@ -1,31 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/getrpcent.c b/lib/libc/rpc/getrpcent.c index 1f198fa..fa404d8 100644 --- a/lib/libc/rpc/getrpcent.c +++ b/lib/libc/rpc/getrpcent.c @@ -1,33 +1,31 @@ /* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/getrpcport.c b/lib/libc/rpc/getrpcport.c index 676a1f5..1ceaa3f 100644 --- a/lib/libc/rpc/getrpcport.c +++ b/lib/libc/rpc/getrpcport.c @@ -1,32 +1,31 @@ /* $NetBSD: getrpcport.c,v 1.16 2000/01/22 22:19:18 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c index afb11c8..3864061 100644 --- a/lib/libc/rpc/key_call.c +++ b/lib/libc/rpc/key_call.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/key_prot_xdr.c b/lib/libc/rpc/key_prot_xdr.c index bcead6a..19a2f6c 100644 --- a/lib/libc/rpc/key_prot_xdr.c +++ b/lib/libc/rpc/key_prot_xdr.c @@ -6,33 +6,32 @@ #include "namespace.h" #include <rpc/key_prot.h> #include "un-namespace.h" -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */ diff --git a/lib/libc/rpc/netname.c b/lib/libc/rpc/netname.c index 72361ba..7b1661e 100644 --- a/lib/libc/rpc/netname.c +++ b/lib/libc/rpc/netname.c @@ -1,31 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/netnamer.c b/lib/libc/rpc/netnamer.c index 772160a..fce4b4d 100644 --- a/lib/libc/rpc/netnamer.c +++ b/lib/libc/rpc/netnamer.c @@ -1,31 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c index a0db013..702d58d 100644 --- a/lib/libc/rpc/pmap_clnt.c +++ b/lib/libc/rpc/pmap_clnt.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_getmaps.c b/lib/libc/rpc/pmap_getmaps.c index 42d3720..34e254a 100644 --- a/lib/libc/rpc/pmap_getmaps.c +++ b/lib/libc/rpc/pmap_getmaps.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_getmaps.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_getport.c b/lib/libc/rpc/pmap_getport.c index ca0aafd..e06f958 100644 --- a/lib/libc/rpc/pmap_getport.c +++ b/lib/libc/rpc/pmap_getport.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_getport.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_prot.c b/lib/libc/rpc/pmap_prot.c index 2c01311..1967467 100644 --- a/lib/libc/rpc/pmap_prot.c +++ b/lib/libc/rpc/pmap_prot.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_prot.c,v 1.10 2000/01/22 22:19:18 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_prot2.c b/lib/libc/rpc/pmap_prot2.c index ae7c7c6..56a1198 100644 --- a/lib/libc/rpc/pmap_prot2.c +++ b/lib/libc/rpc/pmap_prot2.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c index ddcde2e..fe7b432 100644 --- a/lib/libc/rpc/pmap_rmt.c +++ b/lib/libc/rpc/pmap_rmt.c @@ -1,32 +1,31 @@ /* $NetBSD: pmap_rmt.c,v 1.29 2000/07/06 03:10:34 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c index ad1bdb3..5b7ea49 100644 --- a/lib/libc/rpc/rpc_callmsg.c +++ b/lib/libc/rpc/rpc_callmsg.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_callmsg.c,v 1.16 2000/07/14 08:40:42 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rpc_com.h b/lib/libc/rpc/rpc_com.h index f2bf11f..bfa6a0b 100644 --- a/lib/libc/rpc/rpc_com.h +++ b/lib/libc/rpc/rpc_com.h @@ -1,32 +1,31 @@ /* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ @@ -87,8 +86,8 @@ bool_t __xdrrec_setnonblock(XDR *, int); bool_t __xdrrec_getrec(XDR *, enum xprt_stat *, bool_t); void __xprt_unregister_unlocked(SVCXPRT *); -SVCXPRT **__svc_xports; -int __svc_maxrec; +extern SVCXPRT **__svc_xports; +extern int __svc_maxrec; __END_DECLS diff --git a/lib/libc/rpc/rpc_commondata.c b/lib/libc/rpc/rpc_commondata.c index 679233a..e63538d 100644 --- a/lib/libc/rpc/rpc_commondata.c +++ b/lib/libc/rpc/rpc_commondata.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_commondata.c,v 1.7 2000/06/02 23:11:13 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rpc_dtablesize.c b/lib/libc/rpc/rpc_dtablesize.c index 5e50ba8..4bcb71f 100644 --- a/lib/libc/rpc/rpc_dtablesize.c +++ b/lib/libc/rpc/rpc_dtablesize.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_dtablesize.c,v 1.14 1998/11/15 17:32:43 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c index 0ac4597..57ef267 100644 --- a/lib/libc/rpc/rpc_generic.c +++ b/lib/libc/rpc/rpc_generic.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/rpc_prot.c b/lib/libc/rpc/rpc_prot.c index 2a4b575..20dc8fa 100644 --- a/lib/libc/rpc/rpc_prot.c +++ b/lib/libc/rpc/rpc_prot.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index 2568d43..d7702f5 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -1,32 +1,31 @@ /* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ diff --git a/lib/libc/rpc/rpcb_clnt.c b/lib/libc/rpc/rpcb_clnt.c index afef806..a0d840e 100644 --- a/lib/libc/rpc/rpcb_clnt.c +++ b/lib/libc/rpc/rpcb_clnt.c @@ -1,52 +1,31 @@ /* $NetBSD: rpcb_clnt.c,v 1.6 2000/07/16 06:41:43 itojun Exp $ */ -/* - * The contents of this file are subject to the Sun Standards - * License Version 1.0 the (the "License";) You may not use - * this file except in compliance with the License. You may - * obtain a copy of the License at lib/libc/rpc/LICENSE - * - * Software distributed under the License is distributed on - * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is Copyright 1998 by Sun Microsystems, Inc - * - * The Initial Developer of the Original Code is: Sun - * Microsystems, Inc. +/*- + * Copyright (c) 2010, Oracle America, Inc. + * All rights reserved. * - * All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986-1991 by Sun Microsystems Inc. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* #ident "@(#)rpcb_clnt.c 1.27 94/04/24 SMI" */ @@ -61,8 +40,6 @@ __FBSDID("$FreeBSD$"); /* * rpcb_clnt.c * interface to rpcbind rpc service. - * - * Copyright (C) 1988, Sun Microsystems, Inc. */ #include "namespace.h" diff --git a/lib/libc/rpc/rpcb_prot.c b/lib/libc/rpc/rpcb_prot.c index f766749..f543aaf 100644 --- a/lib/libc/rpc/rpcb_prot.c +++ b/lib/libc/rpc/rpcb_prot.c @@ -1,32 +1,31 @@ /* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/rpcb_st_xdr.c b/lib/libc/rpc/rpcb_st_xdr.c index cf1e227..8ffc5b6 100644 --- a/lib/libc/rpc/rpcb_st_xdr.c +++ b/lib/libc/rpc/rpcb_st_xdr.c @@ -1,32 +1,31 @@ /* $NetBSD: rpcb_st_xdr.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright 1991 Sun Microsystems, Inc. diff --git a/lib/libc/rpc/rpcdname.c b/lib/libc/rpc/rpcdname.c index d4455f4..d6a21c9 100644 --- a/lib/libc/rpc/rpcdname.c +++ b/lib/libc/rpc/rpcdname.c @@ -1,31 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/rtime.c b/lib/libc/rpc/rtime.c index 39ac19b..807b14c 100644 --- a/lib/libc/rpc/rtime.c +++ b/lib/libc/rpc/rtime.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c index 78a8ae1..8203bd9 100644 --- a/lib/libc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -1,32 +1,31 @@ /* $NetBSD: svc.c,v 1.21 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -85,6 +84,9 @@ static struct svc_callout { void (*sc_dispatch)(struct svc_req *, SVCXPRT *); } *svc_head; +SVCXPRT **__svc_xports; +int __svc_maxrec; + static struct svc_callout *svc_find(rpcprog_t, rpcvers_t, struct svc_callout **, char *); static void __xprt_do_unregister (SVCXPRT *xprt, bool_t dolock); diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c index b3894e6..2068529 100644 --- a/lib/libc/rpc/svc_auth.c +++ b/lib/libc/rpc/svc_auth.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/svc_auth_des.c b/lib/libc/rpc/svc_auth_des.c index bd45f20..d6fb6af 100644 --- a/lib/libc/rpc/svc_auth_des.c +++ b/lib/libc/rpc/svc_auth_des.c @@ -3,33 +3,32 @@ * Copyright (c) 1988 by Sun Microsystems, Inc. */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* diff --git a/lib/libc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c index 20d4ecc..7e837d3 100644 --- a/lib/libc/rpc/svc_auth_unix.c +++ b/lib/libc/rpc/svc_auth_unix.c @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c index a78b160..980e39f 100644 --- a/lib/libc/rpc/svc_dg.c +++ b/lib/libc/rpc/svc_dg.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_dg.c,v 1.4 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* diff --git a/lib/libc/rpc/svc_generic.c b/lib/libc/rpc/svc_generic.c index 7f6cfb8..21569c0 100644 --- a/lib/libc/rpc/svc_generic.c +++ b/lib/libc/rpc/svc_generic.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_generic.c,v 1.3 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* diff --git a/lib/libc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c index de95152..ffa9122 100644 --- a/lib/libc/rpc/svc_raw.c +++ b/lib/libc/rpc/svc_raw.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_raw.c,v 1.14 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c index b4627d6..08c8a84 100644 --- a/lib/libc/rpc/svc_run.c +++ b/lib/libc/rpc/svc_run.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c index cf00727..b97f974 100644 --- a/lib/libc/rpc/svc_simple.c +++ b/lib/libc/rpc/svc_simple.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_simple.c,v 1.20 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Copyright (c) 1986-1991 by Sun Microsystems Inc. diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c index aded6b1..f830425 100644 --- a/lib/libc/rpc/svc_vc.c +++ b/lib/libc/rpc/svc_vc.c @@ -1,32 +1,31 @@ /* $NetBSD: svc_vc.c,v 1.7 2000/08/03 00:01:53 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/softfloat/Makefile.inc b/lib/libc/softfloat/Makefile.inc index 2213403..f15e4d2 100644 --- a/lib/libc/softfloat/Makefile.inc +++ b/lib/libc/softfloat/Makefile.inc @@ -3,9 +3,11 @@ SOFTFLOAT_BITS?=64 .PATH: ${LIBC_ARCH}/softfloat \ - ${.CURDIR}/softfloat/bits${SOFTFLOAT_BITS} ${.CURDIR}/softfloat + ${LIBC_SRCTOP}/softfloat/bits${SOFTFLOAT_BITS} \ + ${LIBC_SRCTOP}/softfloat -CFLAGS+= -I${.CURDIR}/${LIBC_ARCH}/softfloat -I${.CURDIR}/softfloat +CFLAGS+= -I${LIBC_SRCTOP}/${LIBC_ARCH}/softfloat \ + -I${LIBC_SRCTOP}/softfloat CFLAGS+= -DSOFTFLOAT_FOR_GCC SRCS+= softfloat.c @@ -27,4 +29,4 @@ CFLAGS+= -DFLOATX80 SRCS+= nexf2.c gtxf2.c gexf2.c negxf2.c .endif -SYM_MAPS+= ${.CURDIR}/softfloat/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/softfloat/Symbol.map diff --git a/lib/libc/sparc64/Makefile.inc b/lib/libc/sparc64/Makefile.inc index 84a0e06..af23ae4 100644 --- a/lib/libc/sparc64/Makefile.inc +++ b/lib/libc/sparc64/Makefile.inc @@ -10,4 +10,4 @@ SRCS+= __vdso_gettc.c # Long double is quad precision GDTOASRCS+=strtorQ.c MDSRCS+=machdep_ldisQ.c -SYM_MAPS+=${.CURDIR}/sparc64/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/sparc64/Symbol.map diff --git a/lib/libc/sparc64/fpu/Makefile.inc b/lib/libc/sparc64/fpu/Makefile.inc index 1974d8a..6aaf583 100644 --- a/lib/libc/sparc64/fpu/Makefile.inc +++ b/lib/libc/sparc64/fpu/Makefile.inc @@ -1,8 +1,8 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/sparc64/fpu +.PATH: ${LIBC_SRCTOP}/sparc64/fpu -CFLAGS+= -I${.CURDIR}/sparc64/sys +CFLAGS+= -I${LIBC_SRCTOP}/sparc64/sys SRCS+= fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_explode.c fpu_implode.c \ fpu_mul.c fpu_qp.c fpu_reg.S fpu_sqrt.c fpu_subr.c diff --git a/lib/libc/sparc64/fpu/fpu.c b/lib/libc/sparc64/fpu/fpu.c index 4e92788..431207f 100644 --- a/lib/libc/sparc64/fpu/fpu.c +++ b/lib/libc/sparc64/fpu/fpu.c @@ -202,7 +202,7 @@ static const int opmask[] = {0, 0, 1, 3, 1}; * Implement a move operation for all supported operand types. The additional * nand and xor parameters will be applied to the upper 32 bit word of the * source operand. This allows to implement fabs and fneg (for fp operands - * only!) using this functions, too, by passing (1 << 31) for one of the + * only!) using this functions, too, by passing (1U << 31) for one of the * parameters, and 0 for the other. */ static void @@ -358,10 +358,10 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, __fpu_mov(fe, type, rd, rs2, 0, 0); return (0); case FOP(INS2_FPop1, INSFP1_FNEG): - __fpu_mov(fe, type, rd, rs2, 0, (1 << 31)); + __fpu_mov(fe, type, rd, rs2, 0, (1U << 31)); return (0); case FOP(INS2_FPop1, INSFP1_FABS): - __fpu_mov(fe, type, rd, rs2, (1 << 31), 0); + __fpu_mov(fe, type, rd, rs2, (1U << 31), 0); return (0); case FOP(INS2_FPop1, INSFP1_FSQRT): __fpu_explode(fe, &fe->fe_f1, type, rs2); diff --git a/lib/libc/sparc64/fpu/fpu_sqrt.c b/lib/libc/sparc64/fpu/fpu_sqrt.c index 364384b..52290f2 100644 --- a/lib/libc/sparc64/fpu/fpu_sqrt.c +++ b/lib/libc/sparc64/fpu/fpu_sqrt.c @@ -257,7 +257,7 @@ __fpu_sqrt(fe) * double x correctly while doing the `known q=1.0'. * * We do this one mantissa-word at a time, as noted above, to - * save work. To avoid `(1 << 31) << 1', we also do the top bit + * save work. To avoid `(1U << 31) << 1', we also do the top bit * outside of each per-word loop. * * The calculation `t = y + bit' breaks down into `t0 = y0, ..., diff --git a/lib/libc/sparc64/sys/Makefile.inc b/lib/libc/sparc64/sys/Makefile.inc index dedf783..031af19 100644 --- a/lib/libc/sparc64/sys/Makefile.inc +++ b/lib/libc/sparc64/sys/Makefile.inc @@ -10,7 +10,7 @@ SRCS+= __sparc_sigtramp_setup.c \ __sparc_utrap_setup.c \ sigcode.S -CFLAGS+= -I${.CURDIR}/sparc64/fpu +CFLAGS+= -I${LIBC_SRCTOP}/sparc64/fpu MDASM+= brk.S cerror.S exect.S pipe.S ptrace.S sbrk.S setlogin.S sigaction.S @@ -18,6 +18,6 @@ MDASM+= brk.S cerror.S exect.S pipe.S ptrace.S sbrk.S setlogin.S sigaction.S NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o PSEUDO= _getlogin.o _exit.o -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" PSEUDO+= _pread.o _pwrite.o _lseek.o _mmap.o _ftruncate.o _truncate.o .endif diff --git a/lib/libc/sparc64/sys/__sparc_utrap_setup.c b/lib/libc/sparc64/sys/__sparc_utrap_setup.c index f4a624b..2524f44 100644 --- a/lib/libc/sparc64/sys/__sparc_utrap_setup.c +++ b/lib/libc/sparc64/sys/__sparc_utrap_setup.c @@ -54,5 +54,5 @@ void __sparc_utrap_setup(void) { - sysarch(SPARC_UTRAP_INSTALL, &uia); + sysarch(SPARC_UTRAP_INSTALL, (void *)&uia); } diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 419d031..9c232ba 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # stdio sources -.PATH: ${.CURDIR}/stdio +.PATH: ${LIBC_SRCTOP}/stdio SRCS+= _flock_stub.c asprintf.c clrerr.c dprintf.c \ fclose.c fcloseall.c fdopen.c \ @@ -31,7 +31,7 @@ SRCS+= xprintf.c xprintf_float.c xprintf_int.c xprintf_str.c SRCS+= xprintf_errno.c xprintf_hexdump.c xprintf_quote.c SRCS+= xprintf_time.c xprintf_vis.c -SYM_MAPS+= ${.CURDIR}/stdio/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/stdio/Symbol.map MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \ flockfile.3 \ diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c index 2e19b9f..b936998 100644 --- a/lib/libc/stdio/fdopen.c +++ b/lib/libc/stdio/fdopen.c @@ -70,7 +70,8 @@ fdopen(int fd, const char *mode) /* Make sure the mode the user wants is a subset of the actual mode. */ if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) return (NULL); - tmp = fdflags & O_ACCMODE; + /* Work around incorrect O_ACCMODE. */ + tmp = fdflags & (O_ACCMODE | O_EXEC); if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c index dc5508d..0ff83bf 100644 --- a/lib/libc/stdio/freopen.c +++ b/lib/libc/stdio/freopen.c @@ -92,8 +92,9 @@ freopen(const char * __restrict file, const char * __restrict mode, errno = sverrno; return (NULL); } - if ((dflags & O_ACCMODE) != O_RDWR && (dflags & O_ACCMODE) != - (oflags & O_ACCMODE)) { + /* Work around incorrect O_ACCMODE. */ + if ((dflags & O_ACCMODE) != O_RDWR && + (dflags & (O_ACCMODE | O_EXEC)) != (oflags & O_ACCMODE)) { fclose(fp); FUNLOCKFILE(fp); errno = EINVAL; diff --git a/lib/libc/stdio/printf_l.3 b/lib/libc/stdio/printf_l.3 index 20c855b..312d110 100644 --- a/lib/libc/stdio/printf_l.3 +++ b/lib/libc/stdio/printf_l.3 @@ -43,6 +43,7 @@ .Lb libc .Sh SYNOPSIS .In stdio.h +.In xlocale.h .Ft int .Fn printf_l "locale_t loc" "const char * restrict format" "..." .Ft int diff --git a/lib/libc/stdio/scanf_l.3 b/lib/libc/stdio/scanf_l.3 index 405601e..35a8241 100644 --- a/lib/libc/stdio/scanf_l.3 +++ b/lib/libc/stdio/scanf_l.3 @@ -39,6 +39,7 @@ .Lb libc .Sh SYNOPSIS .In stdio.h +.In xlocale.h .Ft int .Fn scanf_l "locale_t loc" "const char * restrict format" "..." .Ft int diff --git a/lib/libc/stdio/tmpnam.3 b/lib/libc/stdio/tmpnam.3 index 937068f..c54ec27 100644 --- a/lib/libc/stdio/tmpnam.3 +++ b/lib/libc/stdio/tmpnam.3 @@ -244,5 +244,3 @@ file permissions may be specified. It is strongly suggested that .Xr mkstemp 3 be used in place of these functions. -(See -the FSA.) diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 75204f5..68dda94 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -2,21 +2,22 @@ # $FreeBSD$ # machine-independent stdlib sources -.PATH: ${.CURDIR}/${LIBC_ARCH}/stdlib ${.CURDIR}/stdlib +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/stdlib ${LIBC_SRCTOP}/stdlib MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ bsearch.c div.c exit.c getenv.c getopt.c getopt_long.c \ - getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \ + getsubopt.c hcreate.c heapsort.c heapsort_b.c imaxabs.c imaxdiv.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ - merge.c ptsname.c qsort.c qsort_r.c quick_exit.c radixsort.c rand.c \ + merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \ + radixsort.c rand.c \ random.c reallocf.c realpath.c remque.c strfmon.c strtoimax.c \ strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c -SYM_MAPS+= ${.CURDIR}/stdlib/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/stdlib/Symbol.map # machine-dependent stdlib sources -.sinclude "${.CURDIR}/${LIBC_ARCH}/stdlib/Makefile.inc" +.sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/stdlib/Makefile.inc" MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \ atoi.3 atol.3 at_quick_exit.3 bsearch.3 \ diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 6a1798f..d28a8e9 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -104,6 +104,13 @@ FBSD_1.3 { strtouq_l; }; +FBSD_1.4 { + atexit_b; + heapsort_b; + mergesort_b; + qsort_b; +}; + FBSDprivate_1.0 { __system; _system; diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3 index d6dab56..68f4e8f 100644 --- a/lib/libc/stdlib/atexit.3 +++ b/lib/libc/stdlib/atexit.3 @@ -44,6 +44,8 @@ .In stdlib.h .Ft int .Fn atexit "void (*function)(void)" +.Ft int +.Fn atexit_b "void (^function)(void)" .Sh DESCRIPTION The .Fn atexit @@ -69,6 +71,12 @@ process termination, for example by calling .Pp At least 32 functions can always be registered, and more are allowed as long as sufficient memory can be allocated. +.Pp +The +.Fn atexit_b +function behaves identically to +.Fn atexit , +except that it takes a block, rather than a function pointer. .\" XXX {ATEXIT_MAX} is not implemented yet .Sh RETURN VALUES .Rv -std atexit @@ -77,6 +85,12 @@ and more are allowed as long as sufficient memory can be allocated. .It Bq Er ENOMEM No memory was available to add the function to the list. The existing list of functions is unmodified. +.It Bq Er ENOSYS +The +.Fn atexit_b +function was called by a program that did not supply a +.Fn _Block_copy +implementation. .El .Sh SEE ALSO .Xr at_quick_exit 3 diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c index 18c31c3..0a5048a 100644 --- a/lib/libc/stdlib/atexit.c +++ b/lib/libc/stdlib/atexit.c @@ -37,6 +37,7 @@ static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include <errno.h> #include <link.h> #include <stddef.h> #include <stdlib.h> @@ -44,9 +45,16 @@ __FBSDID("$FreeBSD$"); #include <pthread.h> #include "atexit.h" #include "un-namespace.h" +#include "block_abi.h" #include "libc_private.h" +/** + * The _Block_copy() function is provided by the block runtime. + */ +__attribute__((weak)) void* +_Block_copy(void*); + #define ATEXIT_FN_EMPTY 0 #define ATEXIT_FN_STD 1 #define ATEXIT_FN_CXA 2 @@ -72,6 +80,7 @@ struct atexit { }; static struct atexit *__atexit; /* points to head of LIFO stack */ +typedef DECLARE_BLOCK(void, atexit_block, void); /* * Register the function described by 'fptr' to be called at application @@ -125,7 +134,32 @@ atexit(void (*func)(void)) fn.fn_arg = NULL; fn.fn_dso = NULL; - error = atexit_register(&fn); + error = atexit_register(&fn); + return (error); +} + +/** + * Register a block to be performed at exit. + */ +int +atexit_b(atexit_block func) +{ + struct atexit_fn fn; + int error; + if (_Block_copy == 0) { + errno = ENOSYS; + return -1; + } + func = _Block_copy(func); + + // Blocks are not C++ destructors, but they have the same signature (a + // single void* parameter), so we can pretend that they are. + fn.fn_type = ATEXIT_FN_CXA; + fn.fn_ptr.cxa_func = (void(*)(void*))GET_BLOCK_FUNCTION(func); + fn.fn_arg = func; + fn.fn_dso = NULL; + + error = atexit_register(&fn); return (error); } @@ -144,13 +178,15 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso) fn.fn_arg = arg; fn.fn_dso = dso; - error = atexit_register(&fn); + error = atexit_register(&fn); return (error); } #pragma weak __pthread_cxa_finalize void __pthread_cxa_finalize(const struct dl_phdr_info *); +static int global_exit; + /* * Call all handlers registered with __cxa_atexit for the shared * object owning 'dso'. Note: if 'dso' is NULL, then all remaining @@ -164,10 +200,12 @@ __cxa_finalize(void *dso) struct atexit_fn fn; int n, has_phdr; - if (dso != NULL) + if (dso != NULL) { has_phdr = _rtld_addr_phdr(dso, &phdr_info); - else + } else { has_phdr = 0; + global_exit = 1; + } _MUTEX_LOCK(&atexit_mutex); for (p = __atexit; p; p = p->next) { @@ -177,8 +215,9 @@ __cxa_finalize(void *dso) fn = p->fns[n]; if (dso != NULL && dso != fn.fn_dso) { /* wrong DSO ? */ - if (!has_phdr || !__elf_phdr_match_addr( - &phdr_info, fn.fn_ptr.cxa_func)) + if (!has_phdr || global_exit || + !__elf_phdr_match_addr(&phdr_info, + fn.fn_ptr.cxa_func)) continue; } /* @@ -200,6 +239,6 @@ __cxa_finalize(void *dso) if (dso == NULL) _MUTEX_DESTROY(&atexit_mutex); - if (has_phdr && &__pthread_cxa_finalize != NULL) + if (has_phdr && !global_exit && &__pthread_cxa_finalize != NULL) __pthread_cxa_finalize(&phdr_info); } diff --git a/lib/libc/stdlib/bsearch.c b/lib/libc/stdlib/bsearch.c index 4bcaaf3..4a1dd52 100644 --- a/lib/libc/stdlib/bsearch.c +++ b/lib/libc/stdlib/bsearch.c @@ -36,6 +36,13 @@ __FBSDID("$FreeBSD$"); #include <stddef.h> #include <stdlib.h> +#ifdef I_AM_BSEARCH_B +#include "block_abi.h" +#define COMPAR(x,y) CALL_BLOCK(compar, x, y) +#else +#define COMPAR(x,y) compar(x, y) +#endif + /* * Perform a binary search. * @@ -52,6 +59,15 @@ __FBSDID("$FreeBSD$"); * have to make lim 3, then halve, obtaining 1, so that we will only * look at item 3. */ +#ifdef I_AM_BSEARCH_B +void * +bsearch_b(key, base0, nmemb, size, compar) + const void *key; + const void *base0; + size_t nmemb; + size_t size; + DECLARE_BLOCK(int, compar, const void *, const void *); +#else void * bsearch(key, base0, nmemb, size, compar) const void *key; @@ -59,6 +75,7 @@ bsearch(key, base0, nmemb, size, compar) size_t nmemb; size_t size; int (*compar)(const void *, const void *); +#endif { const char *base = base0; size_t lim; @@ -67,7 +84,7 @@ bsearch(key, base0, nmemb, size, compar) for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; - cmp = (*compar)(key, p); + cmp = COMPAR(key, p); if (cmp == 0) return ((void *)p); if (cmp > 0) { /* key > p: move right */ diff --git a/lib/libc/stdlib/bsearch_b.c b/lib/libc/stdlib/bsearch_b.c new file mode 100644 index 0000000..393feba --- /dev/null +++ b/lib/libc/stdlib/bsearch_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#define I_AM_BSEARCH_B +#include "bsearch.c" diff --git a/lib/libc/stdlib/getopt_long.3 b/lib/libc/stdlib/getopt_long.3 index 06eadca..6904716 100644 --- a/lib/libc/stdlib/getopt_long.3 +++ b/lib/libc/stdlib/getopt_long.3 @@ -130,11 +130,11 @@ field should be one of: .Pp .Bl -tag -width ".Dv optional_argument" -offset indent -compact .It Dv no_argument -no argument to the option is expect +no argument to the option is expected .It Dv required_argument an argument to the option is required .It Dv optional_argument -an argument to the option may be presented. +an argument to the option may be presented .El .Pp If diff --git a/lib/libc/stdlib/getsubopt.c b/lib/libc/stdlib/getsubopt.c index efff9da..d2db991 100644 --- a/lib/libc/stdlib/getsubopt.c +++ b/lib/libc/stdlib/getsubopt.c @@ -45,9 +45,7 @@ __FBSDID("$FreeBSD$"); char *suboptarg; int -getsubopt(optionp, tokens, valuep) - char **optionp, **valuep; - char * const *tokens; +getsubopt(char **optionp, char * const *tokens, char **valuep) { int cnt; char *p; diff --git a/lib/libc/stdlib/heapsort.c b/lib/libc/stdlib/heapsort.c index 4bad8a7..673a6a1 100644 --- a/lib/libc/stdlib/heapsort.c +++ b/lib/libc/stdlib/heapsort.c @@ -1,6 +1,8 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 2014 David T. Chisnall + * All rights reserved. * * This code is derived from software contributed to Berkeley by * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias. @@ -40,6 +42,14 @@ __FBSDID("$FreeBSD$"); #include <stddef.h> #include <stdlib.h> +#ifdef I_AM_HEAPSORT_B +#include "block_abi.h" +#define COMPAR(x, y) CALL_BLOCK(compar, x, y) +typedef DECLARE_BLOCK(int, heapsort_block, const void *, const void *); +#else +#define COMPAR(x, y) compar(x, y) +#endif + /* * Swap two areas of size number of bytes. Although qsort(3) permits random * blocks of memory to be sorted, sorting pointers is almost certainly the @@ -77,12 +87,12 @@ __FBSDID("$FreeBSD$"); for (par_i = initval; (child_i = par_i * 2) <= nmemb; \ par_i = child_i) { \ child = base + child_i * size; \ - if (child_i < nmemb && compar(child, child + size) < 0) { \ + if (child_i < nmemb && COMPAR(child, child + size) < 0) { \ child += size; \ ++child_i; \ } \ par = base + par_i * size; \ - if (compar(child, par) <= 0) \ + if (COMPAR(child, par) <= 0) \ break; \ SWAP(par, child, count, size, tmp); \ } \ @@ -108,7 +118,7 @@ __FBSDID("$FreeBSD$"); #define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \ for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \ child = base + child_i * size; \ - if (child_i < nmemb && compar(child, child + size) < 0) { \ + if (child_i < nmemb && COMPAR(child, child + size) < 0) { \ child += size; \ ++child_i; \ } \ @@ -120,7 +130,7 @@ __FBSDID("$FreeBSD$"); par_i = child_i / 2; \ child = base + child_i * size; \ par = base + par_i * size; \ - if (child_i == 1 || compar(k, par) < 0) { \ + if (child_i == 1 || COMPAR(k, par) < 0) { \ COPY(child, k, count, size, tmp1, tmp2); \ break; \ } \ @@ -135,11 +145,19 @@ __FBSDID("$FreeBSD$"); * a data set that will trigger the worst case is nonexistent. Heapsort's * only advantage over quicksort is that it requires little additional memory. */ +#ifdef I_AM_HEAPSORT_B +int +heapsort_b(vbase, nmemb, size, compar) + void *vbase; + size_t nmemb, size; + heapsort_block compar; +#else int heapsort(vbase, nmemb, size, compar) void *vbase; size_t nmemb, size; int (*compar)(const void *, const void *); +#endif { size_t cnt, i, j, l; char tmp, *tmp1, *tmp2; diff --git a/lib/libc/stdlib/heapsort_b.c b/lib/libc/stdlib/heapsort_b.c new file mode 100644 index 0000000..b1814bc --- /dev/null +++ b/lib/libc/stdlib/heapsort_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#define I_AM_HEAPSORT_B +#include "heapsort.c" diff --git a/lib/libc/stdlib/jemalloc/Makefile.inc b/lib/libc/stdlib/jemalloc/Makefile.inc index 9718676..4f5fa58 100644 --- a/lib/libc/stdlib/jemalloc/Makefile.inc +++ b/lib/libc/stdlib/jemalloc/Makefile.inc @@ -1,26 +1,26 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/stdlib/jemalloc +.PATH: ${LIBC_SRCTOP}/stdlib/jemalloc JEMALLOCSRCS:= jemalloc.c arena.c atomic.c base.c bitmap.c chunk.c \ chunk_dss.c chunk_mmap.c ckh.c ctl.c extent.c hash.c huge.c mb.c \ - mutex.c prof.c quarantine.c rtree.c stats.c tcache.c util.c tsd.c + mutex.c prof.c quarantine.c rtree.c stats.c tcache.c tsd.c util.c -SYM_MAPS+=${.CURDIR}/stdlib/jemalloc/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/stdlib/jemalloc/Symbol.map -CFLAGS+=-I${.CURDIR}/../../contrib/jemalloc/include +CFLAGS+=-I${LIBC_SRCTOP}/../../contrib/jemalloc/include .for src in ${JEMALLOCSRCS} MISRCS+=jemalloc_${src} CLEANFILES+=jemalloc_${src} jemalloc_${src}: - ln -sf ${.CURDIR}/../../contrib/jemalloc/src/${src} ${.TARGET} + ln -sf ${LIBC_SRCTOP}/../../contrib/jemalloc/src/${src} ${.TARGET} .endfor MAN+=jemalloc.3 CLEANFILES+=jemalloc.3 jemalloc.3: - ln -sf ${.CURDIR}/../../contrib/jemalloc/doc/jemalloc.3 ${.TARGET} + ln -sf ${LIBC_SRCTOP}/../../contrib/jemalloc/doc/jemalloc.3 ${.TARGET} MLINKS+= \ jemalloc.3 malloc.3 \ @@ -34,6 +34,12 @@ MLINKS+= \ jemalloc.3 mallctl.3 \ jemalloc.3 mallctlnametomib.3 \ jemalloc.3 mallctlbymib.3 \ + jemalloc.3 mallocx.3 \ + jemalloc.3 rallocx.3 \ + jemalloc.3 xallocx.3 \ + jemalloc.3 sallocx.3 \ + jemalloc.3 dallocx.3 \ + jemalloc.3 nallocx.3 \ jemalloc.3 allocm.3 \ jemalloc.3 rallocm.3 \ jemalloc.3 sallocm.3 \ diff --git a/lib/libc/stdlib/jemalloc/Symbol.map b/lib/libc/stdlib/jemalloc/Symbol.map index 617194f..35a5dad 100644 --- a/lib/libc/stdlib/jemalloc/Symbol.map +++ b/lib/libc/stdlib/jemalloc/Symbol.map @@ -21,6 +21,12 @@ FBSD_1.3 { mallctl; mallctlnametomib; mallctlbymib; + mallocx; + rallocx; + xallocx; + sallocx; + dallocx; + nallocx; allocm; rallocm; sallocm; @@ -32,6 +38,12 @@ FBSD_1.3 { __free; __posix_memalign; __malloc_usable_size; + __mallocx; + __rallocx; + __xallocx; + __sallocx; + __dallocx; + __nallocx; __allocm; __rallocm; __sallocm; diff --git a/lib/libc/stdlib/merge.c b/lib/libc/stdlib/merge.c index 01a9028..6b368c3 100644 --- a/lib/libc/stdlib/merge.c +++ b/lib/libc/stdlib/merge.c @@ -56,10 +56,18 @@ __FBSDID("$FreeBSD$"); #include <stdlib.h> #include <string.h> -static void setup(u_char *, u_char *, size_t, size_t, - int (*)(const void *, const void *)); -static void insertionsort(u_char *, size_t, size_t, - int (*)(const void *, const void *)); +#ifdef I_AM_MERGESORT_B +#include "block_abi.h" +#define DECLARE_CMP DECLARE_BLOCK(int, cmp, const void *, const void *) +typedef DECLARE_BLOCK(int, cmp_t, const void *, const void *); +#define CMP(x, y) CALL_BLOCK(cmp, x, y) +#else +typedef int (*cmp_t)(const void *, const void *); +#define CMP(x, y) cmp(x, y) +#endif + +static void setup(u_char *, u_char *, size_t, size_t, cmp_t); +static void insertionsort(u_char *, size_t, size_t, cmp_t); #define ISIZE sizeof(int) #define PSIZE sizeof(u_char *) @@ -95,11 +103,15 @@ static void insertionsort(u_char *, size_t, size_t, * Arguments are as for qsort. */ int +#ifdef I_AM_MERGESORT_B +mergesort_b(base, nmemb, size, cmp) +#else mergesort(base, nmemb, size, cmp) +#endif void *base; size_t nmemb; size_t size; - int (*cmp)(const void *, const void *); + cmp_t cmp; { size_t i; int sense; @@ -141,7 +153,7 @@ mergesort(base, nmemb, size, cmp) p2 = *EVAL(p2); l2 = list1 + (p2 - list2); while (f1 < l1 && f2 < l2) { - if ((*cmp)(f1, f2) <= 0) { + if (CMP(f1, f2) <= 0) { q = f2; b = f1, t = l1; sense = -1; @@ -151,7 +163,7 @@ mergesort(base, nmemb, size, cmp) sense = 0; } if (!big) { /* here i = 0 */ - while ((b += size) < t && cmp(q, b) >sense) + while ((b += size) < t && CMP(q, b) >sense) if (++i == 6) { big = 1; goto EXPONENTIAL; @@ -160,12 +172,12 @@ mergesort(base, nmemb, size, cmp) EXPONENTIAL: for (i = size; ; i <<= 1) if ((p = (b + i)) >= t) { if ((p = t - size) > b && - (*cmp)(q, p) <= sense) + CMP(q, p) <= sense) t = p; else b = p; break; - } else if ((*cmp)(q, p) <= sense) { + } else if (CMP(q, p) <= sense) { t = p; if (i == size) big = 0; @@ -174,14 +186,14 @@ EXPONENTIAL: for (i = size; ; i <<= 1) b = p; while (t > b+size) { i = (((t - b) / size) >> 1) * size; - if ((*cmp)(q, p = b + i) <= sense) + if (CMP(q, p = b + i) <= sense) t = p; else b = p; } goto COPY; FASTCASE: while (i > size) - if ((*cmp)(q, + if (CMP(q, p = b + (i >>= 1)) <= sense) t = p; else @@ -261,8 +273,8 @@ COPY: b = t; void setup(list1, list2, n, size, cmp) size_t n, size; - int (*cmp)(const void *, const void *); u_char *list1, *list2; + cmp_t cmp; { int i, length, size2, tmp, sense; u_char *f1, *f2, *s, *l2, *last, *p2; @@ -285,12 +297,12 @@ setup(list1, list2, n, size, cmp) #ifdef NATURAL p2 = list2; f1 = list1; - sense = (cmp(f1, f1 + size) > 0); + sense = (CMP(f1, f1 + size) > 0); for (; f1 < last; sense = !sense) { length = 2; /* Find pairs with same sense. */ for (f2 = f1 + size2; f2 < last; f2 += size2) { - if ((cmp(f2, f2+ size) > 0) != sense) + if ((CMP(f2, f2+ size) > 0) != sense) break; length += 2; } @@ -303,7 +315,7 @@ setup(list1, list2, n, size, cmp) } else { /* Natural merge */ l2 = f2; for (f2 = f1 + size2; f2 < l2; f2 += size2) { - if ((cmp(f2-size, f2) > 0) != sense) { + if ((CMP(f2-size, f2) > 0) != sense) { p2 = *EVAL(p2) = f2 - list1 + list2; if (sense > 0) reverse(f1, f2-size); @@ -313,7 +325,7 @@ setup(list1, list2, n, size, cmp) if (sense > 0) reverse (f1, f2-size); f1 = f2; - if (f2 < last || cmp(f2 - size, f2) > 0) + if (f2 < last || CMP(f2 - size, f2) > 0) p2 = *EVAL(p2) = f2 - list1 + list2; else p2 = *EVAL(p2) = list2 + n*size; @@ -322,7 +334,7 @@ setup(list1, list2, n, size, cmp) #else /* pairwise merge only. */ for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { p2 = *EVAL(p2) = p2 + size2; - if (cmp (f1, f1 + size) > 0) + if (CMP (f1, f1 + size) > 0) swap(f1, f1 + size); } #endif /* NATURAL */ @@ -336,7 +348,7 @@ static void insertionsort(a, n, size, cmp) u_char *a; size_t n, size; - int (*cmp)(const void *, const void *); + cmp_t cmp; { u_char *ai, *s, *t, *u, tmp; int i; @@ -344,7 +356,7 @@ insertionsort(a, n, size, cmp) for (ai = a+size; --n >= 1; ai += size) for (t = ai; t > a; t -= size) { u = t - size; - if (cmp(u, t) <= 0) + if (CMP(u, t) <= 0) break; swap(u, t); } diff --git a/lib/libc/stdlib/mergesort_b.c b/lib/libc/stdlib/mergesort_b.c new file mode 100644 index 0000000..acf5987 --- /dev/null +++ b/lib/libc/stdlib/mergesort_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#define I_AM_MERGESORT_B +#include "merge.c" diff --git a/lib/libc/stdlib/qsort.3 b/lib/libc/stdlib/qsort.3 index ac01912..a0610d9 100644 --- a/lib/libc/stdlib/qsort.3 +++ b/lib/libc/stdlib/qsort.3 @@ -36,7 +36,7 @@ .Dt QSORT 3 .Os .Sh NAME -.Nm qsort , qsort_r , heapsort , mergesort +.Nm qsort , qsort_b , qsort_r , heapsort , heapsort_b , mergesort, mergesort_b .Nd sort functions .Sh LIBRARY .Lb libc @@ -50,6 +50,13 @@ .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" .Fc .Ft void +.Fo qsort_b +.Fa "void *base" +.Fa "size_t nmemb" +.Fa "size_t size" +.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft void .Fo qsort_r .Fa "void *base" .Fa "size_t nmemb" @@ -65,12 +72,26 @@ .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" .Fc .Ft int +.Fo heapsort_b +.Fa "void *base" +.Fa "size_t nmemb" +.Fa "size_t size" +.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft int .Fo mergesort .Fa "void *base" .Fa "size_t nmemb" .Fa "size_t size" .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" .Fc +.Ft int +.Fo mergesort_b +.Fa "void *base" +.Fa "size_t nmemb" +.Fa "size_t size" +.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc .Sh DESCRIPTION The .Fn qsort @@ -127,6 +148,11 @@ This allows the comparison function to access additional data without using global variables, and thus .Fn qsort_r is suitable for use in functions which must be reentrant. +The +.Fn qsort_b +function behaves identically to +.Fn qsort , +except that it takes a block, rather than a function pointer. .Pp The algorithms implemented by .Fn qsort , @@ -138,8 +164,18 @@ are stable, that is, if two members compare as equal, their order in the sorted array is undefined. The +.Fn heapsort_b +function behaves identically to +.Fn heapsort , +except that it takes a block, rather than a function pointer. +The .Fn mergesort algorithm is stable. +The +.Fn mergesort_b +function behaves identically to +.Fn mergesort , +except that it takes a block, rather than a function pointer. .Pp The .Fn qsort @@ -324,3 +360,7 @@ The function conforms to .St -isoC . +.Sh HISTORY +The variants of these functions that take blocks as arguments first appeared in +Mac OS X. +This implementation was created by David Chisnall. diff --git a/lib/libc/stdlib/qsort_r.c b/lib/libc/stdlib/qsort_r.c index d868736..f489d31 100644 --- a/lib/libc/stdlib/qsort_r.c +++ b/lib/libc/stdlib/qsort_r.c @@ -4,5 +4,16 @@ * * $FreeBSD$ */ +#include "block_abi.h" #define I_AM_QSORT_R #include "qsort.c" + +typedef DECLARE_BLOCK(int, qsort_block, const void *, const void *); + +void +qsort_b(void *base, size_t nel, size_t width, qsort_block compar) +{ + qsort_r(base, nel, width, compar, + (int (*)(void *, const void *, const void *)) + GET_BLOCK_FUNCTION(compar)); +} diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index a2a9329..c4bd953 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -132,26 +132,7 @@ realpath(const char * __restrict path, char * __restrict resolved) resolved[resolved_len] = '\0'; } if (next_token[0] == '\0') { - /* - * Handle consequential slashes. The path - * before slash shall point to a directory. - * - * Only the trailing slashes are not covered - * by other checks in the loop, but we verify - * the prefix for any (rare) "//" or "/\0" - * occurrence to not implement lookahead. - */ - if (lstat(resolved, &sb) != 0) { - if (m) - free(resolved); - return (NULL); - } - if (!S_ISDIR(sb.st_mode)) { - if (m) - free(resolved); - errno = ENOTDIR; - return (NULL); - } + /* Handle consequential slashes. */ continue; } else if (strcmp(next_token, ".") == 0) @@ -236,6 +217,11 @@ realpath(const char * __restrict path, char * __restrict resolved) } } left_len = strlcpy(left, symlink, sizeof(left)); + } else if (!S_ISDIR(sb.st_mode) && p != NULL) { + if (m) + free(resolved); + errno = ENOTDIR; + return (NULL); } } diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc index 477049f..3220cc9 100644 --- a/lib/libc/stdtime/Makefile.inc +++ b/lib/libc/stdtime/Makefile.inc @@ -1,15 +1,15 @@ # Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp # $FreeBSD$ -.PATH: ${.CURDIR}/stdtime ${.CURDIR}/../locale \ - ${.CURDIR}/../../contrib/tzcode/stdtime +.PATH: ${LIBC_SRCTOP}/stdtime ${LIBC_SRCTOP}/../locale \ + ${LIBC_SRCTOP}/../../contrib/tzcode/stdtime SRCS+= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \ time32.c -SYM_MAPS+= ${.CURDIR}/stdtime/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/stdtime/Symbol.map -CFLAGS+= -I${.CURDIR}/../../contrib/tzcode/stdtime -I${.CURDIR}/stdtime +CFLAGS+= -I${LIBC_SRCTOP}/../../contrib/tzcode/stdtime -I${LIBC_SRCTOP}/stdtime CFLAGS.localtime.c= -fwrapv CFLAGS+= ${CFLAGS.${.IMPSRC:T}} diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index b997b7b..9ad5cbb 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -1,9 +1,9 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -.PATH: ${.CURDIR}/${LIBC_ARCH}/string ${.CURDIR}/string +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/string ${LIBC_SRCTOP}/string -CFLAGS+= -I${.CURDIR}/locale +CFLAGS+= -I${LIBC_SRCTOP}/locale # machine-independent string sources MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \ @@ -22,11 +22,11 @@ MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \ wmemcmp.c \ wmemcpy.c wmemmove.c wmemset.c -SYM_MAPS+= ${.CURDIR}/string/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/string/Symbol.map # machine-dependent string sources -.sinclude "${.CURDIR}/${LIBC_ARCH}/string/Makefile.inc" +.sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/string/Makefile.inc" MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \ diff --git a/lib/libc/string/strcasecmp.3 b/lib/libc/string/strcasecmp.3 index 598f76f..1c85042 100644 --- a/lib/libc/string/strcasecmp.3 +++ b/lib/libc/string/strcasecmp.3 @@ -50,7 +50,7 @@ .Ft int .Fn strcasecmp_l "const char *s1" "const char *s2" "locale_t loc" .Ft int -.Fn strncasecmp_l "const char *s1" "const char *s2" "site_t len" "locale_t loc" +.Fn strncasecmp_l "const char *s1" "const char *s2" "size_t len" "locale_t loc" .Sh DESCRIPTION The .Fn strcasecmp diff --git a/lib/libc/string/strcat.3 b/lib/libc/string/strcat.3 index 14ce340..8022269 100644 --- a/lib/libc/string/strcat.3 +++ b/lib/libc/string/strcat.3 @@ -103,8 +103,6 @@ The function is easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. -(See -the FSA.) .Pp Avoid using .Fn strcat . diff --git a/lib/libc/string/strcpy.3 b/lib/libc/string/strcpy.3 index efc95df..4d4a1ee 100644 --- a/lib/libc/string/strcpy.3 +++ b/lib/libc/string/strcpy.3 @@ -210,7 +210,3 @@ The function is easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. -(See -the FSA -and -.Sx EXAMPLES . ) diff --git a/lib/libc/string/strlcpy.3 b/lib/libc/string/strlcpy.3 index 9ad663a..76bf6b7 100644 --- a/lib/libc/string/strlcpy.3 +++ b/lib/libc/string/strlcpy.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $ +.\" $OpenBSD: strlcpy.3,v 1.26 2013/09/30 12:02:35 millert Exp $ .\" .\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> .\" @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 22, 1998 +.Dd November 4, 2013 .Dt STRLCPY 3 .Os .Sh NAME @@ -47,69 +47,81 @@ The .Fn strlcpy and .Fn strlcat -functions copy and concatenate strings respectively. -They are designed -to be safer, more consistent, and less error prone replacements for +functions copy and concatenate strings with the +same input parameters and output result as +.Xr snprintf 3 . +They are designed to be safer, more consistent, and less error +prone replacements for the easily misused functions .Xr strncpy 3 and .Xr strncat 3 . -Unlike those functions, -.Fn strlcpy -and -.Fn strlcat -take the full size of the buffer (not just the length) and guarantee to -NUL-terminate the result (as long as -.Fa size -is larger than 0 or, in the case of -.Fn strlcat , -as long as there is at least one byte free in -.Fa dst ) . -Note that a byte for the NUL should be included in -.Fa size . -Also note that +.Pp .Fn strlcpy and .Fn strlcat -only operate on true -.Dq C -strings. -This means that for -.Fn strlcpy -.Fa src -must be NUL-terminated and for -.Fn strlcat -both -.Fa src -and -.Fa dst -must be NUL-terminated. +take the full size of the destination buffer and guarantee +NUL-termination if there is room. +Note that room for the NUL should be included in +.Fa dstsize . .Pp -The .Fn strlcpy -function copies up to -.Fa size -- 1 characters from the NUL-terminated string +copies up to +.Fa dstsize +\- 1 characters from the string .Fa src to .Fa dst , -NUL-terminating the result. +NUL-terminating the result if +.Fa dstsize +is not 0. .Pp -The .Fn strlcat -function appends the NUL-terminated string +appends string .Fa src to the end of .Fa dst . It will append at most -.Fa size -- strlen(dst) - 1 bytes, NUL-terminating the result. +.Fa dstsize +\- strlen(dst) \- 1 characters. +It will then NUL-terminate, unless +.Fa dstsize +is 0 or the original +.Fa dst +string was longer than +.Fa dstsize +(in practice this should not happen +as it means that either +.Fa dstsize +is incorrect or that +.Fa dst +is not a proper string). +.Pp +If the +.Fa src +and +.Fa dst +strings overlap, the behavior is undefined. .Sh RETURN VALUES -The +Besides quibbles over the return type +.Pf ( Va size_t +versus +.Va int ) +and signal handler safety +.Pf ( Xr snprintf 3 +is not entirely safe on some systems), the +following two are equivalent: +.Bd -literal -offset indent +n = strlcpy(dst, src, len); +n = snprintf(dst, len, "%s", src); +.Ed +.Pp +Like +.Xr snprintf 3 , +the .Fn strlcpy and .Fn strlcat -functions return the total length of the string they tried to -create. +functions return the total length of the string they tried to create. For .Fn strlcpy that means the length of @@ -121,29 +133,12 @@ that means the initial length of plus the length of .Fa src . -While this may seem somewhat confusing, it was done to make -truncation detection simple. .Pp -Note however, that if -.Fn strlcat -traverses -.Fa size -characters without finding a NUL, the length of the string is considered -to be -.Fa size -and the destination string will not be NUL-terminated (since there was -no space for the NUL). -This keeps -.Fn strlcat -from running off the end of a string. -In practice this should not happen (as it means that either -.Fa size -is incorrect or that -.Fa dst -is not a proper -.Dq C -string). -The check exists to prevent potential security problems in incorrect code. +If the return value is +.Cm >= +.Va dstsize , +the output string has been truncated. +It is the caller's responsibility to handle this. .Sh EXAMPLES The following code fragment illustrates the simple case: .Bd -literal -offset indent @@ -169,7 +164,7 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) .Ed .Pp Since it is known how many characters were copied the first time, things -can be sped up a bit by using a copy instead of an append. +can be sped up a bit by using a copy instead of an append: .Bd -literal -offset indent char *dir, *file, pname[MAXPATHLEN]; size_t n; @@ -201,5 +196,5 @@ and .Fn strlcat functions first appeared in .Ox 2.4 , -and made their appearance in +and .Fx 3.3 . diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index ac5907b..07a4537 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -2,18 +2,18 @@ # $FreeBSD$ # sys sources -.PATH: ${.CURDIR}/${LIBC_ARCH}/sys ${.CURDIR}/sys +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/sys ${LIBC_SRCTOP}/sys # Include the generated makefile containing the *complete* list # of syscall names in MIASM. -.include "${.CURDIR}/../../sys/sys/syscall.mk" +.include "${LIBC_SRCTOP}/../../sys/sys/syscall.mk" # Include machine dependent definitions. # # MDASM names override the default syscall names in MIASM. # NOASM will prevent the default syscall code from being generated. # -.sinclude "${.CURDIR}/${LIBC_ARCH}/sys/Makefile.inc" +.sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/sys/Makefile.inc" SRCS+= clock_gettime.c gettimeofday.c __vdso_gettimeofday.c NOASM+= clock_gettime.o gettimeofday.o @@ -21,7 +21,7 @@ PSEUDO+= _clock_gettime.o _gettimeofday.o # Sources common to both syscall interfaces: SRCS+= stack_protector.c stack_protector_compat.c __error.c -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" SYSCALL_COMPAT_SRCS= fcntl.c ftruncate.c lseek.c mmap.c pread.c \ pwrite.c truncate.c SRCS+= ${SYSCALL_COMPAT_SRCS} @@ -55,7 +55,7 @@ SPSEUDO= ${PSEUDO:S/.o/.S/} SRCS+= ${SASM} ${SPSEUDO} -SYM_MAPS+= ${.CURDIR}/sys/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/sys/Symbol.map # Generated files CLEANFILES+= ${SASM} ${SPSEUDO} @@ -85,6 +85,7 @@ MAN+= abort2.2 \ adjtime.2 \ aio_cancel.2 \ aio_error.2 \ + aio_fsync.2 \ aio_mlock.2 \ aio_read.2 \ aio_return.2 \ @@ -300,9 +301,9 @@ MLINKS+=execve.2 fexecve.2 MLINKS+=extattr_get_file.2 extattr.2 \ extattr_get_file.2 extattr_delete_fd.2 \ extattr_get_file.2 extattr_delete_file.2 \ - extattr_get_file.2 extattr_delete_list.2 \ + extattr_get_file.2 extattr_delete_link.2 \ extattr_get_file.2 extattr_get_fd.2 \ - extattr_get_file.2 extattr_get_list.2 \ + extattr_get_file.2 extattr_get_link.2 \ extattr_get_file.2 extattr_list_fd.2 \ extattr_get_file.2 extattr_list_file.2 \ extattr_get_file.2 extattr_list_link.2 \ diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2 index 7b8422a..0363158 100644 --- a/lib/libc/sys/accept.2 +++ b/lib/libc/sys/accept.2 @@ -32,7 +32,8 @@ .Dt ACCEPT 2 .Os .Sh NAME -.Nm accept +.Nm accept , +.Nm accept4 .Nd accept a connection on a socket .Sh LIBRARY .Lb libc diff --git a/lib/libc/sys/aio_fsync.2 b/lib/libc/sys/aio_fsync.2 new file mode 100644 index 0000000..e05bff4 --- /dev/null +++ b/lib/libc/sys/aio_fsync.2 @@ -0,0 +1,153 @@ +.\" Copyright (c) 2013 Sergey Kandaurov +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 27, 2013 +.Dt AIO_FSYNC 2 +.Os +.Sh NAME +.Nm aio_fsync +.Nd asynchronous file synchronization (REALTIME) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In aio.h +.Ft int +.Fn aio_fsync "int op" "struct aiocb *iocb" +.Sh DESCRIPTION +The +.Fn aio_fsync +system call allows the calling process to move all modified data +associated with the descriptor +.Fa iocb->aio_fildes +to a permanent storage device. +The call returns immediately after the synchronization request has been +enqueued to the descriptor; the synchronization may or may not have +completed at the time the call returns. +.Pp +The +.Fa op +argument can only be set to +.Dv O_SYNC +to cause all currently queued I/O operations to be completed +as if by a call to +.Xr fsync 2 . +.Pp +If _POSIX_PRIORITIZED_IO is defined, and the descriptor supports it, +then the enqueued operation is submitted at a priority equal to that +of the calling process minus +.Fa iocb->aio_reqprio . +.Pp +The +.Fa iocb +pointer may be subsequently used as an argument to +.Fn aio_return +and +.Fn aio_error +in order to determine return or error status for the enqueued operation +while it is in progress. +.Pp +If the request could not be enqueued (generally due to invalid arguments), +the call returns without having enqueued the request. +.Sh RETURN VALUES +.Rv -std aio_fsync +.Sh ERRORS +The +.Fn aio_fsync +system call will fail if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The request was not queued because of system resource limitations. +.It Bq Er ENOSYS +The +.Fn aio_fsync +system call is not supported. +.It Bq Er EINVAL +A value of the +.Fa op +argument is not set to +.Dv O_SYNC . +.El +.Pp +The following conditions may be synchronously detected when the +.Fn aio_fsync +system call is made, or asynchronously, at any time thereafter. +If they are detected at call time, +.Fn aio_fsync +returns -1 and sets +.Va errno +appropriately; otherwise the +.Fn aio_return +system call must be called, and will return -1, and +.Fn aio_error +must be called to determine the actual value that would have been +returned in +.Va errno . +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa iocb->aio_fildes +argument +is not a valid descriptor. +.It Bq Er EINVAL +This implementation does not support synchronized I/O for this file. +.El +.Pp +If the request is successfully enqueued, but subsequently cancelled +or an error occurs, the value returned by the +.Fn aio_return +system call is per the +.Xr read 2 +and +.Xr write 2 +system calls, and the value returned by the +.Fn aio_error +system call is one of the error returns from the +.Xr read 2 +or +.Xr write 2 +system calls. +.Sh SEE ALSO +.Xr aio_cancel 2 , +.Xr aio_error 2 , +.Xr aio_read 2 , +.Xr aio_return 2 , +.Xr aio_suspend 2 , +.Xr aio_waitcomplete 2 , +.Xr aio_write 2 , +.Xr fsync 2 , +.Xr siginfo 3 , +.Xr aio 4 +.Sh STANDARDS +The +.Fn aio_fsync +system call is expected to conform to the +.St -p1003.1 +standard. +.Sh HISTORY +The +.Fn aio_fsync +system call first appeared in +.Fx 7.0 . diff --git a/lib/libc/sys/aio_mlock.2 b/lib/libc/sys/aio_mlock.2 index e24f95a..386393f 100644 --- a/lib/libc/sys/aio_mlock.2 +++ b/lib/libc/sys/aio_mlock.2 @@ -87,7 +87,7 @@ request has completed, are not allowed. .Rv -std aio_mlock .Sh ERRORS The -.Fn aio_read +.Fn aio_mlock system call will fail if: .Bl -tag -width Er .It Bq Er EAGAIN diff --git a/lib/libc/sys/cap_enter.2 b/lib/libc/sys/cap_enter.2 index 3369669..807d7ed 100644 --- a/lib/libc/sys/cap_enter.2 +++ b/lib/libc/sys/cap_enter.2 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 25, 2012 +.Dd March 27, 2014 .Dt CAP_ENTER 2 .Os .Sh NAME @@ -38,7 +38,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/capability.h +.In sys/capsicum.h .Ft int .Fn cap_enter "void" .Ft int @@ -52,7 +52,7 @@ Access to global name spaces, such as file system or IPC name spaces, is prevented. If the process is already in a capability mode sandbox, the system call is a no-op. -Future process descendants create with +Future process descendants created with .Xr fork 2 or .Xr pdfork 2 diff --git a/lib/libc/sys/cap_fcntls_limit.2 b/lib/libc/sys/cap_fcntls_limit.2 index b1fca2c..0f792a5 100644 --- a/lib/libc/sys/cap_fcntls_limit.2 +++ b/lib/libc/sys/cap_fcntls_limit.2 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 20, 2012 +.Dd March 27, 2014 .Dt CAP_FCNTLS_LIMIT 2 .Os .Sh NAME @@ -38,7 +38,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/capability.h +.In sys/capsicum.h .Ft int .Fn cap_fcntls_limit "int fd" "uint32_t fcntlrights" .Ft int diff --git a/lib/libc/sys/cap_ioctls_limit.2 b/lib/libc/sys/cap_ioctls_limit.2 index 771736a..4fdd255 100644 --- a/lib/libc/sys/cap_ioctls_limit.2 +++ b/lib/libc/sys/cap_ioctls_limit.2 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 20, 2012 +.Dd March 27, 2014 .Dt CAP_IOCTLS_LIMIT 2 .Os .Sh NAME @@ -38,7 +38,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/capability.h +.In sys/capsicum.h .Ft int .Fn cap_ioctls_limit "int fd" "const unsigned long *cmds" "size_t ncmds" .Ft ssize_t @@ -58,7 +58,7 @@ argument is an array of commands and the .Fa ncmds argument specifies the number of elements in the array. -There might be up to +There can be up to .Va 256 elements in the array. .Pp @@ -92,7 +92,7 @@ system call was never called for this file descriptor), the .Fn cap_ioctls_get system call will return .Dv CAP_IOCTLS_ALL -and won't modify the buffer pointed out by the +and won't modify the buffer pointed to by the .Fa cmds argument. .Sh RETURN VALUES @@ -100,7 +100,7 @@ argument. .Pp The .Fn cap_ioctls_get -function, if successfull, returns the total number of allowed ioctl commands or +function, if successful, returns the total number of allowed ioctl commands or the value .Dv CAP_IOCTLS_ALL if all ioctls commands are allowed. diff --git a/lib/libc/sys/cap_rights_limit.2 b/lib/libc/sys/cap_rights_limit.2 index 225efad..33b57e1 100644 --- a/lib/libc/sys/cap_rights_limit.2 +++ b/lib/libc/sys/cap_rights_limit.2 @@ -32,23 +32,22 @@ .\" .\" $FreeBSD$ .\" -.Dd February 23, 2013 +.Dd March 27, 2014 .Dt CAP_RIGHTS_LIMIT 2 .Os .Sh NAME -.Nm cap_rights_limit , -.Nm cap_rights_get -.Nd manage capability rights +.Nm cap_rights_limit +.Nd limit capability rights .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/capability.h +.In sys/capsicum.h .Ft int -.Fn cap_rights_limit "int fd" "cap_rights_t rights" -.Ft int -.Fn cap_rights_get "int fd" "cap_rights_t *rightsp" +.Fn cap_rights_limit "int fd" "const cap_rights_t *rights" .Sh DESCRIPTION When a file descriptor is created by a function such as +.Xr accept 2 , +.Xr accept4 2 , .Xr fhopen 2 , .Xr kqueue 2 , .Xr mq_open 2 , @@ -57,7 +56,7 @@ When a file descriptor is created by a function such as .Xr pdfork 2 , .Xr pipe 2 , .Xr shm_open 2 , -.Xr socket 2 , +.Xr socket 2 or .Xr socketpair 2 , it is assigned all capability rights. @@ -68,429 +67,48 @@ Once capability rights are reduced, operations on the file descriptor will be limited to those permitted by .Fa rights . .Pp -A bitmask of capability rights assigned to a file descriptor can be obtained with -the -.Fn cap_rights_get -system call. -.Sh RIGHTS -The following rights may be specified in a rights mask: -.Bl -tag -width CAP_EXTATTR_DELETE -.It Dv CAP_ACCEPT -Permit -.Xr accept 2 -and -.Xr accept4 2 . -.It Dv CAP_ACL_CHECK -Permit checking of an ACL on a file descriptor; there is no cross-reference -for this system call. -.It Dv CAP_ACL_DELETE -Permit -.Xr acl_delete_fd_np 3 . -.It Dv CAP_ACL_GET -Permit -.Xr acl_get_fd 3 -and -.Xr acl_get_fd_np 3 . -.It Dv CAP_ACL_SET -Permit -.Xr acl_set_fd 3 -and -.Xr acl_set_fd_np 3 . -.It Dv CAP_BIND -Permit -.Xr bind 2 . -Note that sockets can also become bound implicitly as a result of -.Xr connect 2 -or -.Xr send 2 , -and that socket options set with -.Xr setsockopt 2 -may also affect binding behavior. -.It Dv CAP_BINDAT -Permit -.Xr bindat 2 . -This right has to be present on the directory descriptor. -.It Dv CAP_CONNECT -Permit -.Xr connect 2 ; -also required for -.Xr sendto 2 -with a non-NULL destination address. -.It Dv CAP_CONNECTAT -Permit -.Xr connectat 2 . -This right has to be present on the directory descriptor. -.It Dv CAP_CREATE -Permit -.Xr openat 2 -with the -.Dv O_CREAT -flag. -.\" XXXPJD: Doesn't exist anymore. -.It Dv CAP_EVENT -Permit -.Xr select 2 , -.Xr poll 2 , -and -.Xr kevent 2 -to be used in monitoring the file descriptor for events. -.It Dv CAP_FEXECVE -Permit -.Xr fexecve 2 -and -.Xr openat 2 -with the -.Dv O_EXEC -flag; -.Dv CAP_READ -will also be required. -.It Dv CAP_EXTATTR_DELETE -Permit -.Xr extattr_delete_fd 2 . -.It Dv CAP_EXTATTR_GET -Permit -.Xr extattr_get_fd 2 . -.It Dv CAP_EXTATTR_LIST -Permit -.Xr extattr_list_fd 2 . -.It Dv CAP_EXTATTR_SET -Permit -.Xr extattr_set_fd 2 . -.It Dv CAP_FCHDIR -Permit -.Xr fchdir 2 . -.It Dv CAP_FCHFLAGS -Permit -.Xr fchflags 2 -and -.Xr chflagsat 2 . -.It Dv CAP_CHFLAGSAT -An alias to -.Dv CAP_FCHFLAGS . -.It Dv CAP_FCHMOD -Permit -.Xr fchmod 2 -and -.Xr fchmodat 2 . -.It Dv CAP_FCHMODAT -An alias to -.Dv CAP_FCHMOD . -.It Dv CAP_FCHOWN -Permit -.Xr fchown 2 -and -.Xr fchownat 2 . -.It Dv CAP_FCHOWNAT -An alias to -.Dv CAP_FCHOWN . -.It Dv CAP_FCNTL -Permit -.Xr fcntl 2 . -Note that only the -.Dv F_GETFL , -.Dv F_SETFL , -.Dv F_GETOWN -and -.Dv F_SETOWN -commands require this capability right. -Also note that the list of permitted commands can be further limited with the -.Xr cap_fcntls_limit 2 -system call. -.It Dv CAP_FLOCK -Permit -.Xr flock 2 , -.Xr fcntl 2 -(with -.Dv F_GETLK , -.Dv F_SETLK -or -.Dv F_SETLKW -flag) and -.Xr openat 2 -(with -.Dv O_EXLOCK -or -.Dv O_SHLOCK -flag). -.It Dv CAP_FPATHCONF -Permit -.Xr fpathconf 2 . -.It Dv CAP_FSCK -Permit UFS background-fsck operations on the descriptor. -.It Dv CAP_FSTAT -Permit -.Xr fstat 2 -and -.Xr fstatat 2 . -.It Dv CAP_FSTATAT -An alias to -.Dv CAP_FSTAT . -.It Dv CAP_FSTATFS -Permit -.Xr fstatfs 2 . -.It Dv CAP_FSYNC -Permit -.Xr aio_fsync 2 , -.Xr fsync 2 -and -.Xr openat 2 -with -.Dv O_FSYNC -or -.Dv O_SYNC -flag. -.It Dv CAP_FTRUNCATE -Permit -.Xr ftruncate 2 -and -.Xr openat 2 -with the -.Dv O_TRUNC -flag. -.It Dv CAP_FUTIMES -Permit -.Xr futimes 2 -and -.Xr futimesat 2 . -.It Dv CAP_FUTIMESAT -An alias to -.Dv CAP_FUTIMES . -.It Dv CAP_GETPEERNAME -Permit -.Xr getpeername 2 . -.It Dv CAP_GETSOCKNAME -Permit -.Xr getsockname 2 . -.It Dv CAP_GETSOCKOPT -Permit -.Xr getsockopt 2 . -.It Dv CAP_IOCTL -Permit -.Xr ioctl 2 . -Be aware that this system call has enormous scope, including potentially -global scope for some objects. -The list of permitted ioctl commands can be further limited with the -.Xr cap_ioctls_limit 2 -system call. -.\" XXXPJD: Doesn't exist anymore. -.It Dv CAP_KEVENT -Permit -.Xr kevent 2 ; -.Dv CAP_EVENT -is also required on file descriptors that will be monitored using -.Xr kevent 2 . -.It Dv CAP_LINKAT -Permit -.Xr linkat 2 -and -.Xr renameat 2 . -This right is required for the destination directory descriptor. -.It Dv CAP_LISTEN -Permit -.Xr listen 2 ; -not much use (generally) without -.Dv CAP_BIND . -.It Dv CAP_LOOKUP -Permit the file descriptor to be used as a starting directory for calls such as -.Xr linkat 2 , -.Xr openat 2 , -and -.Xr unlinkat 2 . -.It Dv CAP_MAC_GET -Permit -.Xr mac_get_fd 3 . -.It Dv CAP_MAC_SET -Permit -.Xr mac_set_fd 3 . -.It Dv CAP_MKDIRAT -Permit -.Xr mkdirat 2 . -.It Dv CAP_MKFIFOAT -Permit -.Xr mkfifoat 2 . -.It Dv CAP_MKNODAT -Permit -.Xr mknodat 2 . -.It Dv CAP_MMAP -Permit -.Xr mmap 2 -with the -.Dv PROT_NONE -protection. -.It Dv CAP_MMAP_R -Permit -.Xr mmap 2 -with the -.Dv PROT_READ -protection. -This also implies -.Dv CAP_READ -and -.Dv CAP_SEEK -rights. -.It Dv CAP_MMAP_W -Permit -.Xr mmap 2 -with the -.Dv PROT_WRITE -protection. -This also implies -.Dv CAP_WRITE -and -.Dv CAP_SEEK -rights. -.It Dv CAP_MMAP_X -Permit -.Xr mmap 2 -with the -.Dv PROT_EXEC -protection. -This also implies -.Dv CAP_SEEK -right. -.It Dv CAP_MMAP_RW -Implies -.Dv CAP_MMAP_R -and -.Dv CAP_MMAP_W . -.It Dv CAP_MMAP_RX -Implies -.Dv CAP_MMAP_R -and -.Dv CAP_MMAP_X . -.It Dv CAP_MMAP_WX -Implies -.Dv CAP_MMAP_W -and -.Dv CAP_MMAP_X . -.It Dv CAP_MMAP_RWX -Implies -.Dv CAP_MMAP_R , -.Dv CAP_MMAP_W -and -.Dv CAP_MMAP_X . -.It Dv CAP_PDGETPID -Permit -.Xr pdgetpid 2 . -.It Dv CAP_PDKILL -Permit -.Xr pdkill 2 . -.It Dv CAP_PDWAIT -Permit -.Xr pdwait4 2 . -.It Dv CAP_PEELOFF -Permit -.Xr sctp_peeloff 2 . -.\" XXXPJD: Not documented. -.It Dv CAP_POLL_EVENT -.\" XXXPJD: Not documented. -.It Dv CAP_POST_EVENT -.It Dv CAP_PREAD -Implies -.Dv CAP_SEEK -and -.Dv CAP_READ . -.It Dv CAP_PWRITE -Implies -.Dv CAP_SEEK -and -.Dv CAP_WRITE . -.It Dv CAP_READ -Allow -.Xr aio_read 2 , -.Xr openat -with the -.Dv O_RDONLY flag, -.Xr read 2 , -.Xr recv 2 , -.Xr recvfrom 2 , -.Xr recvmsg 2 -and related system calls. -.It Dv CAP_RECV -An alias to -.Dv CAP_READ . -.It Dv CAP_RENAMEAT -Permit -.Xr renameat 2 . -This right is required for the source directory descriptor. -.It Dv CAP_SEEK -Permit operations that seek on the file descriptor, such as -.Xr lseek 2 , -but also required for I/O system calls that can read or write at any position -in the file, such as -.Xr pread 2 -and -.Xr pwrite 2 . -.It Dv CAP_SEM_GETVALUE -Permit -.Xr sem_getvalue 3 . -.It Dv CAP_SEM_POST -Permit -.Xr sem_post 3 . -.It Dv CAP_SEM_WAIT -Permit -.Xr sem_wait 3 -and -.Xr sem_trywait 3 . -.It Dv CAP_SEND -An alias to -.Dv CAP_WRITE . -.It Dv CAP_SETSOCKOPT -Permit -.Xr setsockopt 2 ; -this controls various aspects of socket behavior and may affect binding, -connecting, and other behaviors with global scope. -.It Dv CAP_SHUTDOWN -Permit explicit -.Xr shutdown 2 ; -closing the socket will also generally shut down any connections on it. -.It Dv CAP_SYMLINKAT -Permit -.Xr symlinkat 2 . -.It Dv CAP_TTYHOOK -Allow configuration of TTY hooks, such as -.Xr snp 4 , -on the file descriptor. -.It Dv CAP_UNLINKAT -Permit -.Xr unlinkat 2 -and -.Xr renameat 2 . -This right is only required for -.Xr renameat 2 -on the destination directory descriptor if the destination object already -exists and will be removed by the rename. -.It Dv CAP_WRITE -Allow -.Xr aio_write 2 , -.Xr openat 2 -with -.Dv O_WRONLY -and -.Dv O_APPEND -flags, -.Xr send 2 , -.Xr sendmsg 2 , -.Xr sendto 2 , -.Xr write 2 , -and related system calls. -For -.Xr sendto 2 -with a non-NULL connection address, -.Dv CAP_CONNECT -is also required. -For -.Xr openat 2 -with the -.Dv O_WRONLY -flag, but without the -.Dv O_APPEND -flag, -.Dv CAP_SEEK -is also required. -.El +The +.Fa rights +argument should be prepared using +.Xr cap_rights_init 3 +family of functions. +.Pp +Capability rights assigned to a file descriptor can be obtained with the +.Xr cap_rights_get 3 +function. +.Pp +The complete list of the capability rights can be found in the +.Xr rights 4 +manual page. .Sh RETURN VALUES .Rv -std +.Sh EXAMPLES +The following example demonstrates how to limit file descriptor capability +rights to allow reading only. +.Bd -literal +cap_rights_t setrights; +char buf[1]; +int fd; + +fd = open("/tmp/foo", O_RDWR); +if (fd < 0) + err(1, "open() failed"); + +if (cap_enter() < 0) + err(1, "cap_enter() failed"); + +cap_rights_init(&setrights, CAP_READ); +if (cap_rights_limit(fd, &setrights) < 0) + err(1, "cap_rights_limit() failed"); + +buf[0] = 'X'; + +if (write(fd, buf, sizeof(buf)) > 0) + errx(1, "write() succeeded!"); + +if (read(fd, buf, sizeof(buf)) < 0) + err(1, "read() failed"); +.Ed .Sh ERRORS .Fn cap_rights_limit succeeds unless: @@ -503,106 +121,32 @@ argument is not a valid active descriptor. An invalid right has been requested in .Fa rights . .It Bq Er ENOTCAPABLE -.Fa rights -contains requested rights not present in the current rights mask associated -with the given file descriptor. -.El -.Pp -.Fn cap_rights_get -succeeds unless: -.Bl -tag -width Er -.It Bq Er EBADF The -.Fa fd -argument is not a valid active descriptor. -.It Bq Er EFAULT -The -.Fa rightsp -argument points at an invalid address. +.Fa rights +argument contains capability rights not present for the given file descriptor. +Capability rights list can only be reduced, never expanded. .El .Sh SEE ALSO .Xr accept 2 , -.Xr aio_fsync 2 , -.Xr aio_read 2 , -.Xr aio_write 2 , -.Xr bind 2 , -.Xr bindat 2 , +.Xr accept4 2 , .Xr cap_enter 2 , -.Xr cap_fcntls_limit 2 , -.Xr cap_ioctls_limit 2 , -.Xr cap_rights_limit 2 , -.Xr connect 2 , -.Xr connectat 2 , -.Xr dup 2 , -.Xr dup2 2 , -.Xr extattr_delete_fd 2 , -.Xr extattr_get_fd 2 , -.Xr extattr_list_fd 2 , -.Xr extattr_set_fd 2 , -.Xr fchflags 2 , -.Xr fchown 2 , -.Xr fcntl 2 , -.Xr fexecve 2 , .Xr fhopen 2 , -.Xr flock 2 , -.Xr fpathconf 2 , -.Xr fstat 2 , -.Xr fstatfs 2 , -.Xr fsync 2 , -.Xr ftruncate 2 , -.Xr futimes 2 , -.Xr getpeername 2 , -.Xr getsockname 2 , -.Xr getsockopt 2 , -.Xr ioctl 2 , -.Xr kevent 2 , .Xr kqueue 2 , -.Xr linkat 2 , -.Xr listen 2 , -.Xr mmap 2 , .Xr mq_open 2 , .Xr open 2 , .Xr openat 2 , .Xr pdfork 2 , -.Xr pdgetpid 2 , -.Xr pdkill 2 , -.Xr pdwait4 2 , .Xr pipe 2 , -.Xr poll 2 , -.Xr pread 2 , -.Xr pwrite 2 , .Xr read 2 , -.Xr recv 2 , -.Xr recvfrom 2 , -.Xr recvmsg 2 , -.Xr renameat 2 , -.Xr sctp_peeloff 2 , -.Xr select 2 , -.Xr send 2 , -.Xr sendmsg 2 , -.Xr sendto 2 , -.Xr setsockopt 2 , .Xr shm_open 2 , -.Xr shutdown 2 , .Xr socket 2 , .Xr socketpair 2 , -.Xr symlinkat 2 , -.Xr unlinkat 2 , .Xr write 2 , -.Xr acl_delete_fd_np 3 , -.Xr acl_get_fd 3 , -.Xr acl_get_fd_np 3 , -.Xr acl_set_fd_np 3 , -.Xr cap_limitfd 3 , -.Xr libcapsicum 3 , -.Xr mac_get_fd 3 , -.Xr mac_set_fd 3 , -.Xr sem_getvalue 3 , -.Xr sem_post 3 , -.Xr sem_trywait 3 , -.Xr sem_wait 3 , +.Xr cap_rights_get 3 , +.Xr cap_rights_init 3 , +.Xr err 3 , .Xr capsicum 4 , -.Xr snp 4 +.Xr rights 4 .Sh HISTORY Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD @@ -611,9 +155,3 @@ Project. This function was created by .An Pawel Jakub Dawidek Aq pawel@dawidek.net under sponsorship of the FreeBSD Foundation. -.Sh BUGS -This man page should list the set of permitted system calls more specifically -for each capability right. -.Pp -Capability rights sometimes have unclear indirect impacts, which should be -documented, or at least hinted at. diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2 index 2fcc89f..8dc14bd 100644 --- a/lib/libc/sys/chflags.2 +++ b/lib/libc/sys/chflags.2 @@ -34,7 +34,8 @@ .Sh NAME .Nm chflags , .Nm lchflags , -.Nm fchflags +.Nm fchflags , +.Nm chflagsat .Nd set file flags .Sh LIBRARY .Lb libc diff --git a/lib/libc/sys/chmod.2 b/lib/libc/sys/chmod.2 index 997df88e..332cf3a 100644 --- a/lib/libc/sys/chmod.2 +++ b/lib/libc/sys/chmod.2 @@ -28,7 +28,7 @@ .\" @(#)chmod.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 10, 2008 +.Dd December 1, 2013 .Dt CHMOD 2 .Os .Sh NAME @@ -139,21 +139,24 @@ defined in #define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ -#ifndef __BSD_VISIBLE -#define S_ISTXT 0001000 /* sticky bit */ -#endif +#define S_ISVTX 0001000 /* sticky bit */ .Ed .Pp +The non-standard +.Dv S_ISTXT +is a synonym for +.Dv S_ISVTX . +.Pp The .Fx VM system totally ignores the sticky bit -.Pq Dv ISTXT +.Pq Dv S_ISVTX for executables. On UFS-based file systems (FFS, LFS) the sticky bit may only be set upon directories. .Pp If mode -.Dv ISTXT +.Dv S_ISVTX (the `sticky bit') is set on a directory, an unprivileged user may not delete or rename files of other users in that directory. @@ -296,12 +299,15 @@ The system call is expected to conform to .St -p1003.1-90 , except for the return of -.Er EFTYPE -and the use of -.Dv S_ISTXT . +.Er EFTYPE . +The +.Dv S_ISVTX +bit on directories is expected to conform to +.St -susv3 . The .Fn fchmodat -system call follows The Open Group Extended API Set 2 specification. +system call is expected to conform to +.St -p1003.1-2008 . .Sh HISTORY The .Fn chmod diff --git a/lib/libc/sys/cpuset.2 b/lib/libc/sys/cpuset.2 index 5a1d695..3e76de3 100644 --- a/lib/libc/sys/cpuset.2 +++ b/lib/libc/sys/cpuset.2 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 8, 2010 +.Dd February 14, 2014 .Dt CPUSET 2 .Os .Sh NAME @@ -98,6 +98,7 @@ argument may have the following values: .Bl -column CPU_WHICH_CPUSET -offset indent .It Dv CPU_WHICH_TID Ta "id is lwpid_t (thread id)" .It Dv CPU_WHICH_PID Ta "id is pid_t (process id)" +.It Dv CPU_WHICH_JAIL Ta "id is jid (jail id)" .It Dv CPU_WHICH_CPUSET Ta "id is a cpusetid_t (cpuset id)" .It Dv CPU_WHICH_IRQ Ta "id is an irq number" .El diff --git a/lib/libc/sys/getrlimit.2 b/lib/libc/sys/getrlimit.2 index 35198bc..1f84bfb 100644 --- a/lib/libc/sys/getrlimit.2 +++ b/lib/libc/sys/getrlimit.2 @@ -108,6 +108,8 @@ Please see for a complete description of this sysctl. .It Dv RLIMIT_NPTS The maximum number of pseudo-terminals created by this user id. +.It Dv RLIMIT_KQUEUES +The maximum number of kqueues created by this user id. .El .Pp A resource limit is specified as a soft limit and a hard limit. diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2 index ed3a8ad..b9e496a 100644 --- a/lib/libc/sys/kqueue.2 +++ b/lib/libc/sys/kqueue.2 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 21, 2013 +.Dd April 7, 2014 .Dt KQUEUE 2 .Os .Sh NAME @@ -245,7 +245,7 @@ Arguments may be passed to and from the filter via the and .Va data fields in the kevent structure. -.Bl -tag -width EVFILT_SIGNAL +.Bl -tag -width EVFILT_PROCDESC .It EVFILT_READ Takes a descriptor as the identifier, and returns whenever there is data available to read. @@ -412,6 +412,24 @@ and the child process will not signal a NOTE_CHILD event. On return, .Va fflags contains the events which triggered the filter. +.It EVFILT_PROCDESC +Takes the process descriptor created by +.Xr pdfork 2 +to monitor as the identifier and the events to watch for in +.Va fflags , +and returns when the associated process performs one or more of the +requested events. +The events to monitor are: +.Bl -tag -width XXNOTE_EXIT +.It NOTE_EXIT +The process has exited. +The exit status will be stored in +.Va data . +.El +.Pp +On return, +.Va fflags +contains the events which triggered the filter. .It EVFILT_SIGNAL Takes the signal number to monitor as the identifier and returns when the given signal is delivered to the process. @@ -532,6 +550,13 @@ system call fails if: .Bl -tag -width Er .It Bq Er ENOMEM The kernel failed to allocate enough memory for the kernel queue. +.It Bq Er ENOMEM +The +.Dv RLIMIT_KQUEUES +rlimit +(see +.Xr getrlimit 2 ) +for the current user would be exceeded. .It Bq Er EMFILE The per-process descriptor table is full. .It Bq Er ENFILE diff --git a/lib/libc/sys/madvise.2 b/lib/libc/sys/madvise.2 index b5ea6b2..357e05e 100644 --- a/lib/libc/sys/madvise.2 +++ b/lib/libc/sys/madvise.2 @@ -28,7 +28,7 @@ .\" @(#)madvise.2 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd July 19, 1996 +.Dd January 30, 2014 .Dt MADVISE 2 .Os .Sh NAME @@ -50,7 +50,10 @@ allows a process that has knowledge of its memory behavior to describe it to the system. The .Fn posix_madvise -interface is identical and is provided for standards conformance. +interface is identical, except it returns an error number on error and does +not modify +.Va errno , +and is provided for standards conformance. .Pp The known behaviors are: .Bl -tag -width MADV_SEQUENTIAL diff --git a/lib/libc/sys/mq_getattr.2 b/lib/libc/sys/mq_getattr.2 index 77253fc..fc42d59 100644 --- a/lib/libc/sys/mq_getattr.2 +++ b/lib/libc/sys/mq_getattr.2 @@ -37,7 +37,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 29, 2005 +.Dd February 21, 2014 .Dt MQ_GETATTR 2 .Os .Sh NAME @@ -83,8 +83,8 @@ structure referenced by the .Fa mqstat argument will be set to the current state of the message queue: -.Bl -tag -width ".Va mq_flags" -.It Va mq_flags +.Bl -tag -width ".Va mq_curmsgs" +.It Va mq_curmsgs The number of messages currently on the queue. .El .Sh RETURN VALUES diff --git a/lib/libc/sys/pdfork.2 b/lib/libc/sys/pdfork.2 index 26d0eb0..a489515 100644 --- a/lib/libc/sys/pdfork.2 +++ b/lib/libc/sys/pdfork.2 @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 28, 2013 +.Dd April 7, 2014 .Dt PDFORK 2 .Os .Sh NAME @@ -45,7 +45,7 @@ .Lb libc .Sh SYNOPSIS .In sys/procdesc.h -.Ft int +.Ft pid_t .Fn pdfork "int *fdp" "int flags" .Ft int .Fn pdgetpid "int fd" "pid_t *pidp" @@ -117,6 +117,13 @@ and allow waiting for process state transitions; currently only .Dv POLLHUP is defined, and will be raised when the process dies. +Process state transitions can also be monitored using +.Xr kqueue 2 +filter +.Dv EVFILT_PROCDESC ; +currently only +.Dv NOTE_EXIT +is implemented. .Pp .Xr close 2 will close the process descriptor unless @@ -125,12 +132,6 @@ is set; if the process is still alive and this is the last reference to the process descriptor, the process will be terminated with the signal .Dv SIGKILL . -.Pp -.Nm -and associated functions depend on -.Cd "options PROCDESC" -described in -.Xr procdesc 4 . .Sh RETURN VALUES .Fn pdfork returns a PID, 0 or -1, as diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2 index 6ea0f14..b4b170c 100644 --- a/lib/libc/sys/pipe.2 +++ b/lib/libc/sys/pipe.2 @@ -32,7 +32,8 @@ .Dt PIPE 2 .Os .Sh NAME -.Nm pipe +.Nm pipe , +.Nm pipe2 .Nd create descriptor pair for interprocess communication .Sh LIBRARY .Lb libc diff --git a/lib/libc/sys/posix_fadvise.2 b/lib/libc/sys/posix_fadvise.2 index 7a9a648..8691f6b 100644 --- a/lib/libc/sys/posix_fadvise.2 +++ b/lib/libc/sys/posix_fadvise.2 @@ -28,7 +28,7 @@ .\" @(#)madvise.2 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd June 19, 2012 +.Dd January 30, 2014 .Dt POSIX_FADVISE 2 .Os .Sh NAME @@ -93,7 +93,7 @@ Future access to this data may require a read operation. .Sh ERRORS The .Fn posix_fadvise -system call will fail if: +system call returns zero on success, and an error on failure: .Bl -tag -width Er .It Bq Er EBADF The diff --git a/lib/libc/sys/posix_fallocate.2 b/lib/libc/sys/posix_fallocate.2 index 087c68c..7501777 100644 --- a/lib/libc/sys/posix_fallocate.2 +++ b/lib/libc/sys/posix_fallocate.2 @@ -28,7 +28,7 @@ .\" @(#)open.2 8.2 (Berkeley) 11/16/93 .\" $FreeBSD$ .\" -.Dd February 25, 2012 +.Dd January 23, 2014 .Dt POSIX_FALLOCATE 2 .Os .Sh NAME @@ -83,9 +83,8 @@ that reduces the file size to a size smaller than If successful, .Fn posix_fallocate returns zero. -It returns -1 on failure, and sets -.Va errno -to indicate the error. +It returns an error on failure, without setting +.Va errno . .Sh ERRORS Possible failure conditions: .Bl -tag -width Er @@ -107,7 +106,7 @@ A signal was caught during execution. .It Bq Er EINVAL The .Fa len -argument was zero or the +argument was less than or equal to zero or the .Fa offset argument was less than zero. .It Bq Er EIO diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index 32bf34d..8f553ea 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -139,4 +139,4 @@ command. The .Fn procctl function appeared in -.Fx 10 . +.Fx 10.0 . diff --git a/lib/libc/sys/shm_open.2 b/lib/libc/sys/shm_open.2 index a521e58..76d8f3c 100644 --- a/lib/libc/sys/shm_open.2 +++ b/lib/libc/sys/shm_open.2 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 20, 2007 +.Dd December 18, 2013 .Dt SHM_OPEN 2 .Os .Sh NAME @@ -253,8 +253,8 @@ requires write permission to the shared memory object. .El .Sh SEE ALSO .Xr close 2 , -.Xr ftruncate 2 , .Xr fstat 2 , +.Xr ftruncate 2 , .Xr mmap 2 , .Xr munmap 2 .Sh STANDARDS @@ -273,7 +273,7 @@ functions first appeared in .Fx 4.3 . The functions were reimplemented as system calls using shared memory objects directly rather than files in -.Fx 7.0 . +.Fx 8.0 . .Sh AUTHORS .An Garrett A. Wollman Aq wollman@FreeBSD.org (C library support and this manual page) diff --git a/lib/libc/sys/swapon.2 b/lib/libc/sys/swapon.2 index b3e4474..6879513 100644 --- a/lib/libc/sys/swapon.2 +++ b/lib/libc/sys/swapon.2 @@ -28,7 +28,7 @@ .\" @(#)swapon.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd October 4, 2013 .Dt SWAPON 2 .Os .Sh NAME @@ -98,10 +98,6 @@ Additionally, .Fn swapon can fail for the following reasons: .Bl -tag -width Er -.It Bq Er EINVAL -The system has reached the boot-time limit on the number of -swap devices, -.Va vm.nswapdev . .It Bq Er ENOTBLK The .Fa special diff --git a/lib/libc/sys/sync.2 b/lib/libc/sys/sync.2 index ff588ff..06d5e93 100644 --- a/lib/libc/sys/sync.2 +++ b/lib/libc/sys/sync.2 @@ -52,7 +52,7 @@ As information in the cache is lost after a system crash, a .Fn sync system call is issued frequently -by the user process +by the kernel process .Xr syncer 4 (about every 30 seconds). .Pp diff --git a/lib/libc/sys/wait.2 b/lib/libc/sys/wait.2 index cfa78e9..84b2b1a 100644 --- a/lib/libc/sys/wait.2 +++ b/lib/libc/sys/wait.2 @@ -28,7 +28,7 @@ .\" @(#)wait.2 8.2 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd September 7, 2013 +.Dd December 3, 2013 .Dt WAIT 2 .Os .Sh NAME @@ -48,7 +48,7 @@ .Fn wait "int *status" .Ft pid_t .Fn waitpid "pid_t wpid" "int *status" "int options" -.In sys/signal.h +.In signal.h .Ft int .Fn waitid "idtype_t idtype" "id_t id" "siginfo_t *info" "int options" .In sys/time.h @@ -62,63 +62,76 @@ .Sh DESCRIPTION The .Fn wait -function suspends execution of its calling process until +function suspends execution of its calling thread until .Fa status -information is available for a terminated child process, +information is available for a child process or a signal is received. On return from a successful .Fn wait call, the .Fa status -area contains termination information about the process that exited +area contains information about the process that reported a status change as defined below. -The -.Fn wait -call is the same as -.Fn wait4 -with a -.Fa wpid -value of -1, -with an -.Fa options -value of zero, -and a -.Fa rusage -value of zero. .Pp The .Fn wait4 -system call provides a more general interface for programs -that need to wait for certain child processes, +and +.Fn wait6 +system calls provide a more general interface for programs +that need to wait for specific child processes, that need resource utilization statistics accumulated by child processes, or that require options. +The other wait functions are implemented using either +.Fn wait4 +or +.Fn wait6 . .Pp -The broadest interface of all functions in this family is +The .Fn wait6 -which is otherwise very much like +function is the most general function in this family and its distinct +features are: +.Pp +All of the desired process statuses to be waited on must be explicitly +specified in +.Fa options . +The +.Fn wait , +.Fn waitpid , +.Fn wait3 , +and .Fn wait4 -but with a few very important distinctions. -To wait for exited processes, the option flag +functions all implicitly wait for exited and trapped processes, +but the +.Fn waitid +and +.Fn wait6 +functions require the corresponding .Dv WEXITED -need to be explicitly specified. -This allows for waiting for processes which have experienced other -status changes without having to handle also the exit status from -the terminated processes. -Instead of the traditional -.Dv rusage -argument, a pointer to a new structure +and +.Dv WTRAPPED +flags to be explicitly specified. +This allows waiting for processes which have experienced other +status changes without having to also handle the exit status from +terminated processes. +.Pp +The +.Fn wait6 +function accepts a +.Fa wrusage +argument which points to a structure defined as: .Bd -literal struct __wrusage { struct rusage wru_self; struct rusage wru_children; }; .Ed -can be passed. +.Pp This allows the calling process to collect resource usage statistics from both its own child process as well as from its grand children. When no resource usage statistics are needed this pointer can be .Dv NULL . +.Pp The last argument .Fa infop must be either @@ -126,11 +139,13 @@ must be either or a pointer to a .Fa siginfo_t structure. -When specified, the structure is filled the same as for -.Dv SIGNCHLD -signal, delivered at the process state change. -.br -The process, which state is queried, is specified by two arguments +If +.Pf non- Dv NULL , +the structure is filled with the same data as for a +.Dv SIGCHLD +signal delivered when the process changed state. +.Pp +The set of child processes to be queried is specified by the arguments .Fa idtype and .Fa id . @@ -138,8 +153,8 @@ The separate .Fa idtype and .Fa id -arguments allows to support many other types of -IDs as well in addition to PID and PGID. +arguments support many other types of +identifers in addition to process IDs and process group IDs. .Bl -bullet -offset indent .It If @@ -188,50 +203,33 @@ and wait for any child process in the same process group as the caller. .El .Pp -Non-standard specifiers for the process to wait for, supported by this +Non-standard identifier types supported by this implementation of .Fn waitid and -.Fn wait6 , +.Fn wait6 are: -.Bl -bullet -offset indent -.It -The -.Fa idtype -value -.Dv P_UID -waits for processes which effective UID is equal to -.Dv (uid_t)id . -.It -The -.Fa idtype -value -.Dv P_GID -waits for processes which effective GID is equal to -.Dv (gid_t)id . -.It -The -.Fa idtype -value -.Dv P_SID -waits for processes which session ID is equal to -.Dv id . -In case the child process started its own new session, -SID will be the same as its own PID. -Otherwise the SID of a child process will match the caller's SID. -.It -The -.Fa idtype -value -.Dv P_JAILID -waits for processes within a jail which jail identifier is equal -to -.Dv id . +.Bl -tag -width P_JAILID +.It Dv P_UID +Wait for processes whose effective user ID is equal to +.Dv (uid_t) Fa id . +.It Dv P_GID +Wait for processes whose effective group ID is equal to +.Dv (gid_t) Fa id . +.It Dv P_SID +Wait for processes whose session ID is equal to +.Fa id . +.\" This is just how sessions work, not sure this needs to be documented here +If the child process started its own session, +its session ID will be the same as its process ID. +Otherwise the session ID of a child process will match the caller's session ID. +.It Dv P_JAILID +Waits for processes within a jail whose jail identifier is equal to +.Fa id . .El .Pp -For -.Fn wait , -.Fn wait3 , +For the +.Fn waitpid and .Fn wait4 functions, the single @@ -250,12 +248,12 @@ the call waits for any child process in the process group of the caller. .It If .Fa wpid -is greater than zero, the call waits for the process with process id +is greater than zero, the call waits for the process with process ID .Fa wpid . .It If .Fa wpid -is less than -1, the call waits for any process whose process group id +is less than -1, the call waits for any process whose process group ID equals the absolute value of .Fa wpid . .El @@ -267,30 +265,44 @@ argument is defined below. The .Fa options argument contains the bitwise OR of any of the following options. -.Bl -tag -width Ds +.Bl -tag -width WCONTINUED .It Dv WCONTINUED -indicates that children of the current process that -have continued from a job control stop, by receiving a +Report the status of selected processes that +have continued from a job control stop by receiving a .Dv SIGCONT -signal, should also have their status reported. +signal. .It Dv WNOHANG -is used to indicate that the call should not block when +Do not block when there are no processes wishing to report status. .It Dv WUNTRACED -indicates that children of the current process which are stopped -due to a +Report the status of selected processes which are stopped due to a .Dv SIGTTIN , SIGTTOU , SIGTSTP , or .Dv SIGSTOP -signal shall have their status reported. +signal. .It Dv WSTOPPED -is an alias for +An alias for .Dv WUNTRACED . .It Dv WTRAPPED -allows waiting for processes which have trapped or reached a breakpoint. +Report the status of selected processes which are being traced via +.Xr ptrace 2 +and have trapped or reached a breakpoint. +This flag is implicitly set for the functions +.Fn wait , +.Fn waitpid , +.Fn wait3 , +and +.Fn wait4 . +.br +For the +.Fn waitid +and +.Fn wait6 +functions, the flag has to be explicitly included in +.Fa options +if status reports from trapped processes are expected. .It Dv WEXITED -indicates that the caller is wants to receive status reports from -terminated processes. +Report the status of selected processes which have terminated. This flag is implicitly set for the functions .Fn wait , .Fn waitpid , @@ -302,11 +314,11 @@ For the .Fn waitid and .Fn wait6 -functions, the flag has to be explicitly included in the -.Fa options , +functions, the flag has to be explicitly included in +.Fa options if status reports from terminated processes are expected. .It Dv WNOWAIT -keeps the process whose status is returned in a waitable state. +Keep the process whose status is returned in a waitable state. The process may be waited for again after this call completes. .El .sp @@ -336,50 +348,68 @@ process and all its children is returned. .Pp If .Fa wrusage -argument is non-NULL, a resource usage statistics -from both its own child process as well as from its grand children -is returned. +is non-NULL, separate summaries are returned for the resources used +by the terminated process and the resources used by all its children. .Pp If .Fa infop -is non-NULL, it must point to a +is non-NULL, a .Dv siginfo_t -structure which is filled on return such that the -.Dv si_signo -field is always +structure is returned with the +.Fa si_signo +field set to .Dv SIGCHLD -and the field -.Dv si_pid -if be non-zero, if there is a status change to report. -If there are no status changes to report and WNOHANG is applied, -both of these fields are returned zero. -When using the -.Fn waitid -function with the +and the +.Fa si_pid +field set to the process ID of the process reporting status. +.Pp +When the .Dv WNOHANG -option set, checking these fields is the only way to know whether -there were any status changes to report, because the return value -from +option is specified and no processes +wish to report status, .Fn waitid -is be zero as it is for any successful return from -.Fn waitid . +sets the +.Fa si_signo +and +.Fa si_pid +fields in +.Fa infop +to zero. +Checking these fields is the only way to know if a status change was reported. .Pp When the .Dv WNOHANG option is specified and no processes wish to report status, .Fn wait4 -returns a +and +.Fn wait6 +return a process id of 0. .Pp The +.Fn wait +call is the same as +.Fn wait4 +with a +.Fa wpid +value of -1, +with an +.Fa options +value of zero, +and a +.Fa rusage +value of +.Dv NULL . +The .Fn waitpid function is identical to .Fn wait4 with an .Fa rusage -value of zero. +value of +.Dv NULL . The older .Fn wait3 call is the same as @@ -388,29 +418,31 @@ with a .Fa wpid value of -1. The +.Fn wait4 +function is identical to .Fn wait6 -call, with the bits +with the flags .Dv WEXITED and .Dv WTRAPPED -set in the +set in .Fa options -and with +and .Fa infop set to -.Dv NULL , -is similar to -.Fn wait4 . +.Dv NULL . .Pp -The following macros may be used to test the manner of exit of the process. -One of the first four macros will evaluate to a non-zero (true) value: +The following macros may be used to test the current status of the process. +Exactly one of the following four macros will evaluate to a non-zero +.Pq true +value: .Bl -tag -width Ds .It Fn WIFCONTINUED status True if the process has not terminated, and has continued after a job control stop. This macro can be true only if the wait call specified the .Dv WCONTINUED -option). +option. .It Fn WIFEXITED status True if the process terminated normally by a call to .Xr _exit 2 @@ -481,7 +513,7 @@ in The implementation queues one .Dv SIGCHLD signal for each child process whose -status has changed, if +status has changed; if .Fn wait returns because the status of a child process is available, the pending SIGCHLD signal associated with the process ID of the child process will @@ -492,7 +524,7 @@ signals remain pending. .Pp If .Dv SIGCHLD -is blocked, +is blocked and .Fn wait returns because the status of a child process is available, the pending .Dv SIGCHLD @@ -538,13 +570,23 @@ If .Fn waitid returns because one or more processes have a state change to report, 0 is returned. -To indicate an error, -1 will be returned and -.Dv errno -set to an appropriate value. +If an error is detected, +a value of -1 +is returned and +.Va errno +is set to indicate the error. If .Dv WNOHANG -was used, 0 can be returned indicating no error, but no processes -may have changed state either, if si_signo and/or si_pid are zero. +is specified and there are +no stopped, continued or exited children, +0 is returned. +The +.Fa si_signo +and +.Fa si_pid +fields of +.Fa infop +must be checked against zero to determine if a process reported status. .Sh ERRORS The .Fn wait @@ -620,7 +662,7 @@ requires .Fn waitid to return the full 32 bits passed to .Xr _exit 2 ; -this implementation only returns 8 bits like in the other calls. +this implementation only returns 8 bits like the other calls. .Sh HISTORY The .Fn wait diff --git a/lib/libc/uuid/Makefile.inc b/lib/libc/uuid/Makefile.inc index 595f0d0..05c1322 100644 --- a/lib/libc/uuid/Makefile.inc +++ b/lib/libc/uuid/Makefile.inc @@ -2,12 +2,12 @@ # DCE 1.1 UUID implementation sources -.PATH: ${.CURDIR}/uuid +.PATH: ${LIBC_SRCTOP}/uuid SRCS+= uuid_compare.c uuid_create.c uuid_create_nil.c uuid_equal.c \ uuid_from_string.c uuid_hash.c uuid_is_nil.c uuid_stream.c \ uuid_to_string.c -SYM_MAPS+= ${.CURDIR}/uuid/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/uuid/Symbol.map MAN+= uuid.3 MLINKS+=uuid.3 uuid_compare.3 diff --git a/lib/libc/xdr/Makefile.inc b/lib/libc/xdr/Makefile.inc index d1bb208..ff2c473 100644 --- a/lib/libc/xdr/Makefile.inc +++ b/lib/libc/xdr/Makefile.inc @@ -1,12 +1,12 @@ # @(#)Makefile 5.11 (Berkeley) 9/6/90 # $FreeBSD$ -.PATH: ${.CURDIR}/xdr ${.CURDIR}/. +.PATH: ${LIBC_SRCTOP}/xdr ${LIBC_SRCTOP}/. SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \ xdr_rec.c xdr_reference.c xdr_sizeof.c \ xdr_stdio.c -SYM_MAPS+= ${.CURDIR}/xdr/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/xdr/Symbol.map MAN+= xdr.3 diff --git a/lib/libc/xdr/xdr.c b/lib/libc/xdr/xdr.c index 337cdc0..4435119 100644 --- a/lib/libc/xdr/xdr.c +++ b/lib/libc/xdr/xdr.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr.c, Generic XDR routines implementation. * - * Copyright (C) 1986, Sun Microsystems, Inc. - * * These are the "generic" xdr routines used to serialize and de-serialize * most common data items. See xdr.h for more info on the interface to * xdr. diff --git a/lib/libc/xdr/xdr_array.c b/lib/libc/xdr/xdr_array.c index 6c35452..620155c 100644 --- a/lib/libc/xdr/xdr_array.c +++ b/lib/libc/xdr/xdr_array.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_array.c,v 1.12 2000/01/22 22:19:18 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr_array.c, Generic XDR routines impelmentation. * - * Copyright (C) 1984, Sun Microsystems, Inc. - * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * arrays. See xdr.h for more info on the interface to xdr. */ diff --git a/lib/libc/xdr/xdr_float.c b/lib/libc/xdr/xdr_float.c index 0a4f09f..8051649 100644 --- a/lib/libc/xdr/xdr_float.c +++ b/lib/libc/xdr/xdr_float.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_float.c,v 1.23 2000/07/17 04:59:51 matt Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr_float.c, Generic XDR routines implementation. * - * Copyright (C) 1984, Sun Microsystems, Inc. - * * These are the "floating point" xdr routines used to (de)serialize * most common data items. See xdr.h for more info on the interface to * xdr. diff --git a/lib/libc/xdr/xdr_mem.c b/lib/libc/xdr/xdr_mem.c index 138269c..70f79c6 100644 --- a/lib/libc/xdr/xdr_mem.c +++ b/lib/libc/xdr/xdr_mem.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr_mem.h, XDR implementation using memory buffers. * - * Copyright (C) 1984, Sun Microsystems, Inc. - * * If you have some data to be interpreted as external data representation * or to be converted to external data representation in a memory buffer, * then this is the package for you. diff --git a/lib/libc/xdr/xdr_rec.c b/lib/libc/xdr/xdr_rec.c index dc4aa18..3f63498 100644 --- a/lib/libc/xdr/xdr_rec.c +++ b/lib/libc/xdr/xdr_rec.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -40,8 +42,6 @@ __FBSDID("$FreeBSD$"); * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" * layer above tcp (for rpc's use). * - * Copyright (C) 1984, Sun Microsystems, Inc. - * * These routines interface XDRSTREAMS to a tcp/ip connection. * There is a record marking layer between the xdr stream * and the tcp transport level. A record is composed on one or more @@ -106,7 +106,7 @@ static const struct xdr_ops xdrrec_ops = { * meet the needs of xdr and rpc based on tcp. */ -#define LAST_FRAG ((u_int32_t)(1 << 31)) +#define LAST_FRAG ((u_int32_t)(1U << 31)) typedef struct rec_strm { char *tcp_handle; diff --git a/lib/libc/xdr/xdr_reference.c b/lib/libc/xdr/xdr_reference.c index 5a497b6..146dcf2 100644 --- a/lib/libc/xdr/xdr_reference.c +++ b/lib/libc/xdr/xdr_reference.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_reference.c,v 1.13 2000/01/22 22:19:18 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr_reference.c, Generic XDR routines impelmentation. * - * Copyright (C) 1987, Sun Microsystems, Inc. - * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * "pointers". See xdr.h for more info on the interface to xdr. */ diff --git a/lib/libc/xdr/xdr_sizeof.c b/lib/libc/xdr/xdr_sizeof.c index f33c613..3daaa0c 100644 --- a/lib/libc/xdr/xdr_sizeof.c +++ b/lib/libc/xdr/xdr_sizeof.c @@ -1,36 +1,36 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ /* * xdr_sizeof.c * - * Copyright 1990 Sun Microsystems, Inc. - * * General purpose routine to see how much space something will use * when serialized using XDR. */ diff --git a/lib/libc/xdr/xdr_stdio.c b/lib/libc/xdr/xdr_stdio.c index 8c1724d..832b308 100644 --- a/lib/libc/xdr/xdr_stdio.c +++ b/lib/libc/xdr/xdr_stdio.c @@ -1,32 +1,34 @@ /* $NetBSD: xdr_stdio.c,v 1.14 2000/01/22 22:19:19 mycroft Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +/*- + * Copyright (c) 2010, Oracle America, Inc. * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. */ #if defined(LIBC_SCCS) && !defined(lint) @@ -39,8 +41,6 @@ __FBSDID("$FreeBSD$"); /* * xdr_stdio.c, XDR implementation on standard i/o file. * - * Copyright (C) 1984, Sun Microsystems, Inc. - * * This set of routines implements a XDR on a stdio stream. * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes * from the stream. diff --git a/lib/libc/yp/Makefile.inc b/lib/libc/yp/Makefile.inc index 6faa9a5..2925d9c 100644 --- a/lib/libc/yp/Makefile.inc +++ b/lib/libc/yp/Makefile.inc @@ -2,12 +2,12 @@ # $FreeBSD$ # yp sources -.PATH: ${.CURDIR}/yp +.PATH: ${LIBC_SRCTOP}/yp SRCS+= xdryp.c yp.h yp_xdr.c yplib.c CLEANFILES+= yp.h yp_xdr.c -SYM_MAPS+= ${.CURDIR}/yp/Symbol.map +SYM_MAPS+= ${LIBC_SRCTOP}/yp/Symbol.map RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -C diff --git a/lib/libc_nonshared/Makefile b/lib/libc_nonshared/Makefile new file mode 100644 index 0000000..e65fca0 --- /dev/null +++ b/lib/libc_nonshared/Makefile @@ -0,0 +1,28 @@ +# $FreeBSD$ + +# We're actually creating a libc_noshared.a that is PIC along side libc.so.* +# It is used exclusively with libc.so.* - there is no need for any other +# compile modes. +# bsd.lib.mk doesn't have an easy way to express that. +MK_PROFILE?=no +.include <bsd.own.mk> +NO_PIC= +# -fpic on some platforms, -fPIC on others. +CFLAGS+=${PICFLAG} -DPIC -fvisibility=hidden + +LIB= c_nonshared + +LIBC_NONSHARED_SRCS= + +# So that an empty .a file doesn't cause errors. +SRCS= __stub.c + +.if ${MK_ICONV} == "yes" +.PATH: ${.CURDIR}/../libc/iconv +.include "Makefile.iconv" +CFLAGS+=-I${.CURDIR}/../libc/iconv +.endif + +SRCS+= ${LIBC_NONSHARED_SRCS} + +.include <bsd.lib.mk> diff --git a/lib/libc_nonshared/Makefile.iconv b/lib/libc_nonshared/Makefile.iconv new file mode 100644 index 0000000..8fb1ad9 --- /dev/null +++ b/lib/libc_nonshared/Makefile.iconv @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.if ${MK_ICONV} == "yes" +LIBC_NONSHARED_SRCS+= \ + __iconv.c __iconv_free_list.c __iconv_get_list.c \ + iconv.c iconv_canonicalize.c iconv_close.c \ + iconv_open.c iconv_open_into.c \ + iconv_set_relocation_prefix.c iconvctl.c iconvlist.c +.endif diff --git a/lib/libc_nonshared/__stub.c b/lib/libc_nonshared/__stub.c new file mode 100644 index 0000000..495f0aa --- /dev/null +++ b/lib/libc_nonshared/__stub.c @@ -0,0 +1,31 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +extern int __stub_N8TwezWFyocUB; + +int __stub_N8TwezWFyocUB; /* 42 */ diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile index 9a21dde..1621fe6 100644 --- a/lib/libcam/Makefile +++ b/lib/libcam/Makefile @@ -42,6 +42,6 @@ MLINKS+= cam.3 cam_open_device.3 \ SDIR= ${.CURDIR}/../../sys CFLAGS+= -I${.CURDIR} -I${SDIR} -SHLIB_MAJOR= 6 +SHLIB_MAJOR= 7 .include <bsd.lib.mk> diff --git a/lib/libcam/camlib.c b/lib/libcam/camlib.c index cd59922..f320247 100644 --- a/lib/libcam/camlib.c +++ b/lib/libcam/camlib.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include <string.h> #include <fcntl.h> #include <unistd.h> @@ -348,16 +349,16 @@ cam_open_btl(path_id_t path_id, target_id_t target_id, lun_id_t target_lun, if (ccb.cdm.status == CAM_DEV_MATCH_MORE) { snprintf(cam_errbuf, CAM_ERRBUF_SIZE, "%s: CDM reported more than one" - " passthrough device at %d:%d:%d!!\n", - func_name, path_id, target_id, target_lun); + " passthrough device at %d:%d:%jx!!\n", + func_name, path_id, target_id, (uintmax_t)target_lun); goto btl_bailout; } if (ccb.cdm.num_matches == 0) { snprintf(cam_errbuf, CAM_ERRBUF_SIZE, "%s: no passthrough device found at" - " %d:%d:%d", func_name, path_id, target_id, - target_lun); + " %d:%d:%jx", func_name, path_id, target_id, + (uintmax_t)target_lun); goto btl_bailout; } @@ -687,14 +688,14 @@ cam_path_string(struct cam_device *dev, char *str, int len) return(str); } - snprintf(str, len, "(%s%d:%s%d:%d:%d:%d): ", + snprintf(str, len, "(%s%d:%s%d:%d:%d:%jx): ", (dev->device_name[0] != '\0') ? dev->device_name : "pass", dev->dev_unit_num, (dev->sim_name[0] != '\0') ? dev->sim_name : "unknown", dev->sim_unit_number, dev->bus_id, dev->target_id, - dev->target_lun); + (uintmax_t)dev->target_lun); return(str); } diff --git a/lib/libcasper/Makefile b/lib/libcasper/Makefile new file mode 100644 index 0000000..ddcfba5 --- /dev/null +++ b/lib/libcasper/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= casper + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib + +SRCS= libcasper.c +INCS= libcasper.h + +DPADD= ${LIBCAPSICUM} ${LIBNV} ${LIBPJDLOG} +LDADD= -lcapsicum -lnv -lpjdlog + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libpjdlog +CFLAGS+=-I${.CURDIR}/../../sbin/casper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/lib/libcasper/libcasper.c b/lib/libcasper/libcasper.c new file mode 100644 index 0000000..7545baa --- /dev/null +++ b/lib/libcasper/libcasper.c @@ -0,0 +1,441 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/capsicum.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/un.h> + +#include <assert.h> +#include <dirent.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +#include <libcapsicum.h> +#include <libcasper.h> +#include <libcasper_impl.h> +#include <nv.h> +#include <pjdlog.h> + +/* + * Currently there is only one service_connection per service. + * In the future we may want multiple connections from multiple clients + * per one service instance, but it has to be carefully designed. + * The problem is that we may restrict/sandbox service instance according + * to the limits provided. When new connection comes in with different + * limits we won't be able to access requested resources. + * Not to mention one process will serve to mutiple mutually untrusted + * clients and compromise of this service instance by one of its clients + * can lead to compromise of the other clients. + */ + +/* + * Client connections to the given service. + */ +#define SERVICE_CONNECTION_MAGIC 0x5e91c0ec +struct service_connection { + int sc_magic; + cap_channel_t *sc_chan; + nvlist_t *sc_limits; + TAILQ_ENTRY(service_connection) sc_next; +}; + +#define SERVICE_MAGIC 0x5e91ce +struct service { + int s_magic; + char *s_name; + service_limit_func_t *s_limit; + service_command_func_t *s_command; + TAILQ_HEAD(, service_connection) s_connections; +}; + +struct service * +service_alloc(const char *name, service_limit_func_t *limitfunc, + service_command_func_t *commandfunc) +{ + struct service *service; + + service = malloc(sizeof(*service)); + if (service == NULL) + return (NULL); + service->s_name = strdup(name); + if (service->s_name == NULL) { + free(service); + return (NULL); + } + service->s_limit = limitfunc; + service->s_command = commandfunc; + TAILQ_INIT(&service->s_connections); + service->s_magic = SERVICE_MAGIC; + + return (service); +} + +void +service_free(struct service *service) +{ + struct service_connection *sconn; + + PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + + service->s_magic = 0; + while ((sconn = service_connection_first(service)) != NULL) + service_connection_remove(service, sconn); + free(service->s_name); + free(service); +} + +struct service_connection * +service_connection_add(struct service *service, int sock, + const nvlist_t *limits) +{ + struct service_connection *sconn; + int serrno; + + PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + + sconn = malloc(sizeof(*sconn)); + if (sconn == NULL) { + pjdlog_error("Unable to allocate memory for service connection."); + return (NULL); + } + sconn->sc_chan = cap_wrap(sock); + if (sconn->sc_chan == NULL) { + serrno = errno; + pjdlog_error("Unable to wrap communication channel."); + free(sconn); + errno = serrno; + return (NULL); + } + if (limits == NULL) { + sconn->sc_limits = NULL; + } else { + sconn->sc_limits = nvlist_clone(limits); + if (sconn->sc_limits == NULL) { + serrno = errno; + pjdlog_error("Unable to clone limits."); + (void)cap_unwrap(sconn->sc_chan); + free(sconn); + errno = serrno; + return (NULL); + } + } + sconn->sc_magic = SERVICE_CONNECTION_MAGIC; + TAILQ_INSERT_TAIL(&service->s_connections, sconn, sc_next); + return (sconn); +} + +void +service_connection_remove(struct service *service, + struct service_connection *sconn) +{ + + PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + TAILQ_REMOVE(&service->s_connections, sconn, sc_next); + sconn->sc_magic = 0; + nvlist_destroy(sconn->sc_limits); + cap_close(sconn->sc_chan); + free(sconn); +} + +int +service_connection_clone(struct service *service, + struct service_connection *sconn) +{ + struct service_connection *newsconn; + int serrno, sock[2]; + + if (socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sock) < 0) + return (-1); + + newsconn = service_connection_add(service, sock[0], + service_connection_get_limits(sconn)); + if (newsconn == NULL) { + serrno = errno; + close(sock[0]); + close(sock[1]); + errno = serrno; + return (-1); + } + + return (sock[1]); +} + +struct service_connection * +service_connection_first(struct service *service) +{ + struct service_connection *sconn; + + PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + + sconn = TAILQ_FIRST(&service->s_connections); + PJDLOG_ASSERT(sconn == NULL || + sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + return (sconn); +} + +struct service_connection * +service_connection_next(struct service_connection *sconn) +{ + + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + sconn = TAILQ_NEXT(sconn, sc_next); + PJDLOG_ASSERT(sconn == NULL || + sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + return (sconn); +} + +cap_channel_t * +service_connection_get_chan(const struct service_connection *sconn) +{ + + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + return (sconn->sc_chan); +} + +int +service_connection_get_sock(const struct service_connection *sconn) +{ + + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + return (cap_sock(sconn->sc_chan)); +} + +const nvlist_t * +service_connection_get_limits(const struct service_connection *sconn) +{ + + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + return (sconn->sc_limits); +} + +void +service_connection_set_limits(struct service_connection *sconn, + nvlist_t *limits) +{ + + PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + + nvlist_destroy(sconn->sc_limits); + sconn->sc_limits = limits; +} + +#if 0 +static void +casper_message_connection(struct service *service, const nvlist_t *nvl) +{ + + service_connection_add(&service->s_connections, + nvlist_get_descriptor(nvl, "sock")); +} + +static void +casper_message(const cap_channel_t *capcas, struct service *service) +{ + const char *cmd; + nvlist_t *nvl; + + nvl = cap_recv_nvlist(capcas); + if (nvl == NULL) + pjdlog_exit(1, "Unable to receive message from Casper"); + cmd = nvlist_get_string(nvl, "cmd"); + if (strcmp(cmd, "connection") == 0) + casper_message_connection(service, nvl); + else + PJDLOG_ABORT("Unknown command from Casper: %s.", cmd); +} +#endif + +void +service_message(struct service *service, struct service_connection *sconn) +{ + nvlist_t *nvlin, *nvlout; + const char *cmd; + int error; + + nvlin = cap_recv_nvlist(service_connection_get_chan(sconn)); + if (nvlin == NULL) { + if (errno == ENOTCONN) { + pjdlog_debug(1, "Connection closed by the client."); + } else { + pjdlog_errno(LOG_ERR, + "Unable to receive message from client"); + } + service_connection_remove(service, sconn); + return; + } + + error = EDOOFUS; + nvlout = nvlist_create(0); + + cmd = nvlist_get_string(nvlin, "cmd"); + pjdlog_debug(1, "Command received from client: %s.", cmd); + if (pjdlog_debug_get() >= 2) + nvlist_fdump(nvlin, stderr); + if (strcmp(cmd, "limit_set") == 0) { + nvlist_t *nvllim; + + nvllim = nvlist_take_nvlist(nvlin, "limits"); + error = service->s_limit(service_connection_get_limits(sconn), + nvllim); + if (error == 0) { + service_connection_set_limits(sconn, nvllim); + /* Function consumes nvllim. */ + } else { + nvlist_destroy(nvllim); + } + } else if (strcmp(cmd, "limit_get") == 0) { + const nvlist_t *nvllim; + + nvllim = service_connection_get_limits(sconn); + if (nvllim != NULL) + nvlist_add_nvlist(nvlout, "limits", nvllim); + else + nvlist_add_null(nvlout, "limits"); + error = 0; + } else if (strcmp(cmd, "clone") == 0) { + int sock; + + sock = service_connection_clone(service, sconn); + if (sock == -1) { + error = errno; + } else { + nvlist_move_descriptor(nvlout, "sock", sock); + error = 0; + } + } else { + error = service->s_command(cmd, + service_connection_get_limits(sconn), nvlin, nvlout); + } + + nvlist_destroy(nvlin); + nvlist_add_number(nvlout, "error", (uint64_t)error); + pjdlog_debug(1, "Sending reply to client (error=%d).", error); + if (pjdlog_debug_get() >= 2) + nvlist_fdump(nvlout, stderr); + + if (cap_send_nvlist(service_connection_get_chan(sconn), nvlout) == -1) { + pjdlog_errno(LOG_ERR, "Unable to send message to client"); + service_connection_remove(service, sconn); + } + + nvlist_destroy(nvlout); +} + +static int +fd_add(fd_set *fdsp, int maxfd, int fd) +{ + + FD_SET(fd, fdsp); + return (fd > maxfd ? fd : maxfd); +} + +int +service_start(const char *name, int sock, service_limit_func_t *limitfunc, + service_command_func_t *commandfunc, int argc, char *argv[]) +{ + struct service *service; + struct service_connection *sconn, *sconntmp; + fd_set fds; + int maxfd, nfds, serrno; + + assert(argc == 2); + + pjdlog_init(PJDLOG_MODE_STD); + pjdlog_debug_set(atoi(argv[1])); + + service = service_alloc(name, limitfunc, commandfunc); + if (service == NULL) + return (errno); + if (service_connection_add(service, sock, NULL) == NULL) { + serrno = errno; + service_free(service); + return (serrno); + } + + for (;;) { + FD_ZERO(&fds); + maxfd = -1; + for (sconn = service_connection_first(service); sconn != NULL; + sconn = service_connection_next(sconn)) { + maxfd = fd_add(&fds, maxfd, + service_connection_get_sock(sconn)); + } + + PJDLOG_ASSERT(maxfd >= 0); + PJDLOG_ASSERT(maxfd + 1 <= (int)FD_SETSIZE); + nfds = select(maxfd + 1, &fds, NULL, NULL, NULL); + if (nfds < 0) { + if (errno != EINTR) + pjdlog_errno(LOG_ERR, "select() failed"); + continue; + } else if (nfds == 0) { + /* Timeout. */ + PJDLOG_ABORT("select() timeout"); + continue; + } + + for (sconn = service_connection_first(service); sconn != NULL; + sconn = sconntmp) { + /* + * Prepare for connection to be removed from the list + * on failure. + */ + sconntmp = service_connection_next(sconn); + if (FD_ISSET(service_connection_get_sock(sconn), &fds)) + service_message(service, sconn); + } + if (service_connection_first(service) == NULL) { + /* + * No connections left, exiting. + */ + break; + } + } + + return (0); +} diff --git a/lib/libcasper/libcasper.h b/lib/libcasper/libcasper.h new file mode 100644 index 0000000..91d6027 --- /dev/null +++ b/lib/libcasper/libcasper.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LIBCASPER_H_ +#define _LIBCASPER_H_ + +#ifndef _NVLIST_T_DECLARED +#define _NVLIST_T_DECLARED +struct nvlist; + +typedef struct nvlist nvlist_t; +#endif + +#define PARENT_FILENO 3 +#define EXECUTABLE_FILENO 4 +#define PROC_FILENO 5 + +struct service; +struct service_connection; + +typedef int service_limit_func_t(const nvlist_t *, const nvlist_t *); +typedef int service_command_func_t(const char *cmd, const nvlist_t *, + nvlist_t *, nvlist_t *); + +struct service_connection *service_connection_add(struct service *service, + int sock, const nvlist_t *limits); +void service_connection_remove(struct service *service, + struct service_connection *sconn); +int service_connection_clone(struct service *service, + struct service_connection *sconn); +struct service_connection *service_connection_first(struct service *service); +struct service_connection *service_connection_next(struct service_connection *sconn); +cap_channel_t *service_connection_get_chan(const struct service_connection *sconn); +int service_connection_get_sock(const struct service_connection *sconn); +const nvlist_t *service_connection_get_limits(const struct service_connection *sconn); +void service_connection_set_limits(struct service_connection *sconn, + nvlist_t *limits); + +int service_start(const char *name, int sock, service_limit_func_t *limitfunc, + service_command_func_t *commandfunc, int argc, char *argv[]); + +#endif /* !_LIBCASPER_H_ */ diff --git a/lib/libkse/thread/thr_self.c b/lib/libcasper/libcasper_impl.h index bad0041..320f21a 100644 --- a/lib/libkse/thread/thr_self.c +++ b/lib/libcasper/libcasper_impl.h @@ -1,7 +1,10 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. +/*- + * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -10,14 +13,11 @@ * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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) @@ -29,19 +29,18 @@ * $FreeBSD$ */ -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" +#ifndef _LIBCASPER_IMPL_H_ +#define _LIBCASPER_IMPL_H_ + +#include "libcasper.h" + +struct service; +struct service_connection; -__weak_reference(_pthread_self, pthread_self); +struct service * service_alloc(const char *name, + service_limit_func_t *limitfunc, service_command_func_t *commandfunc); +void service_free(struct service *service); -pthread_t -_pthread_self(void) -{ - if (_thr_initial == NULL) - _libpthread_init(NULL); +void service_message(struct service *service, struct service_connection *sconn); - /* Return the running thread pointer: */ - return (_get_curthread()); -} +#endif /* !_LIBCASPER_IMPL_H_ */ diff --git a/lib/libcxxrt/Version.map b/lib/libcxxrt/Version.map index f7e12e1..a97c66f 100644 --- a/lib/libcxxrt/Version.map +++ b/lib/libcxxrt/Version.map @@ -111,6 +111,19 @@ CXXABI_1.3 { "typeinfo for void"; "typeinfo for wchar_t const*"; "typeinfo for wchar_t"; + # C++11 typeinfo not understood by our linker + # std::nullptr_t + _ZTIDn;_ZTIPDn;_ZTIPKDn; + # char16_t + _ZTIDi;_ZTIPDi;_ZTIPKDi; + # char32_t + _ZTIDs;_ZTIPDs;_ZTIPKDs; + # IEEE 754r decimal floating point + _ZTIDd;_ZTIPDd;_ZTIPKDd; + _ZTIDe;_ZTIPDe;_ZTIPKDe; + _ZTIDf;_ZTIPDf;_ZTIPKDf; + # IEEE 754r half-precision floating point + _ZTIDh;_ZTIPDh;_ZTIPKDh; "typeinfo for bool*"; "typeinfo for wchar_t*"; @@ -195,6 +208,19 @@ CXXABI_1.3 { "typeinfo name for void*"; "typeinfo name for unsigned int*"; "typeinfo name for float*"; + # C++11 typeinfo not understood by our linker + # std::nullptr_t + _ZTSDn;_ZTIPDn;_ZTIPKDn; + # char16_t + _ZTSDi;_ZTIPDi;_ZTIPKDi; + # char32_t + _ZTSDs;_ZTIPDs;_ZTIPKDs; + # IEEE 754r decimal floating point + _ZTSDd;_ZTIPDd;_ZTIPKDd; + _ZTSDe;_ZTIPDe;_ZTIPKDe; + _ZTSDf;_ZTIPDf;_ZTIPKDf; + # IEEE 754r half-precision floating point + _ZTSDh;_ZTIPDh;_ZTIPKDh; "typeinfo name for __cxxabiv1::__array_type_info"; "typeinfo name for __cxxabiv1::__class_type_info"; diff --git a/lib/libdevstat/devstat.c b/lib/libdevstat/devstat.c index 0f313fb..ade8738 100644 --- a/lib/libdevstat/devstat.c +++ b/lib/libdevstat/devstat.c @@ -150,7 +150,9 @@ static const char *namelist[] = { "_devstat_version", #define X_DEVICE_STATQ 3 "_device_statq", -#define X_END 4 +#define X_TIME_UPTIME 4 + "_time_uptime", +#define X_END 5 }; /* @@ -199,7 +201,7 @@ devstat_getnumdevs(kvm_t *kd) * supplied in a more atmoic manner by the kern.devstat.all sysctl. * Because this generation sysctl is separate from the statistics sysctl, * the device list and the generation could change between the time that - * this function is called and the device list is retreived. + * this function is called and the device list is retrieved. */ long devstat_getgeneration(kvm_t *kd) @@ -349,10 +351,10 @@ devstat_getdevs(kvm_t *kd, struct statinfo *stats) oldnumdevs = dinfo->numdevs; oldgeneration = dinfo->generation; - clock_gettime(CLOCK_MONOTONIC, &ts); - stats->snap_time = ts.tv_sec + ts.tv_nsec * 1e-9; - if (kd == NULL) { + clock_gettime(CLOCK_MONOTONIC, &ts); + stats->snap_time = ts.tv_sec + ts.tv_nsec * 1e-9; + /* If this is our first time through, mem_ptr will be null. */ if (dinfo->mem_ptr == NULL) { /* @@ -433,6 +435,11 @@ devstat_getdevs(kvm_t *kd, struct statinfo *stats) } } else { + if (KREADNL(kd, X_TIME_UPTIME, ts.tv_sec) == -1) + return(-1); + else + stats->snap_time = ts.tv_sec; + /* * This is of course non-atomic, but since we are working * on a core dump, the generation is unlikely to change diff --git a/lib/libedit/chartype.h b/lib/libedit/chartype.h index 8874cea..c8b2b14 100644 --- a/lib/libedit/chartype.h +++ b/lib/libedit/chartype.h @@ -12,13 +12,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile index f4baf14..c400204 100644 --- a/lib/libelf/Makefile +++ b/lib/libelf/Makefile @@ -1,8 +1,15 @@ # $FreeBSD$ +.include <bsd.own.mk> + +TOP= ${.CURDIR}/../../contrib/elftoolchain +SRCDIR= ${TOP}/libelf + +.PATH: ${SRCDIR} LIB= elf -SRCS= elf_begin.c \ +SRCS= elf.c \ + elf_begin.c \ elf_cntl.c \ elf_end.c elf_errmsg.c elf_errno.c \ elf_data.c \ @@ -16,6 +23,7 @@ SRCS= elf_begin.c \ elf_kind.c \ elf_memory.c \ elf_next.c \ + elf_open.c \ elf_rand.c \ elf_rawfile.c \ elf_phnum.c \ @@ -40,7 +48,6 @@ SRCS= elf_begin.c \ gelf_syminfo.c \ gelf_symshndx.c \ gelf_xlate.c \ - libelf.c \ libelf_align.c \ libelf_allocate.c \ libelf_ar.c \ @@ -49,11 +56,14 @@ SRCS= elf_begin.c \ libelf_data.c \ libelf_ehdr.c \ libelf_extended.c \ + libelf_memory.c \ + libelf_open.c \ libelf_phdr.c \ libelf_shdr.c \ libelf_xlate.c \ ${GENSRCS} -INCS= libelf.h gelf.h + +INCS= libelf.h gelf.h # # We need to link against the correct version of these files. One @@ -66,13 +76,13 @@ SRCS+= sys/elf32.h sys/elf64.h sys/elf_common.h GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} CLEANDIRS= sys -CFLAGS+= -I${.CURDIR} -I. +CFLAGS+= -I. -I${SRCDIR} -I${TOP}/common sys/elf32.h sys/elf64.h sys/elf_common.h: ${.CURDIR}/../../sys/${.TARGET} mkdir -p ${.OBJDIR}/sys ln -sf ${.CURDIR}/../../sys/${.TARGET} ${.TARGET} -SHLIB_MAJOR= 1 +SHLIB_MAJOR= 2 MAN= elf.3 \ elf_begin.3 \ @@ -97,6 +107,7 @@ MAN= elf.3 \ elf_kind.3 \ elf_memory.3 \ elf_next.3 \ + elf_open.3 \ elf_rawfile.3 \ elf_rand.3 \ elf_strptr.3 \ @@ -124,6 +135,7 @@ MAN= elf.3 \ MLINKS+= \ elf_errmsg.3 elf_errno.3 \ + elf_flagdata.3 elf_flagarhdr.3 \ elf_flagdata.3 elf_flagehdr.3 \ elf_flagdata.3 elf_flagelf.3 \ elf_flagdata.3 elf_flagphdr.3 \ @@ -135,6 +147,7 @@ MLINKS+= \ elf_getscn.3 elf_newscn.3 \ elf_getscn.3 elf_nextscn.3 \ elf_getshstrndx.3 elf_setshstrndx.3 \ + elf_open.3 elf_openmemory.3 \ gelf_getcap.3 gelf_update_cap.3 \ gelf_getdyn.3 gelf_update_dyn.3 \ gelf_getmove.3 gelf_update_move.3 \ @@ -160,12 +173,7 @@ MLINKS+= \ gelf_xlatetof.3 elf${E}_xlatetom.3 .endfor -VERSION_MAP= ${.CURDIR}/Version.map - -LIBELF_TEST_HOOKS?= 1 -.if defined(LIBELF_TEST_HOOKS) && (${LIBELF_TEST_HOOKS} > 0) -CFLAGS+= -DLIBELF_TEST_HOOKS -.endif +VERSION_MAP= ${SRCDIR}/Version.map libelf_convert.c: elf_types.m4 libelf_convert.m4 libelf_fsize.c: elf_types.m4 libelf_fsize.m4 @@ -176,4 +184,5 @@ libelf_msize.c: elf_types.m4 libelf_msize.m4 # Keep the .SUFFIXES line after the include of bsd.lib.mk .SUFFIXES: .m4 .c .m4.c: - m4 -D SRCDIR=${.CURDIR} ${.IMPSRC} > ${.TARGET} + m4 -D SRCDIR=${SRCDIR} ${M4FLAGS} ${.IMPSRC} > ${.TARGET} + diff --git a/lib/libelf/README b/lib/libelf/README deleted file mode 100644 index 726fcc9..0000000 --- a/lib/libelf/README +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ -# $NetBSD$ - -libelf: a BSD-licensed implementation of the ELF(3)/GELF(3) API. - -Documentation: - * Manual page elf.3 contains an overview of the library. Other - manual pages document individual APIs in the library. - * A tutorial "libelf by Example" is available at: - http://people.freebsd.org/~jkoshy/download/libelf/article.html - -For ongoing development please see http://elftoolchain.sourceforge.net/ diff --git a/lib/libelf/Version.map b/lib/libelf/Version.map deleted file mode 100644 index a6a6bd8..0000000 --- a/lib/libelf/Version.map +++ /dev/null @@ -1,105 +0,0 @@ -/* - * $FreeBSD$ - */ -FBSD_1.0 { -global: - elf32_checksum; - elf32_fsize; - elf32_getehdr; - elf32_getphdr; - elf32_getshdr; - elf32_newehdr; - elf32_newphdr; - elf32_xlatetof; - elf32_xlatetom; - elf64_checksum; - elf64_fsize; - elf64_getehdr; - elf64_getphdr; - elf64_getshdr; - elf64_newehdr; - elf64_newphdr; - elf64_xlatetof; - elf64_xlatetom; - elf_begin; - elf_cntl; - elf_end; - elf_errmsg; - elf_errno; - elf_fill; - elf_flagdata; - elf_flagehdr; - elf_flagelf; - elf_flagphdr; - elf_flagscn; - elf_flagshdr; - elf_getarhdr; - elf_getarsym; - elf_getbase; - elf_getdata; - elf_getident; - elf_getscn; - elf_getphdrnum; - elf_getphnum; - elf_getshdrnum; - elf_getshnum; - elf_getshdrstrndx; - elf_getshstrndx; - elf_hash; - elf_kind; - elf_memory; - elf_ndxscn; - elf_newdata; - elf_newscn; - elf_next; - elf_nextscn; - elf_rand; - elf_rawdata; - elf_rawfile; - elf_setshstrndx; - elf_strptr; - elf_update; - elf_version; - gelf_checksum; - gelf_fsize; - gelf_getcap; - gelf_getclass; - gelf_getdyn; - gelf_getehdr; - gelf_getmove; - gelf_getphdr; - gelf_getrel; - gelf_getrela; - gelf_getshdr; - gelf_getsym; - gelf_getsyminfo; - gelf_getsymshndx; - gelf_newehdr; - gelf_newphdr; - gelf_update_cap; - gelf_update_dyn; - gelf_update_ehdr; - gelf_update_move; - gelf_update_phdr; - gelf_update_rel; - gelf_update_rela; - gelf_update_shdr; - gelf_update_sym; - gelf_update_syminfo; - gelf_update_symshndx; - gelf_xlatetof; - gelf_xlatetom; -local: - *; -}; - -/* - * Private symbols, mostly test hooks - */ -FBSDprivate_1.0 { -global: - _libelf_set_error; - _libelf_get_max_error; - _libelf_get_no_error_message; - _libelf_get_unknown_error_message; -}; diff --git a/lib/libelf/_libelf.h b/lib/libelf/_libelf.h deleted file mode 100644 index 0606a62..0000000 --- a/lib/libelf/_libelf.h +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef __LIBELF_H_ -#define __LIBELF_H_ - -#include <sys/queue.h> - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -/* - * Library-private data structures. - */ - -#define LIBELF_MSG_SIZE 256 - -struct _libelf_globals { - int libelf_arch; - unsigned int libelf_byteorder; - int libelf_class; - int libelf_error; - int libelf_fillchar; - unsigned int libelf_version; - char libelf_msg[LIBELF_MSG_SIZE]; -}; - -extern struct _libelf_globals _libelf; - -#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) - -#define LIBELF_ELF_ERROR_MASK 0xFF -#define LIBELF_OS_ERROR_SHIFT 8 - -#define LIBELF_SET_ERROR(E, O) do { \ - LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \ - ((O) << LIBELF_OS_ERROR_SHIFT)); \ - } while (0) - -#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) - -/* - * Flags for library internal use. These use the upper 16 bits of a - * flags field. - */ -#define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ -#define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ -#define LIBELF_F_SHDRS_LOADED 0x040000 /* whether all shdrs were read in */ - -struct _Elf { - int e_activations; /* activation count */ - Elf_Arhdr *e_arhdr; /* header for archive members */ - unsigned int e_byteorder; /* ELFDATA* */ - int e_class; /* ELFCLASS* */ - Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ - int e_fd; /* associated file descriptor */ - unsigned int e_flags; /* ELF_F_*, LIBELF_F_* flags */ - Elf_Kind e_kind; /* ELF_K_* */ - Elf *e_parent; /* non-NULL for archive members */ - char *e_rawfile; /* uninterpreted bytes */ - size_t e_rawsize; /* size of uninterpreted bytes */ - unsigned int e_version; /* file version */ - - union { - struct { /* ar(1) archives */ - off_t e_next; /* set by elf_rand()/elf_next() */ - int e_nchildren; - char *e_rawstrtab; /* file name strings */ - size_t e_rawstrtabsz; - char *e_rawsymtab; /* symbol table */ - size_t e_rawsymtabsz; - Elf_Arsym *e_symtab; - size_t e_symtabsz; - } e_ar; - struct { /* regular ELF files */ - union { - Elf32_Ehdr *e_ehdr32; - Elf64_Ehdr *e_ehdr64; - } e_ehdr; - union { - Elf32_Phdr *e_phdr32; - Elf64_Phdr *e_phdr64; - } e_phdr; - STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ - size_t e_nphdr; /* number of Phdr entries */ - size_t e_nscn; /* number of sections */ - size_t e_strndx; /* string table section index */ - } e_elf; - } e_u; -}; - -struct _Elf_Scn { - union { - Elf32_Shdr s_shdr32; - Elf64_Shdr s_shdr64; - } s_shdr; - STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ - STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ - STAILQ_ENTRY(_Elf_Scn) s_next; - struct _Elf *s_elf; /* parent ELF descriptor */ - unsigned int s_flags; /* flags for the section as a whole */ - size_t s_ndx; /* index# for this section */ - uint64_t s_offset; /* managed by elf_update() */ - uint64_t s_rawoff; /* original offset in the file */ - uint64_t s_size; /* managed by elf_update() */ -}; - - -enum { - ELF_TOFILE, - ELF_TOMEMORY -}; - -#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > UINT_MAX) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - -#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > INT_MAX || \ - (SRC)->NAME < INT_MIN) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - - -/* - * Prototypes - */ - -Elf_Data *_libelf_allocate_data(Elf_Scn *_s); -Elf *_libelf_allocate_elf(void); -Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); -Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); -Elf *_libelf_ar_open(Elf *_e); -Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); -int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); -char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname); -char *_libelf_ar_get_name(char *_buf, size_t _sz, Elf *_e); -int _libelf_ar_get_number(char *_buf, size_t _sz, int _base, size_t *_ret); -Elf_Arsym *_libelf_ar_process_symtab(Elf *_ar, size_t *_dst); -unsigned long _libelf_checksum(Elf *_e, int _elfclass); -void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); -int _libelf_falign(Elf_Type _t, int _elfclass); -size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, - size_t count); -int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); -void *_libelf_getphdr(Elf *_e, int _elfclass); -void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); -void _libelf_init_elf(Elf *_e, Elf_Kind _kind); -int _libelf_load_scn(Elf *e, void *ehdr); -int _libelf_malign(Elf_Type _t, int _elfclass); -size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); -void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); -Elf_Data *_libelf_release_data(Elf_Data *_d); -Elf *_libelf_release_elf(Elf *_e); -Elf_Scn *_libelf_release_scn(Elf_Scn *_s); -int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); -int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); -int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, - size_t _shstrndx); -Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, - unsigned int _encoding, int _elfclass, int _direction); -int _libelf_xlate_shtype(uint32_t _sht); - -#endif /* __LIBELF_H_ */ diff --git a/lib/libelf/elf.3 b/lib/libelf/elf.3 deleted file mode 100644 index 35bba9c..0000000 --- a/lib/libelf/elf.3 +++ /dev/null @@ -1,580 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 21, 2007 -.Dt ELF 3 -.Os -.Sh NAME -.Nm elf -.Nd API for manipulating ELF objects -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Sh DESCRIPTION -The -.Lb libelf -provides functions that allow an application to read and manipulate -ELF object files, and to read -.Xr ar 1 -archives. -The library allows the manipulation of ELF objects in a byte ordering -and word-size independent way, allowing an application to read and -create ELF objects for 32 and 64 bit architectures and for little- -and big-endian machines. -The library is capable of processing ELF objects that use extended -section numbering. -.Pp -This manual page serves to provide an overview of the functionality in -the ELF library. -Further information may found in the manual pages for individual -.Xr ELF 3 -functions that comprise the library. -.Ss ELF Concepts -As described in -.Xr elf 5 , -ELF files contain several data structures that are laid out in a -specific way. -ELF files begin with an -.Dq Executable Header , -and may contain an optional -.Dq Program Header Table , -and optional data in the form of ELF -.Dq sections . -A -.Dq Section Header Table -describes the content of the data in these sections. -.Pp -ELF objects have an associated -.Dq "ELF class" -which denotes the natural machine word size for the architecture -the object is associated with. -Objects for 32 bit architectures have an ELF class of -.Dv ELFCLASS32 . -Objects for 64 bit architectures have an ELF class of -.Dv ELFCLASS64 . -.Pp -ELF objects also have an associated -.Dq endianness -which denotes the endianness of the machine architecture associated -with the object. -This may be -.Dv ELFDATA2LSB -for little-endian architectures and -.Dv ELFDATA2MSB -for big-endian architectures. -.Pp -ELF objects are also associated with an API version number. -This version number determines the layout of the individual components -of an ELF file and the semantics associated with these. -.Ss Data Representation And Translation -The -.Xr ELF 3 -library distinguishes between -.Dq native -representations of ELF data structures and their -.Dq file -representations. -.Pp -An application would work with ELF data in its -.Dq native -representation, i.e., using the native byteorder and alignment mandated -by the processor the application is running on. -The -.Dq file -representation of the same data could use a different byte ordering -and follow different constraints on object alignment than these native -constraints. -.Pp -Accordingly, the -.Xr ELF 3 -library offers translation facilities -.Po -.Xr elf32_xlatetof 3 , -.Xr elf32_xlatetom 3 , -.Xr elf64_xlatetof 3 -and -.Xr elf64_xlatetom 3 -.Pc -to and from these -representations and also provides higher-level APIs that retrieve and store -data from the ELF object in a transparent manner. -.Ss Library Working Version -Conceptually, there are three version numbers associated with an -application using the ELF library to manipulate ELF objects: -.Bl -bullet -compact -offset indent -.It -The ELF version that the application was compiled against. -This version determines the ABI expected by the application. -.It -The ELF version of the ELF object being manipulated by the -application through the ELF library. -.It -The ELF version (or set of versions) supported by the ELF library itself. -.El -.Pp -In order to facilitate working with ELF objects of differing versions, -the ELF library requires the application to call the -.Fn elf_version -function before invoking many of its operations, in order to inform -the library of the application's desired working version. -.Pp -In the current implementation, all three versions have to be -.Dv EV_CURRENT . -.Ss Namespace use -The ELF library uses the following prefixes: -.Bl -tag -width "ELF_F_*" -.It elf_* -Used for class-independent functions. -.It elf32_* -Used for functions working with 32 bit ELF objects. -.It elf64_* -Used for functions working with 64 bit ELF objects. -.It Elf_* -Used for class-independent data types. -.It ELF_C_* -Used for command values used in a few functions. -These symbols are defined as members of the -.Vt Elf_Cmd -enumeration. -.It ELF_E_* -Used for error numbers. -.It ELF_F_* -Used for flags. -.It ELF_K_* -These constants define the kind of file associated with an ELF -descriptor. -See -.Xr elf_kind 3 . -The symbols are defined by the -.Vt Elf_Kind -enumeration. -.It ELF_T_* -These values are defined by the -.Vt Elf_Type -enumeration, and denote the types of ELF data structures -that can be present in an ELF object. -.El -.Ss Descriptors -Applications communicate with the library using descriptors. -These are: -.Bl -tag -width ".Vt Elf_Data" -.It Vt Elf -An -.Vt Elf -descriptor represents an ELF object or an -.Xr ar 1 -archive. -It is allocated using one of the -.Fn elf_begin -or -.Fn elf_memory -functions. -An -.Vt Elf -descriptor can be used to read and write data to an ELF file. -An -.Vt Elf -descriptor can be associated with zero or more -.Vt Elf_Scn -section descriptors. -.Pp -Given an ELF descriptor, the application may retrieve the ELF -object's class-dependent -.Dq "Executable Header" -structures using the -.Fn elf32_getehdr -or -.Fn elf64_getehdr -functions. -A new Ehdr structure may be allocated using the -.Fn elf64_newehdr -or -.Fn elf64_newehdr -functions. -.Pp -The -.Dq "Program Header Table" -associated with an ELF descriptor may be allocated using the -.Fn elf32_getphdr -or -.Fn elf64_getphdr -functions. -A new program header table may be allocated or an existing table -resized using the -.Fn elf32_newphdr -or -.Fn elf64_newphdr -functions. -.Pp -The -.Vt Elf -structure is opaque and has no members visible to the -application. -.\" TODO describe the Elf_Arhdr and Elf_Arsym structures. -.It Vt Elf_Data -An -.Vt Elf_Data -data structure describes an individual chunk of a ELF file as -represented in memory. -It has the following application visible members: -.Bl -tag -width ".Vt unsigned int d_version" -compact -.It Vt "uint64_t d_align" -The in-file alignment of the data buffer within its containing ELF section. -This value must be a power of two. -.It Vt "uint64_t d_off" -The offset with the containing section where this descriptors data -would be placed. -This field will be computed by the library unless the application -requests full control of the ELF object's layout. -.It Vt "uint64_t d_size" -The number of bytes of data in this descriptor. -.It Vt "void *d_buf" -A pointer to data in memory. -.It Vt "Elf_Type d_type" -The ELF type (see below) of the data in this descriptor. -.It Vt "unsigned int d_version" -The operating version for the data in this buffer. -.El -.Pp -.Vt Elf_Data -descriptors are usually associated with -.Vt Elf_Scn -descriptors. -Existing data descriptors associated with an ELF section may be -structures are retrieved using the -.Fn elf_getdata -function. -The -.Fn elf_newdata -function may be used to attach new data descriptors to an ELF section. -.It Vt Elf_Scn -.Vt Elf_Scn -descriptors represent a section in an ELF object. -.Pp -They are retrieved using the -.Fn elf_getscn -function. -An application may iterate through the existing sections of an ELF -object using the -.Fn elf_nextscn -function. -New sections may be allocated using the -.Fn elf_newscn -function. -.Pp -The -.Vt Elf_Scn -descriptor is opaque and contains no application modifiable fields. -.El -.Ss Supported Elf Types -The following ELF datatypes are supported by the library. -.Pp -.Bl -tag -width ".Dv ELF_T_SYMINFO" -compact -.It Dv ELF_T_ADDR -Machine addresses. -.It Dv ELF_T_BYTE -Byte data. -The library will not attempt to translate byte data. -.It Dv ELF_T_CAP -Software and hardware capability records. -.It Dv ELF_T_DYN -Records used in a section of type -.Dv SHT_DYNAMIC . -.It Dv ELF_T_EHDR -ELF executable header. -.It Dv ELF_T_HALF -16-bit unsigned words. -.It Dv ELF_T_LWORD -64 bit unsigned words. -.It Dv ELF_T_MOVE -ELF Move records. -.\".It Dv ELF_T_MOVEP -.\" As yet unsupported. -.It Dv ELF_T_NOTE -ELF Note structures. -.It Dv ELF_T_OFF -File offsets. -.It Dv ELF_T_PHDR -ELF program header table entries. -.It Dv ELF_T_REL -ELF relocation entries. -.It Dv ELF_T_RELA -ELF relocation entries with addends. -.It Dv ELF_T_SHDR -ELF section header entries. -.It Dv ELF_T_SWORD -Signed 32-bit words. -.It Dv ELF_T_SXWORD -Signed 64-bit words. -.It Dv ELF_T_SYMINFO -ELF symbol information. -.It Dv ELF_T_SYM -ELF symbol table entries. -.It Dv ELF_T_VDEF -Symbol version definition records. -.It Dv ELF_T_VNEED -Symbol version requirement records. -.It Dv ELF_T_WORD -Unsigned 32-bit words. -.It Dv ELF_T_XWORD -Unsigned 64-bit words. -.El -.Pp -The symbol -.Dv ELF_T_NUM -denotes the number of Elf types known to the library. -.Pp -The following table shows the mapping between ELF section types -defined in -.Xr elf 5 -and the types supported by the library. -.Bl -column ".Dv SHT_PREINIT_ARRAY" ".Dv ELF_T_SYMINFO" -.It Em Section Type Ta Em "Library Type" Ta Em Description -.It Dv SHT_DYNAMIC Ta Dv ELF_T_DYN Ta Xo -.Sq .dynamic -section entries. -.Xc -.It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. -.It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. -.It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. -.It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. -.It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. -.It Dv SHT_NOBITS Ta Dv ELF_T_BYTE Ta Xo -Empty sections. -See -.Xr elf 5 . -.Xc -.It Dv SHT_NOTE Ta Dv ELF_T_NOTE Ta ELF note records. -.It Dv SHT_PREINIT_ARRAY Ta Dv ELF_T_ADDR Ta Pre-initialization function pointers. -.It Dv SHT_PROGBITS Ta Dv ELF_T_BYTE Ta Machine code. -.It Dv SHT_REL Ta Dv ELF_T_REL Ta ELF relocation records. -.It Dv SHT_RELA Ta Dv ELF_T_RELA Ta Relocation records with addends. -.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. -.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. -.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. -.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. -.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. -.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. -.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. -.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. -.El -.Ss Functional Grouping -This section contains a brief overview of the available functionality -in the ELF library. -Each function listed here is described further in its own manual page. -.Bl -tag -width 2n -.It "Archive Access" -.Bl -tag -width 17n -compact -.It Fn elf_getarsym -Retrieve the archive symbol table. -.It Fn elf_getarhdr -Retrieve the archive header for an object. -.It Fn elf_getbase -Retrieve the offset of a member inside an archive. -.It Fn elf_next -Iterate through an -.Xr ar 1 -archive. -.It Fn elf_rand -Random access inside an -.Xr ar 1 -archive. -.El -.It "Data Structures" -.Bl -tag -width 17n -compact -.It Fn elf_getdata -Retrieve translated data for an ELF section. -.It Fn elf_getscn -Retrieve the section descriptor for a named section. -.It Fn elf_ndxscn -Retrieve the index for a section. -.It Fn elf_newdata -Add a new -.Vt Elf_Data -descriptor to an ELF section. -.It Fn elf_newscn -Add a new section descriptor to an ELF descriptor. -.It Fn elf_nextscn -Iterate through the sections in an ELF object. -.It Fn elf_rawdata -Retrieve untranslated data for an ELF sectino. -.It Fn elf_rawfile -Return a pointer to the untranslated file contents for an ELF object. -.It Fn elf32_getehdr , Fn elf64_getehdr -Retrieve the Executable Header in an ELF object. -.It Fn elf32_getphdr , Fn elf64_getphdr -Retrieve the Program Header Table in an ELF object. -.It Fn elf32_getshdr , Fn elf64_getshdr -Retrieve the ELF section header associated with an -.Vt Elf_Scn -descriptor. -.It Fn elf32_newehdr , Fn elf64_newehdr -Allocate an Executable Header in an ELF object. -.It Fn elf32_newphdr , Fn elf64_newphdr -Allocate or resize the Program Header Table in an ELF object. -.El -.It "Data Translation" -.Bl -tag -width 17n -compact -.It Fn elf32_xlatetof , Fn elf64_xlatetof -Translate an ELF data structure from its native representation to its -file representation. -.It Fn elf32_xlatetom , Fn elf64_xlatetom -Translate an ELF data structure from its file representation to a -native representation. -.El -.It "Error Reporting" -.Bl -tag -width 17n -compact -.It Fn elf_errno -Retrieve the current error. -.It Fn elf_errmsg -Retrieve a human readable description of the current error. -.El -.It "Initialization" -.Bl -tag -width 17n -compact -.It Fn elf_begin -Opens an -.Xr ar 1 -archive or ELF object given a file descriptor. -.It Fn elf_end -Close an ELF descriptor and release all its resources. -.It Fn elf_memory -Opens an -.Xr ar 1 -archive or ELF object present in a memory area. -.It Fn elf_version -Sets the operating version. -.El -.It "IO Control" -.Bl -tag -width 17n -compact -.It Fn elf_cntl -Manage the association between and ELF descriptor and its underlying file. -.It Fn elf_flagdata -Mark an -.Vt Elf_Data -descriptor as dirty. -.It Fn elf_flagehdr -Mark the ELF Executable Header in an ELF descriptor as dirty. -.It Fn elf_flagphdr -Mark the ELF Program Header Table in an ELF descriptor as dirty. -.It Fn elf_flagscn -Mark an -.Vt Elf_Scn -descriptor as dirty. -.It Fn elf_flagshdr -Mark an ELF Section Header as dirty. -.It Fn elf_setshstrndx -Set the index of the section name string table for the ELF object. -.It Fn elf_update -Recompute ELF object layout and optionally write the modified object -back to the underlying file. -.El -.It "Queries" -.Bl -tag -width 17n -compact -.It Fn elf32_checksum , Fn elf64_checkum -Compute checksum of an ELF object. -.It Fn elf_getident -Retrieve the identification bytes for an ELF object. -.It Fn elf_getshnum -Retrieve the number of sections in an ELF object. -.It Fn elf_getshstrndx -Retrieve the section index of the section name string table in -an ELF object. -.It Fn elf_hash -Compute the ELF hash value of a string. -.It Fn elf_kind -Query the kind of object associated with an ELF descriptor. -.It Fn elf32_fsize , Fn elf64_fsize -Return the size of the file representation of an ELF type. -.El -.El -.Ss Controlling ELF Object Layout -In the usual mode of operation, library will compute section -offsets and alignments based on the contents of an ELF descriptor's -sections without need for further intervention by the -application. -.Pp -However, if the application wishes to take complete charge of the -layout of the ELF file, it may set the -.Dv ELF_F_LAYOUT -flag on an ELF descriptor using -.Xr elf_flagelf 3 , -following which the library will use the data offsets and alignments -specified by the application when laying out the file. -Application control of file layout is described further in the -.Xr elf_update 3 -manual page. -.Pp -Gaps in between sections will be filled with the fill character -set by function -.Fn elf_fill . -.Ss Error Handling -In case an error is encountered, these library functions set an -internal error number and signal the presence of the error by -returning an special return value. -The application can check the -current error number by calling -.Xr elf_errno 3 . -A human readable description of the recorded error is available by -calling -.Xr elf_errmsg 3 . -.Ss Memory Management Rules -The library keeps track of all -.Vt Elf_Scn -and -.Vt Elf_Data -descriptors associated with an ELF descriptor and recovers them -when the descriptor is closed using -.Xr elf_end 3 . -Thus the application must not call -.Xr free 3 -on data structures allocated by the ELF library. -.Pp -Conversely the library will not -free data that it has not allocated. -As an example, an application may call -.Xr elf_newdata 3 -to allocate a new -.Vt Elf_Data -descriptor and can set the -.Va d_off -member of the descriptor to point to a region of memory allocated -using -.Xr malloc 3 . -It is the applications responsibility to free this area, though the -library will reclaim the space used by the -.Vt Elf_Data -descriptor itself. -.Sh SEE ALSO -.Xr gelf 3 , -.Xr elf 5 -.Sh HISTORY -The original ELF(3) API was developed for Unix System V. -The current implementation of the ELF(3) API appeared in -.Fx 7.0 . -.Sh AUTHORS -The ELF library was written by -.An "Joseph Koshy" -.Aq jkoshy@FreeBSD.org . diff --git a/lib/libelf/elf_begin.3 b/lib/libelf/elf_begin.3 deleted file mode 100644 index 6d9371a..0000000 --- a/lib/libelf/elf_begin.3 +++ /dev/null @@ -1,280 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 20, 2010 -.Dt ELF_BEGIN 3 -.Os -.Sh NAME -.Nm elf_begin -.Nd open an ELF file or ar(1) archive -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf *" -.Fn elf_begin "int fd" "Elf_Cmd cmd" "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_begin -is used to open ELF files and -.Xr ar 1 -archives for further processing by other APIs in the -.Xr elf 3 -library. -It is also used to access individual ELF members of an -.Xr ar 1 -archive in combination with the -.Xr elf_next 3 -and -.Xr elf_rand 3 -APIs. -.Pp -Argument -.Ar fd -is an open file descriptor returned from an -.Xr open 2 -system call. -Function -.Fn elf_begin -uses argument -.Ar fd -for reading or writing depending on the value of argument -.Ar cmd . -Argument -.Ar elf -is primarily used for iterating through archives. -.Pp -The argument -.Ar cmd -can have the following values: -.Bl -tag -width "ELF_C_WRITE" -.It ELF_C_NULL -Causes -.Fn elf_begin -to return NULL. -Arguments -.Ar fd -and -.Ar elf -are ignored, and no additional error is signalled. -.It ELF_C_READ -This value is to be when the application wishes to examine (but not -modify) the contents of the file specified by argument -.Ar fd . -It can be used for both -.Xr ar 1 -archives and for regular ELF files. -.Pp -Argument -.Ar fd -should have been opened for reading. -If argument -.Ar elf -is NULL, the library will allocate a new ELF descriptor for -the file being processed. -If argument -.Ar elf -is not NULL, and references a regular ELF file previously opened with -.Fn elf_begin , -then the activation count for -.Ar elf -is incremented. -If argument -.Ar elf -is not NULL, and references a descriptor for an -.Xr ar 1 -archive opened earlier with -.Fn elf_begin , -a descriptor for an element in the archive is returned as -described in the section -.Sx "Processing ar(1) archives" -below. -.It Dv ELF_C_RDWR -The command is used to prepare an ELF file for reading and writing. -It is not supported for archives. -.Pp -Argument -.Ar fd -should have been opened for reading and writing. -If argument -.Ar elf -is NULL, the library will allocate a new ELF descriptor for -the file being processed. -If the argument -.Ar elf -is non-null, it should point to a descriptor previously -allocated with -.Fn elf_begin -with the same values for arguments -.Ar fd -and -.Ar cmd ; -in this case the library will increment the activation count for descriptor -.Ar elf -and return the same descriptor. -Changes to the in-memory image of the ELF file are written back to -disk using the -.Xr elf_update 3 -function. -.Pp -This command is not valid for -.Xr ar 1 -archives. -.It Dv ELF_C_WRITE -This command is used when the application wishes to create a new ELF -file. -Argument -.Ar fd -should have been opened for writing. -Argument -.Ar elf -is ignored, and the previous contents of file referenced by -argument -.Ar fd -are overwritten. -.El -.Ss Processing ar(1) archives -An -.Xr ar 1 -archive may be opened in read mode (with argument -.Ar cmd -set to -.Dv ELF_C_READ ) -using -.Fn elf_begin -or -.Fn elf_memory . -The returned ELF descriptor can be passed into to -subsequent calls to -.Fn elf_begin -to access individual members of the archive. -.Pp -Random access within an opened archive is possible using -the -.Xr elf_next 3 -and -.Xr elf_rand 3 -functions. -.Pp -The symbol table of the archive may be retrieved -using -.Xr elf_getarsym 3 . -.Sh RETURN VALUES -The function returns a pointer to a ELF descriptor if successful, or NULL -if an error occurred. -.Sh EXAMPLES -To iterate through the members of an -.Xr ar 1 -archive, use: -.Bd -literal -offset indent -Elf_Cmd c; -Elf *ar_e, *elf_e; -\&... -c = ELF_C_READ; -if ((ar_e = elf_begin(fd, c, (Elf *) 0)) == 0) { - \&... handle error in opening the archive ... -} -while ((elf_e = elf_begin(fd, c, ar_e)) != 0) { - \&... process member referenced by elf_e here ... - c = elf_next(elf_e); - elf_end(elf_e); -} -.Ed -.Pp -To create a new ELF file, use: -.Bd -literal -offset indent -int fd; -Elf *e; -\&... -if ((fd = open("filename", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) { - \&... handle the error from open(2) ... -} -if ((e = elf_begin(fd, ELF_C_WRITE, (Elf *) 0)) == 0) { - \&... handle the error from elf_begin() ... -} -\&... create the ELF image using other elf(3) APIs ... -elf_update(e, ELF_C_WRITE); -elf_end(e); -.Ed -.Sh ERRORS -Function -.Fn elf_begin -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARCHIVE -The archive denoted by argument -.Ar elf -could not be parsed. -.It Bq Er ELF_E_ARGUMENT -An unrecognized value was specified in argument -.Ar cmd . -.It Bq Er ELF_E_ARGUMENT -A non-null value for argument -.Ar elf -was specified when -.Ar cmd -was set to -.Dv ELF_C_RDWR . -.It Bq Er ELF_E_ARGUMENT -The value of argument -.Ar fd -differs from the one the ELF descriptor -.Ar elf -was created with. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -differs from the value specified when ELF descriptor -.Ar elf -was created. -.It Bq Er ELF_E_ARGUMENT -An -.Xr ar 1 -archive was opened with -.Ar cmd -set to -.Dv ELF_C_RDWR . -.It Bq Er ELF_E_IO -Function -.Fn elf_begin -was unable to truncate a file opened for writing using -.Dv ELF_C_WRITE . -.It Bq Er ELF_E_RESOURCE -An out of memory condition was encountered. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_begin -was called before a working version was established with -.Xr elf_version 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_end 3 , -.Xr elf_errno 3 , -.Xr elf_memory 3 , -.Xr elf_next 3 , -.Xr elf_rand 3 , -.Xr elf_update 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_begin.c b/lib/libelf/elf_begin.c deleted file mode 100644 index 6e81e32..0000000 --- a/lib/libelf/elf_begin.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/mman.h> -#include <sys/stat.h> - -#include <ar.h> -#include <ctype.h> -#include <libelf.h> -#include <unistd.h> - -#include "_libelf.h" - -static Elf * -_libelf_open_object(int fd, Elf_Cmd c) -{ - Elf *e; - void *m; - struct stat sb; - - /* - * 'Raw' files are always mapped with 'PROT_READ'. At - * elf_update(3) time for files opened with ELF_C_RDWR the - * mapping is unmapped, file data is written to using write(2) - * and then the raw data is immediately mapped back in. - */ - if (fstat(fd, &sb) < 0) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - m = NULL; - if ((m = mmap(NULL, (size_t) sb.st_size, PROT_READ, MAP_PRIVATE, fd, - (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - if ((e = elf_memory(m, (size_t) sb.st_size)) == NULL) { - (void) munmap(m, (size_t) sb.st_size); - return (NULL); - } - - e->e_flags |= LIBELF_F_MMAP; - e->e_fd = fd; - e->e_cmd = c; - - if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { - (void) elf_end(e); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (e); -} - -Elf * -elf_begin(int fd, Elf_Cmd c, Elf *a) -{ - Elf *e; - - e = NULL; - - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - switch (c) { - case ELF_C_NULL: - return (NULL); - - case ELF_C_WRITE: - - if (a != NULL) { /* not allowed for ar(1) archives. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - /* - * Check writeability of `fd' immediately and fail if - * not writeable. - */ - if (ftruncate(fd, (off_t) 0) < 0) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - if ((e = _libelf_allocate_elf()) != NULL) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_byteorder = LIBELF_PRIVATE(byteorder); - e->e_fd = fd; - e->e_cmd = c; - } - return (e); - - case ELF_C_RDWR: - if (a != NULL) { /* not allowed for ar(1) archives. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - /*FALLTHROUGH*/ - case ELF_C_READ: - /* - * Descriptor `a' could be for a regular ELF file, or - * for an ar(1) archive. If descriptor `a' was opened - * using a valid file descriptor, we need to check if - * the passed in `fd' value matches the original one. - */ - if (a && - ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - break; - - default: - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - - } - - if (a == NULL) - e = _libelf_open_object(fd, c); - else if (a->e_kind == ELF_K_AR) - e = _libelf_ar_open_member(a->e_fd, c, a); - else - (e = a)->e_activations++; - - return (e); -} diff --git a/lib/libelf/elf_cntl.3 b/lib/libelf/elf_cntl.3 deleted file mode 100644 index 17c8db9..0000000 --- a/lib/libelf/elf_cntl.3 +++ /dev/null @@ -1,111 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 9, 2006 -.Dt ELF_CNTL 3 -.Os -.Sh NAME -.Nm elf_cntl -.Nd control an elf file descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_cntl "Elf *elf" "Elf_Cmd cmd" -.Sh DESCRIPTION -Function -.Fn elf_cntl -controls the ELF library's subsequent use of the file descriptor -used to create ELF descriptor -.Ar elf . -.Pp -Argument -.Ar cmd -informs the library of the action to be taken: -.Bl -tag -width "ELF_C_FDDONE" -.It Dv ELF_C_FDDONE -This value instructs the ELF library not to perform any further -I/O on the file descriptor associated with argument -.Ar elf . -For ELF descriptors opened with mode -.Ar ELF_C_WRITE -or -.Ar ELF_C_RDWR -subsequent -.Fn elf_update -operations on the descriptor will fail. -.It Dv ELF_C_FDREAD -This value instructs the ELF library to read in all necessary -data associated with ELF descriptor -.Ar elf -into memory so that the underlying file descriptor can be -safely closed with command -.Dv ELF_C_FDDONE . -.El -.Pp -Argument -.Ar elf -must be an ELF descriptor associated with a file system object -(e.g., an -.Xr ar 1 -archive, an ELF file, or other data file). -.Sh IMPLEMENTATION NOTES -Due to use of -.Xr mmap 2 -internally, this function is a no-op for ELF objects opened in -.Dv ELF_C_READ -mode. -.Sh RETURN VALUES -Function -.Fn elf_cntl -returns 0 on success, or -1 if an error was detected. -.Sh ERRORS -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARCHIVE -Argument -.Ar elf -is a descriptor for an archive member. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -was not recognized. -.It Bq Er ELF_E_MODE -An -.Dv ELF_C_FDREAD -operation was requested on an ELF descriptor opened -for writing. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_next 3 , -.Xr elf_update 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_cntl.c b/lib/libelf/elf_cntl.c deleted file mode 100644 index 9fbd5c7..0000000 --- a/lib/libelf/elf_cntl.c +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" - -int -elf_cntl(Elf *e, Elf_Cmd c) -{ - if (e == NULL || - (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if (e->e_parent) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (-1); - } - - if (c == ELF_C_FDREAD) { - if (e->e_cmd == ELF_C_WRITE) { - LIBELF_SET_ERROR(MODE, 0); - return (-1); - } - else - return (0); - } - - e->e_fd = -1; - return 0; -} diff --git a/lib/libelf/elf_data.c b/lib/libelf/elf_data.c deleted file mode 100644 index d3bd390..0000000 --- a/lib/libelf/elf_data.c +++ /dev/null @@ -1,243 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <errno.h> -#include <libelf.h> -#include <stdlib.h> - -#include "_libelf.h" - - -Elf_Data * -elf_getdata(Elf_Scn *s, Elf_Data *d) -{ - Elf *e; - size_t fsz, msz, count; - int elfclass, elftype; - unsigned int sh_type; - uint64_t sh_align, sh_offset, sh_size; - int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF || - (d != NULL && s != d->d_scn)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) - return (d); - - if (d != NULL) - return (STAILQ_NEXT(d, d_next)); - - if (e->e_rawfile == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - elfclass = e->e_class; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - - if (elfclass == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || - elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && - sh_offset + sh_size > (uint64_t) e->e_rawsize)) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (elftype, (size_t) 1, e->e_version)) == 0) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (sh_size % fsz) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - count = sh_size / fsz; - - msz = _libelf_msize(elftype, elfclass, e->e_version); - - assert(msz > 0); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_buf = NULL; - d->d_off = 0; - d->d_align = sh_align; - d->d_size = msz * count; - d->d_type = elftype; - d->d_version = e->e_version; - - if (sh_type == SHT_NOBITS || sh_size == 0) { - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - return (d); - } - - if ((d->d_buf = malloc(msz*count)) == NULL) { - (void) _libelf_release_data(d); - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_flags |= LIBELF_F_MALLOCED; - - xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); - if (!(*xlate)(d->d_buf, d->d_size, e->e_rawfile + sh_offset, count, - e->e_byteorder != LIBELF_PRIVATE(byteorder))) { - _libelf_release_data(d); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - return (d); -} - -Elf_Data * -elf_newdata(Elf_Scn *s) -{ - Elf *e; - Elf_Data *d; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - /* - * elf_newdata() has to append a data descriptor, so - * bring in existing section data if not already present. - */ - if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) - if (elf_getdata(s, NULL) == NULL) - return (NULL); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - d->d_align = 1; - d->d_buf = NULL; - d->d_off = (uint64_t) ~0; - d->d_size = 0; - d->d_type = ELF_T_BYTE; - d->d_version = LIBELF_PRIVATE(version); - - (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); - - return (d); -} - -/* - * Retrieve a data descriptor for raw (untranslated) data for section - * `s'. - */ - -Elf_Data * -elf_rawdata(Elf_Scn *s, Elf_Data *d) -{ - Elf *e; - int elf_class; - uint32_t sh_type; - uint64_t sh_align, sh_offset, sh_size; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF || e->e_rawfile == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) - return (d); - - if (d != NULL) - return (STAILQ_NEXT(d, d_next)); - - elf_class = e->e_class; - - assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); - - if (elf_class == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : - e->e_rawfile + sh_offset; - d->d_off = 0; - d->d_align = sh_align; - d->d_size = sh_size; - d->d_type = ELF_T_BYTE; - d->d_version = e->e_version; - - STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); - - return (d); -} diff --git a/lib/libelf/elf_end.3 b/lib/libelf/elf_end.3 deleted file mode 100644 index 3622fb2..0000000 --- a/lib/libelf/elf_end.3 +++ /dev/null @@ -1,76 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 29, 2006 -.Dt ELF_END 3 -.Os -.Sh NAME -.Nm elf_end -.Nd release an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_end "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_end -is used to release the resources associated with an ELF descriptor -pointed to by argument -.Ar elf . -This descriptor must have been allocated by a previous call to -.Xr elf_begin 3 -or -.Xr elf_memory 3 . -For programming convenience, a NULL value is permitted for argument -.Ar elf . -.Pp -A call to -.Fn elf_end -decrements the activation count for descriptor -.Ar elf -by one. -The resources associated with the descriptor are only released -with its activation count goes to zero. -.Pp -Once function -.Fn elf_end -returns zero, the ELF descriptor -.Ar elf -will no longer be valid and should not be used further. -.Sh RETURN VALUES -Function -.Fn elf_end -returns the current value of the ELF descriptor -.Ar elf Ap s -activation count, or zero if argument -.Ar elf -was NULL. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_memory 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_end.c b/lib/libelf/elf_end.c deleted file mode 100644 index affb135..0000000 --- a/lib/libelf/elf_end.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/mman.h> - -#include <assert.h> -#include <libelf.h> -#include <stdlib.h> - -#include "_libelf.h" - -int -elf_end(Elf *e) -{ - Elf *sv; - Elf_Scn *scn, *tscn; - - if (e == NULL || e->e_activations == 0) - return (0); - - if (--e->e_activations > 0) - return (e->e_activations); - - assert(e->e_activations == 0); - - while (e && e->e_activations == 0) { - switch (e->e_kind) { - case ELF_K_AR: - /* - * If we still have open child descriptors, we - * need to defer reclaiming resources till all - * the child descriptors for the archive are - * closed. - */ - if (e->e_u.e_ar.e_nchildren > 0) - return (0); - break; - case ELF_K_ELF: - /* - * Reclaim all section descriptors. - */ - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) - scn = _libelf_release_scn(scn); - break; - case ELF_K_NUM: - assert(0); - default: - break; - } - - if (e->e_flags & LIBELF_F_MMAP) - (void) munmap(e->e_rawfile, e->e_rawsize); - - sv = e; - if ((e = e->e_parent) != NULL) - e->e_u.e_ar.e_nchildren--; - sv = _libelf_release_elf(sv); - } - - return (0); -} - diff --git a/lib/libelf/elf_errmsg.3 b/lib/libelf/elf_errmsg.3 deleted file mode 100644 index f014168..0000000 --- a/lib/libelf/elf_errmsg.3 +++ /dev/null @@ -1,107 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 11, 2006 -.Dt ELF_ERRMSG 3 -.Os -.Sh NAME -.Nm elf_errmsg , -.Nm elf_errno -.Nd ELF library error message handling -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_errno "void" -.Ft "const char *" -.Fn elf_errmsg "int error" -.Sh DESCRIPTION -When an error occurs during an ELF library API call, the library -encodes the error using an error number and stores the error number -internally for retrieval by the application at a later point of time. -Error numbers may contain an OS supplied error code in addition to -an ELF API specific error code. -An error number value of zero indicates no error. -.Pp -Function -.Fn elf_errno -is used to retrieve the last error recorded by the ELF library. -Invoking this function has the side-effect of resetting the -ELF library's recorded error number to zero. -.Pp -The function -.Fn elf_errmsg -returns a null-terminated string with a human readable -description of the error specified in argument -.Ar error . -A zero value for argument -.Ar error -retrieves the most recent error encountered by the ELF -library. -An argument value of -1 behaves identically, except that -it guarantees a non-NULL return from -.Fn elf_errmsg . -.Sh RETURN VALUES -Function -.Fn elf_errno -returns a non-zero value encoding the last error encountered -by the ELF library, or zero if no error was encountered. -.Pp -Function -.Fn elf_errmsg -returns a pointer to library local storage for non-zero values -of argument -.Ar error . -With a zero argument, the function will return a NULL pointer if no -error had been encountered by the library, or will return a pointer to -library local storage containing an appropriate message otherwise. -.Sh EXAMPLES -Clearing the ELF library's recorded error number can be accomplished -by invoking -.Fn elf_errno -and discarding its return value. -.Bd -literal -offset indent -/* clear error */ -(void) elf_errno(); -.Ed -.Pp -Retrieving a human-readable description of the current error number -can be done with the following snippet: -.Bd -literal -offset indent -int err; -const char *errmsg; -\&... -err = elf_errno(); -if (err != 0) - errmsg = elf_errmsg(err); -.Ed -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 -.Sh BUGS -Function -.Fn elf_errmsg -is not localized. diff --git a/lib/libelf/elf_errmsg.c b/lib/libelf/elf_errmsg.c deleted file mode 100644 index 193a602..0000000 --- a/lib/libelf/elf_errmsg.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> -#include <string.h> - -#include "_libelf.h" - -/* - * Retrieve a human readable translation for an error message. - */ - -static const char *_libelf_errors[] = { -#define DEFINE_ERROR(N,S) [ELF_E_##N] = S - DEFINE_ERROR(NONE, "No Error"), - DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), - DEFINE_ERROR(ARGUMENT, "Invalid argument"), - DEFINE_ERROR(CLASS, "ELF class mismatch"), - DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), - DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), - DEFINE_ERROR(IO, "I/O error"), - DEFINE_ERROR(LAYOUT, "Layout constraint violation"), - DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), - DEFINE_ERROR(RANGE, "Value out of range of target"), - DEFINE_ERROR(RESOURCE, "Resource exhaustion"), - DEFINE_ERROR(SECTION, "Invalid section descriptor"), - DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), - DEFINE_ERROR(UNIMPL, "Unimplemented feature"), - DEFINE_ERROR(VERSION, "Unknown ELF API version"), - DEFINE_ERROR(NUM, "Unknown error") -#undef DEFINE_ERROR -}; - -const char * -elf_errmsg(int error) -{ - int oserr; - - if (error == 0 && (error = LIBELF_PRIVATE(error)) == 0) - return NULL; - else if (error == -1) - error = LIBELF_PRIVATE(error); - - oserr = error >> LIBELF_OS_ERROR_SHIFT; - error &= LIBELF_ELF_ERROR_MASK; - - if (error < 0 || error >= ELF_E_NUM) - return _libelf_errors[ELF_E_NUM]; - if (oserr) { - strlcpy(LIBELF_PRIVATE(msg), _libelf_errors[error], - sizeof(LIBELF_PRIVATE(msg))); - strlcat(LIBELF_PRIVATE(msg), ": ", sizeof(LIBELF_PRIVATE(msg))); - strlcat(LIBELF_PRIVATE(msg), strerror(oserr), - sizeof(LIBELF_PRIVATE(msg))); - return (const char *)&LIBELF_PRIVATE(msg); - } - return _libelf_errors[error]; -} - -#if defined(LIBELF_TEST_HOOKS) - -const char * -_libelf_get_unknown_error_message(void) -{ - return _libelf_errors[ELF_E_NUM]; -} - -const char * -_libelf_get_no_error_message(void) -{ - return _libelf_errors[0]; -} - -#endif /* LIBELF_TEST_HOOKS */ diff --git a/lib/libelf/elf_fill.3 b/lib/libelf/elf_fill.3 deleted file mode 100644 index a635b43..0000000 --- a/lib/libelf/elf_fill.3 +++ /dev/null @@ -1,52 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 11, 2006 -.Dt ELF_FILL 3 -.Os -.Sh NAME -.Nm elf_fill -.Nd set fill byte for inter-section padding -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft void -.Fn elf_fill "int fill" -.Sh DESCRIPTION -Function -.Fn elf_fill -allows an application to specify a fill value for the padding inserted -between two sections of an ELF file to meet section alignment -constraints. -By default the ELF library uses zero bytes for padding. -.Pp -The ELF library will only pad bytes if the -.Dv ELF_F_LAYOUT -flag is not set for the ELF file. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagelf 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_flag.c b/lib/libelf/elf_flag.c deleted file mode 100644 index a8e948e..0000000 --- a/lib/libelf/elf_flag.c +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" - -unsigned int -elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) -{ - Elf *e; - Elf_Scn *scn; - unsigned int r; - - if (d == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL || e->e_kind != ELF_K_ELF || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = scn->s_flags |= flags; - else - r = scn->s_flags &= ~flags; - - return (r); -} - -unsigned int -elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *ehdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || - (flags & ~(ELF_F_DIRTY|ELF_F_LAYOUT)) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = e->e_flags |= flags; - else - r = e->e_flags &= ~flags; - return (r); -} - -unsigned int -elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *phdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - phdr = e->e_u.e_elf.e_phdr.e_phdr32; - else - phdr = e->e_u.e_elf.e_phdr.e_phdr64; - - if (phdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (s == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = s->s_flags |= flags; - else - r = s->s_flags &= ~flags; - return (r); -} - -unsigned int -elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - return (elf_flagscn(s, c, flags)); -} diff --git a/lib/libelf/elf_flagdata.3 b/lib/libelf/elf_flagdata.3 deleted file mode 100644 index b07e524..0000000 --- a/lib/libelf/elf_flagdata.3 +++ /dev/null @@ -1,159 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 22, 2007 -.Dt ELF_FLAGDATA 3 -.Os -.Sh NAME -.Nm elf_flagdata , -.Nm elf_flagehdr , -.Nm elf_flagelf , -.Nm elf_flagphdr , -.Nm elf_flagscn , -.Nm elf_flagshdr -.Nd manipulate flags associated with ELF(3) data structures -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "unsigned int" -.Fn elf_flagdata "Elf_Data *data" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagehdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagelf "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagphdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagscn "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" -.Sh DESCRIPTION -These functions are used to query, set or reset flags on data -structures associated with an ELF file. -.Pp -Arguments -.Ar data , -.Ar elf -and -.Ar scn -denote the data structures whose flags need to be changed. -These values are allowed to be NULL to simplify error handling in -application code. -.Pp -Argument -.Ar cmd -may have the following values: -.Bl -tag -width ELF_C_SET -.It Dv ELF_C_CLR -The argument -.Ar flags -specifies the flags to be cleared. -.It Dv ELF_C_SET -The argument -.Ar flags -specifies the flags to be set. -.El -.Pp -The argument -.Ar flags -is allowed to have the following flags set: -.Bl -tag -width ELF_F_LAYOUT -.It Dv ELF_F_DIRTY -Mark the associated data structure as needing to be written back -to the underlying file. -A subsequent call to -.Xr elf_update 3 -will resynchronize the library's internal data structures. -.It Dv ELF_F_LAYOUT -This flag is only valid with the -.Fn elf_flagelf -API. -It informs the library that the application will take -responsibility for the layout of the file and that the library is -not to insert any padding in between sections. -.El -.Pp -Marking a given data structure as -.Dq dirty -affects all of its contained elements. -Thus marking an ELF descriptor -.Ar elf -with -.Fn elf_flagelf "elf" "ELF_C_SET" "ELF_F_DIRTY" -means that the entire contents of the descriptor are -.Dq dirty . -.Pp -Using a value of zero for argument -.Ar flags -will return the current set of flags for the data structure being -queried. -.Sh RETURN VALUES -These functions return the updated flags is successful, and zero if -an error is detected. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -An unsupported value was used for the -.Ar cmd -argument. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar flags -had unsupported flags set. -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_flagehdr -was called without an executable header being allocated. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_flagphdr -was called without a program header being allocated. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_newehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf32_newshdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf64_newshdr 3 , -.Xr elf_newdata 3 , -.Xr elf_update 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr gelf_newphdr 3 , -.Xr gelf_newshdr 3 , -.Xr gelf_update_dyn 3 , -.Xr gelf_update_move 3 , -.Xr gelf_update_rel 3 , -.Xr gelf_update_rela 3 , -.Xr gelf_update_sym 3 , -.Xr gelf_update_syminfo 3 diff --git a/lib/libelf/elf_getarhdr.3 b/lib/libelf/elf_getarhdr.3 deleted file mode 100644 index 03f911a..0000000 --- a/lib/libelf/elf_getarhdr.3 +++ /dev/null @@ -1,97 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 15, 2006 -.Dt ELF_GETARHDR 3 -.Os -.Sh NAME -.Nm elf_getarhdr -.Nd retrieve ar(1) header for an archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Arhdr *" -.Fn elf_getarhdr "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_getarhdr -function returns a pointer to an archive member header for -a descriptor -.Ar elf . -This descriptor must have been returned by a prior call to -.Xr elf_begin 3 , -and must be a descriptor for a member inside an -.Xr ar 1 -archive. -.Pp -Structure -.Vt Elf_Arhdr -includes the following members: -.Bl -tag -width indent -.It Vt "char *" Va ar_name -A pointer to a null terminated string containing the translated -name of the archive member. -.It Vt "char *" Va ar_rawname -A pointer to a null terminated string containing the untranslated -name for the archive member, including all -.Xr ar 1 -formatting characters and trailing white space. -.It Vt time_t Va ar_date -The timestamp associated with the member. -.It Vt uid_t Va ar_uid -The uid of the creator of the member. -.It Vt gid_t Va ar_gid -The gid of the creator of the member. -.It Vt mode_t Va ar_mode -The file mode of the member. -.It Vt size_t Va ar_size -The size of the member in bytes. -.El -.Sh RETURN VALUES -This function returns a valid pointer to an -.Vt Elf_Arhdr -structure if successful, or NULL if an error is encountered. -.Sh ERRORS -Function -.Fn elf_getarhdr -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for a member of an -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getarsym 3 , -.Xr elf_memory 3 diff --git a/lib/libelf/elf_getarsym.3 b/lib/libelf/elf_getarsym.3 deleted file mode 100644 index 44b28c8..0000000 --- a/lib/libelf/elf_getarsym.3 +++ /dev/null @@ -1,130 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 15, 2006 -.Dt ELF_GETARSYM 3 -.Os -.Sh NAME -.Nm elf_getarsym -.Nd retrieve the symbol table of an archive -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Arsym *" -.Fn elf_getarsym "Elf *elf" "size_t *ptr" -.Sh DESCRIPTION -The function -.Fn elf_getarsym -retrieves the symbol table for an -.Xr ar 1 -archive, if one is available. -.Pp -Argument -.Ar elf -should be a descriptor for an -.Xr ar 1 -archive opened using -.Fn elf_begin -or -.Fn elf_memory . -.Pp -If the archive -.Ar elf -contains a symbol table with n entries, this function returns a -pointer to an array of n+1 -.Vt Elf_Arsym -structures. -An -.Vt Elf_Arsym -structure has the following elements: -.Bl -tag -width indent -compact -.It Vt "char *" Va as_name -This structure member is a pointer to a null-terminated symbol name. -.It Vt "off_t" Va as_off -This structure member contains the byte offset from the beginning of the archive to -the header for the archive member. -This value is suitable for use with -.Xr elf_rand 3 . -.It Vt "unsigned long" Va as_hash -This structure member contains a portable hash value for the symbol -name, as computed by -.Xr elf_hash 3 . -.El -.Pp -The last entry of the returned array will have a NULL value for member -.Va as_name , -a zero value for member -.Va as_off -and an illegal value of ~0UL for -.Va as_hash . -.Pp -If argument -.Ar ptr -is non-null, the -.Fn elf_getarsym -function will store the number of table entries returned (including the -sentinel entry at the end) into the location it points to. -.Sh RETURN VALUES -Function -.Fn elf_getarsym -returns a pointer to an array of -.Vt Elf_Arsym -structures if successful, or a NULL -pointer if an error was encountered. -.Pp -If argument -.Ar ptr -is non-null and there was no error, the library will store the -number of archive symbol entries returned into the location it -points to. -If argument -.Ar ptr -is non-null and an error was encountered, the library will -set the location pointed to by it to zero. -.Sh ERRORS -Function -.Fn elf_getarsym -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getarhdr 3 , -.Xr elf_hash 3 , -.Xr elf_memory 3 , -.Xr elf_next 3 , -.Xr elf_rand 3 diff --git a/lib/libelf/elf_getbase.3 b/lib/libelf/elf_getbase.3 deleted file mode 100644 index c19445d..0000000 --- a/lib/libelf/elf_getbase.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2006,2008,2010 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 6, 2010 -.Dt ELF_GETBASE 3 -.Os -.Sh NAME -.Nm elf_getbase -.Nd get the base offset for an object file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_getbase "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_getbase -returns the file offset to the first byte of the object referenced by ELF -descriptor -.Ar elf . -.Pp -For descriptors referencing members of archives, the returned offset is -the file offset of the member in its containing archive. -For descriptors to regular objects, the returned offset is (vacuously) -zero. -.Sh RETURN VALUES -Function -.Fn elf_getbase -returns a valid file offset if successful, or -.Pq Vt off_t -.Li -1 -in case of an error. -.Sh ERRORS -Function -.Fn elf_getbase -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getarhdr 3 , -.Xr elf_getident 3 , -.Xr elf_rawfile 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_getdata.3 b/lib/libelf/elf_getdata.3 deleted file mode 100644 index 7961220..0000000 --- a/lib/libelf/elf_getdata.3 +++ /dev/null @@ -1,217 +0,0 @@ -.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd February 18, 2013 -.Dt ELF_GETDATA 3 -.Os -.Sh NAME -.Nm elf_getdata , -.Nm elf_newdata , -.Nm elf_rawdata -.Nd iterate through or allocate section data -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Data *" -.Fn elf_getdata "Elf_Scn *scn" "Elf_Data *data" -.Ft "Elf_Data *" -.Fn elf_newdata "Elf_Scn *scn" -.Ft "Elf_Data *" -.Fn elf_rawdata "Elf_Scn *scn" "Elf_Data *data" -.Sh DESCRIPTION -These functions are used to access and manipulate data descriptors -associated with section descriptors. -Data descriptors used by the ELF library are described in -.Xr elf 3 . -.Pp -Function -.Fn elf_getdata -will return the next data descriptor associated with section descriptor -.Ar scn . -The returned data descriptor will be setup to contain translated data. -Argument -.Ar data -may be NULL, in which case the function returns the first data descriptor -associated with section -.Ar scn . -If argument -.Ar data -is not NULL, it must be a pointer to a data descriptor associated with -section descriptor -.Ar scn , -and function -.Fn elf_getdata -will return a pointer to the next data descriptor for the section, -or NULL when the end of the section's descriptor list is reached. -.Pp -Function -.Fn elf_newdata -will allocate a new data descriptor and append it to the list of data -descriptors associated with section descriptor -.Ar scn . -The new data descriptor will be initialized as follows: -.Bl -tag -width "d_version" -compact -offset indent -.It Va d_align -Set to 1. -.It Va d_buf -Initialized to NULL. -.It Va d_off -Set to (off_t) -1. -This field is under application control if the -.Dv ELF_F_LAYOUT -flag was set on the ELF descriptor. -.It Va d_size -Set to zero. -.It Va d_type -Initialized to -.Dv ELF_T_BYTE . -.It Va d_version -Set to the current working version of the library, as set by -.Xr elf_version 3 . -.El -The application must set these values as appropriate before -calling -.Xr elf_update 3 . -Section -.Ar scn -must be associated with an ELF file opened for writing. -If the application has not requested full control of layout by -setting the -.Dv ELF_F_LAYOUT -flag on descriptor -.Ar elf , -then the data referenced by the returned descriptor will be positioned -after the existing content of the section, honoring the file alignment -specified in member -.Va d_align . -On successful completion of a call to -.Fn elf_newdata , -the ELF library will mark the section -.Ar scn -as -.Dq dirty . -.Pp -Function -.Fn elf_rawdata -is used to step through the data descriptors associated with -section -.Ar scn . -In contrast to function -.Fn elf_getdata , -this function returns untranslated data. -If argument -.Ar data -is NULL, the first data descriptor associated with section -.Ar scn -is returned. -If argument -.Ar data -is not NULL, is must be a data descriptor associated with -section -.Ar scn , -and function -.Fn elf_rawdata -will return the next data descriptor in the list, or NULL -if no further descriptors are present. -Function -.Fn elf_rawdata -always returns -.Vt Elf_Data -structures of type -.Dv ELF_T_BYTE . -.Ss Special handling of zero-sized and SHT_NOBITS sections -For sections of type -.Dv SHT_NOBITS , -and for zero-sized sections, -the functions -.Fn elf_getdata -and -.Fn elf_rawdata -return a pointer to a valid -.Vt Elf_Data -structure that has its -.Va d_buf -member set to NULL and its -.Va d_size -member set to the size of the section. -.Pp -If an application wishes to create a section of type -.Dv SHT_NOBITS , -it should add a data buffer to the section using function -.Fn elf_newdata . -It should then set the -.Va d_buf -and -.Va d_size -members of the returned -.Vt Elf_Data -structure to NULL and the desired size of the section respectively. -.Sh RETURN VALUES -These functions return a valid pointer to a data descriptor if successful, or -NULL if an error occurs. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar scn -was NULL. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with section descriptor -.Ar scn . -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -Section -.Ar scn -had type -.Dv SHT_NULL . -.It Bq Er ELF_E_SECTION -The type of the section -.Ar scn -was not recognized by the library. -.It Bq Er ELF_E_SECTION -The size of the section -.Ar scn -is not a multiple of the file size for its section type. -.It Bq Er ELF_E_SECTION -The file offset for section -.Ar scn -is incorrect. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagdata 3 , -.Xr elf_flagscn 3 , -.Xr elf_getscn 3 , -.Xr elf_getshdr 3 , -.Xr elf_newscn 3 , -.Xr elf_rawfile 3 , -.Xr elf_update 3 , -.Xr elf_version 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_getident.3 b/lib/libelf/elf_getident.3 deleted file mode 100644 index 1031e1d..0000000 --- a/lib/libelf/elf_getident.3 +++ /dev/null @@ -1,83 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd July 3, 2006 -.Dt ELF_GETIDENT 3 -.Os -.Sh NAME -.Nm elf_getident -.Nd return the initial bytes of a file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft char * -.Fn elf_getident "Elf *elf" "size_t *sz" -.Sh DESCRIPTION -Function -.Fn elf_getident -returns a pointer to the initial bytes of the file for descriptor -.Ar elf . -.Pp -If argument -.Ar sz -is non-null, the size of the identification area returned is written -to the location pointed to by -.Ar sz . -This location is set to zero on errors. -.Sh RETURN VALUES -Function -.Fn elf_getident -will return a non-NULL pointer to the initial bytes of the file if -successful, or NULL if an error condition is detected. -.Sh ERRORS -Function -.Fn elf_getident -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_SEQUENCE -ELF descriptor -.Ar elf -was opened for writing and function -.Fn elf_getident -was called before a call to -.Xr elf_update 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getarhdr 3 , -.Xr elf_getbase 3 , -.Xr elf_getflags 3 , -.Xr elf_kind 3 , -.Xr elf_rawfile 3 , -.Xr elf_update 3 , -.Xr gelf 3 , -.Xr gelf_getclass 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getident.c b/lib/libelf/elf_getident.c deleted file mode 100644 index 1b5ae13..0000000 --- a/lib/libelf/elf_getident.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <assert.h> -#include <libelf.h> - -#include "_libelf.h" - -char * -elf_getident(Elf *e, size_t *sz) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - goto error; - } - - if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - goto error; - } - - assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); - - if (sz) { - if (e->e_kind == ELF_K_AR) - *sz = SARMAG; - else if (e->e_kind == ELF_K_ELF) - *sz = EI_NIDENT; - else - *sz = e->e_rawsize; - } - - return (e->e_rawfile); - - error: - if (sz) - *sz = 0; - return (NULL); -} diff --git a/lib/libelf/elf_getphdrnum.3 b/lib/libelf/elf_getphdrnum.3 deleted file mode 100644 index 9a25bf6..0000000 --- a/lib/libelf/elf_getphdrnum.3 +++ /dev/null @@ -1,85 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 5, 2009 -.Dt ELF_GETPHDRNUM 3 -.Os -.Sh NAME -.Nm elf_getphdrnum -.Nd return the number of program headers in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getphdrnum "Elf *elf" "size_t *phnum" -.Sh DESCRIPTION -Function -.Fn elf_getphdrnum -retrieves the number of ELF program headers associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar phnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects and ELF objects that use extended numbering. -.Sh RETURN VALUES -Function -.Fn elf_getphdrnum -returns a zero value if successful, or -1 in case of an error. -.Sh ERRORS -Function -.Fn elf_getphnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable Header. -.It Bq Er ELF_E_HEADER -The ELF Executable Header associated with argument -.Ar elf -was corrupt. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -was corrupt. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getshdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getphnum.3 b/lib/libelf/elf_getphnum.3 deleted file mode 100644 index 174ecb5..0000000 --- a/lib/libelf/elf_getphnum.3 +++ /dev/null @@ -1,92 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 5, 2009 -.Dt ELF_GETPHNUM 3 -.Os -.Sh NAME -.Nm elf_getphnum -.Nd return the number of program headers in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getphnum "Elf *elf" "size_t *phnum" -.Sh DESCRIPTION -This function is deprecated. -Please use function -.Xr elf_getphdrnum 3 -instead. -.Pp -Function -.Fn elf_getphnum -retrieves the number of ELF program headers associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar phnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects and ELF objects that use extended numbering. -.Sh RETURN VALUES -Function -.Fn elf_getphnum -returns a non-zero value if successful, or zero in case of an -error. -.Sh ERRORS -Function -.Fn elf_getphnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable Header. -.It Bq Er ELF_E_HEADER -The ELF Executable Header associated with argument -.Ar elf -was corrupt. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -was corrupt. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getscn.3 b/lib/libelf/elf_getscn.3 deleted file mode 100644 index 1b1b5f9..0000000 --- a/lib/libelf/elf_getscn.3 +++ /dev/null @@ -1,151 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 22, 2007 -.Dt ELF_GETSCN 3 -.Os -.Sh NAME -.Nm elf_getscn , -.Nm elf_ndxscn , -.Nm elf_newscn , -.Nm elf_nextscn -.Nd get/allocate section information for an ELF object -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Scn *" -.Fn elf_getscn "Elf *elf" "size_t index" -.Ft size_t -.Fn elf_ndxscn "Elf_Scn *scn" -.Ft "Elf_Scn *" -.Fn elf_newscn "Elf *elf" -.Ft "Elf_Scn *" -.Fn elf_nextscn "Elf *elf" "Elf_Scn *scn" -.Sh DESCRIPTION -These functions are used to iterate through the sections associated -with an ELF descriptor. -.Pp -Function -.Fn elf_getscn -will return a section descriptor for the section at index -.Ar index -in the object denoted by ELF descriptor -.Ar elf . -An error will be signalled if the specified section does not -exist. -.Pp -Function -.Fn elf_ndxscn -returns the section table index associated with section descriptor -.Ar scn . -.Pp -Function -.Fn elf_newscn -creates a new section and appends it to the list of sections -associated with descriptor -.Ar elf . -The library will automatically increment the -.Va e_shnum -field of the ELF header associated with descriptor -.Ar elf , -and will set the -.Dv ELF_F_DIRTY -flag on the returned section descriptor. -For ELF descriptors opened for writing, the ELF library will -automatically create an empty section at index zero -.Dv ( SHN_UNDEF ) -on the first call to -.Fn elf_newscn . -.Pp -Function -.Fn elf_nextscn -takes a section descriptor -.Ar scn -and returns a pointer to the section descriptor at the next higher -index. -Argument -.Ar scn -is allowed to be NULL, in which case this function will return a -pointer to the section descriptor at index 1. -If no further sections are present, function -.Fn elf_nextscn -will return a NULL pointer. -.Sh RETURN VALUES -Functions -.Fn elf_getscn , -.Fn elf_newscn -and -.Fn elf_nextscn -return a valid pointer to a section descriptor if successful, or -NULL if an error occurs. -.Pp -Function -.Fn elf_ndxscn -returns a valid section table index if successful, or -.Dv SHN_UNDEF -if an error occurs. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar elf -or -.Ar scn -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar index -exceeded the current number of sections in the ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Section descriptor -.Ar scn -was not associated with ELF descriptor -.Ar elf . -.It Bq Er ELF_E_CLASS -Descriptor -.Ar elf -was of an unknown ELF class. -.It Bq Er ELF_E_SECTION -Argument -.Ar elf -specified extended section numbering in the ELF header with the section header at -index -.Dv SHN_UNDEF -not being of type -.Dv SHT_NULL . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagdata 3 , -.Xr elf_flagscn 3 , -.Xr elf_getdata 3 , -.Xr elf_getshdr 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_getshdrnum.3 b/lib/libelf/elf_getshdrnum.3 deleted file mode 100644 index 42a1194..0000000 --- a/lib/libelf/elf_getshdrnum.3 +++ /dev/null @@ -1,77 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 4, 2009 -.Dt ELF_GETSHDRNUM 3 -.Os -.Sh NAME -.Nm elf_getshdrnum -.Nd return the number of sections in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshdrnum "Elf *elf" "size_t *shnum" -.Sh DESCRIPTION -Function -.Fn elf_getshdrnum -retrieves the number of ELF sections associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar shnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects, and ELF objects that use extended section numbering. -.Sh RETURN VALUES -Function -.Fn elf_getshdrnum -returns zero value if successful, or -1 in case of an error. -.Sh ERRORS -Function -.Fn elf_getshdrnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getshdrstrndx.3 b/lib/libelf/elf_getshdrstrndx.3 deleted file mode 100644 index ea4c65c..0000000 --- a/lib/libelf/elf_getshdrstrndx.3 +++ /dev/null @@ -1,78 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 5, 2009 -.Dt ELF_GETSHDRSTRNDX 3 -.Os -.Sh NAME -.Nm elf_getshdrstrndx -.Nd retrieve the index of the section name string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshdrstrndx "Elf *elf" "size_t *ndxptr" -.Sh DESCRIPTION -Function -.Fn elf_getshdrstrndx -retrieves the section index of the string table containing section -names from descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar ndxptr . -.Pp -This function allow applications to process both normal ELF -objects and ELF objects that use extended section numbering uniformly. -.Sh RETURN VALUES -These functions return zero if successful, or -1 in case of an error. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -contained a value in the reserved range of section indices. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getshnum.3 b/lib/libelf/elf_getshnum.3 deleted file mode 100644 index 41431fe..0000000 --- a/lib/libelf/elf_getshnum.3 +++ /dev/null @@ -1,83 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 5, 2009 -.Dt ELF_GETSHNUM 3 -.Os -.Sh NAME -.Nm elf_getshnum -.Nd return the number of sections in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshnum "Elf *elf" "size_t *shnum" -.Sh DESCRIPTION -This function is deprecated. -Please use -.Xr elf_getshdrnum 3 -instead. -.Pp -Function -.Fn elf_getshnum -retrieves the number of ELF sections associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar shnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects, and ELF objects that use extended section numbering. -.Sh RETURN VALUES -Function -.Fn elf_getshnum -returns a non-zero value if successful, or zero in case of an -error. -.Sh ERRORS -Function -.Fn elf_getshnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_getshstrndx.3 b/lib/libelf/elf_getshstrndx.3 deleted file mode 100644 index a720277..0000000 --- a/lib/libelf/elf_getshstrndx.3 +++ /dev/null @@ -1,93 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 5, 2009 -.Dt ELF_GETSHSTRNDX 3 -.Os -.Sh NAME -.Nm elf_getshstrndx , -.Nm elf_setshstrndx -.Nd retrieve/update the index of the section name string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshstrndx "Elf *elf" "size_t *ndxptr" -.Ft int -.Fn elf_setshstrndx "Elf *elf" "size_t ndx" -.Sh DESCRIPTION -Function -.Fn elf_getshstrndx -retrieves the section index of the string table containing section -names from descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar ndxptr . -Function -.Fn elf_getshstrndx -is deprecated. -Please use -.Xr elf_getshdrstrndx 3 -instead. -.Pp -Function -.Fn elf_setshstrndx -sets the index of the section name string table to argument -.Ar ndx . -.Pp -These routines allow applications to process both normal ELF -objects and ELF objects that use extended section numbering uniformly. -.Sh RETURN VALUES -These functions return a non-zero value if successful, or zero in case -of an error. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -contained a value in the reserved range of section indices. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/lib/libelf/elf_hash.3 b/lib/libelf/elf_hash.3 deleted file mode 100644 index 0df2804..0000000 --- a/lib/libelf/elf_hash.3 +++ /dev/null @@ -1,57 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 15, 2006 -.Dt ELF_HASH 3 -.Os -.Sh NAME -.Nm elf_hash -.Nd compute a hash value for a string -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "unsigned long" -.Fn elf_hash "const char *name" -.Sh DESCRIPTION -Function -.Fn elf_hash -computes a portable hash value for the null terminated string -pointed to by argument -.Ar name . -.Pp -The hash value returned is will be identical across -machines of different architectures. -This allows hash tables to be built on one machine and -correctly used on another of a different architecture. -The hash value returned is also guaranteed -.Em not -to be the bit pattern of all ones (~0UL). -.Sh IMPLEMENTATION NOTES -The library internally uses unsigned 32 bit arithmetic to compute -the hash value. -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_kind.3 b/lib/libelf/elf_kind.3 deleted file mode 100644 index de74e57..0000000 --- a/lib/libelf/elf_kind.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 1, 2006 -.Dt ELF_KIND 3 -.Os -.Sh NAME -.Nm elf_kind -.Nd determine ELF file type -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft Elf_Kind -.Fn elf_kind "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_kind -function identifies the kind of file associated with its argument -.Ar elf . -The argument -.Ar elf -is allowed to be NULL. -.Sh RETURN VALUES -The -.Fn elf_kind -function returns one of the following values: -.Bl -tag -width indent -.It Dv ELF_K_AR -The file associated with argument -.Ar elf -is an archive. -.It Dv ELF_K_ELF -The file associated with argument -.Ar elf -is an ELF file. -.It Dv ELF_K_NONE -The argument -.Ar elf -was NULL, or the ELF library could not determine the type of the file -associated with argument -.Ar elf , -or an error occurred when processing. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getident 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_memory.3 b/lib/libelf/elf_memory.3 deleted file mode 100644 index 83de512..0000000 --- a/lib/libelf/elf_memory.3 +++ /dev/null @@ -1,122 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 28, 2006 -.Dt ELF_MEMORY 3 -.Os -.Sh NAME -.Nm elf_memory -.Nd process an ELF or ar(1) archive mapped into memory -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf *" -.Fn elf_memory "char *image" "size_t size" -.Sh DESCRIPTION -Function -.Fn elf_memory -is used to process an ELF file or -.Xr ar 1 -archive whose image is present in memory. -.Pp -Argument -.Ar image -points to the start of the memory image of the file or archive. -Argument -.Ar size -contains the size in bytes of the memory image. -.Pp -The ELF descriptor is created for reading (i.e., analogous to the -use of -.Xr elf_begin 3 -with a command argument value of -.Dv ELF_C_READ Ns ). -.Sh RETURN VALUES -Function -.Fn elf_memory -returns a pointer to a new ELF descriptor if successful, or NULL if an -error occurred. -.Pp -The return value may be queried for the file type using -.Xr elf_kind 3 . -.Sh EXAMPLES -To read parse an elf file, use: -.Bd -literal -offset indent -int fd; -void *p; -struct stat sb; -Elf *e; -\&... -if ((fd = open("./elf-file", O_RDONLY)) < 0 || - fstat(fd, &sb) < 0 || - (p = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == - MAP_FAILED) { - ... handle system error ... -} - -if ((e = elf_memory(p, sb.st_size)) == NULL) { - ... handle elf(3) error ... -} -\&... use ELF descriptor "e" here ... -.Ed -.Sh ERRORS -Function -.Fn elf_memory -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was used for argument -.Ar image -or the value of argument -.Ar sz -was zero. -.It Bq Er ELF_E_HEADER -The header of the ELF object contained an unsupported value in its -.Va e_ident[EI_CLASS] -field. -.It Bq Er ELF_E_HEADER -The header of the ELF object contained an unsupported value in its -.Va e_ident[EI_DATA] -field. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_memory -was called before a working version was set using -.Xr elf_version 3 . -.It Bq Er ELF_E_VERSION -The argument -.Ar image -corresponds to an ELF file with an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_errno 3 , -.Xr elf_kind 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_memory.c b/lib/libelf/elf_memory.c deleted file mode 100644 index f42378e..0000000 --- a/lib/libelf/elf_memory.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <libelf.h> -#include <string.h> - -#include "_libelf.h" - -Elf * -elf_memory(char *image, size_t sz) -{ - Elf *e; - - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - if (image == NULL || sz == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((e = _libelf_allocate_elf()) == NULL) - return (NULL); - - e->e_cmd = ELF_C_READ; - e->e_rawfile = image; - e->e_rawsize = sz; - -#undef LIBELF_IS_ELF -#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ - (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ - (P)[EI_MAG3] == ELFMAG3) - - if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_class = image[EI_CLASS]; - e->e_byteorder = image[EI_DATA]; - e->e_version = image[EI_VERSION]; - - if (e->e_version > EV_CURRENT) { - e = _libelf_release_elf(e); - LIBELF_SET_ERROR(VERSION, 0); - return (NULL); - } - - if ((e->e_byteorder != ELFDATA2LSB && e->e_byteorder != - ELFDATA2MSB) || (e->e_class != ELFCLASS32 && e->e_class != - ELFCLASS64)) { - e = _libelf_release_elf(e); - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - } else if (sz >= SARMAG && - strncmp(image, ARMAG, (size_t) SARMAG) == 0) { - _libelf_init_elf(e, ELF_K_AR); - e = _libelf_ar_open(e); - } else - _libelf_init_elf(e, ELF_K_NONE); - - return (e); -} diff --git a/lib/libelf/elf_next.3 b/lib/libelf/elf_next.3 deleted file mode 100644 index 184ab9f..0000000 --- a/lib/libelf/elf_next.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 17, 2006 -.Dt ELF_NEXT 3 -.Os -.Sh NAME -.Nm elf_next -.Nd provide sequential access to the next archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft Elf_Cmd -.Fn elf_next "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_next -function causes the ELF archive descriptor corresponding to argument -.Ar elf -to be adjusted to provide access to the next member in -the archive on a subsequent call to -.Fn elf_begin . -.Pp -The return value of -.Fn elf_next -is suitable for use in a loop invoking -.Fn elf_begin . -.Sh RETURN VALUES -If successful, function -.Fn elf_next -returns the value -.Dv ELF_C_READ . -Otherwise, if argument -.Ar elf -was not associated with an archive, or if it was -.Dv NULL , -or if any other error occurred, the value -.Dv ELF_C_NULL -is returned. -.Sh EXAMPLES -To process all the members of an archive use: -.Bd -literal -offset indent -Elf_Cmd cmd; -Elf *archive, *e; -\&... -cmd = ELF_C_READ; -archive = elf_begin(fd, cmd, NULL); -while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) -{ - ... process `e' here ... - - cmd = elf_next(e); - elf_end(e); -} -elf_end(archive); -.Ed -.Sh ERRORS -Function -.Fn elf_next -may fail with the following error: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not associated with a containing -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_rand 3 diff --git a/lib/libelf/elf_next.c b/lib/libelf/elf_next.c deleted file mode 100644 index 1e1627c..0000000 --- a/lib/libelf/elf_next.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <assert.h> -#include <libelf.h> - -#include "_libelf.h" - -Elf_Cmd -elf_next(Elf *e) -{ - off_t next; - Elf *parent; - - if (e == NULL) - return (ELF_C_NULL); - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (ELF_C_NULL); - } - - assert (parent->e_kind == ELF_K_AR); - assert (parent->e_cmd == ELF_C_READ); - assert((uintptr_t) e->e_rawfile % 2 == 0); - assert(e->e_rawfile > parent->e_rawfile); - - next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; - next = (next + 1) & ~1; /* round up to an even boundary */ - - parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? (off_t) 0 : next; - - return (ELF_C_READ); -} diff --git a/lib/libelf/elf_phnum.c b/lib/libelf/elf_phnum.c deleted file mode 100644 index 4ec108e..0000000 --- a/lib/libelf/elf_phnum.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <libelf.h> - -#include "_libelf.h" - -static int -_libelf_getphdrnum(Elf *e, size_t *phnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *phnum = e->e_u.e_elf.e_nphdr; - - return (0); -} - -int -elf_getphdrnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum)); -} - -/* Deprecated API */ -int -elf_getphnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum) >= 0); -} diff --git a/lib/libelf/elf_rand.3 b/lib/libelf/elf_rand.3 deleted file mode 100644 index e4d23d7..0000000 --- a/lib/libelf/elf_rand.3 +++ /dev/null @@ -1,118 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 17, 2006 -.Dt ELF_RAND 3 -.Os -.Sh NAME -.Nm elf_rand -.Nd provide sequential access to the next archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_rand "Elf *archive" "off_t offset" -.Sh DESCRIPTION -The -.Fn elf_rand -function causes the ELF descriptor -.Ar archive -to be adjusted so that the next call to -.Xr elf_begin 3 -will provide access to the archive member at byte offset -.Ar offset -in the archive. -Argument -.Ar offset -is the byte offset from the start of the archive to the beginning of -the archive header for the desired member. -.Pp -Archive member offsets may be retrieved using the -.Xr elf_getarsym 3 -function. -.Sh RETURN VALUES -Function -.Fn elf_rand -returns -.Ar offset -if successful or zero in case of an error. -.Sh EXAMPLES -To process all the members of an archive use: -.Bd -literal -offset indent -off_t off; -Elf *archive, *e; -\&... -cmd = ELF_C_READ; -archive = elf_begin(fd, cmd, NULL); -while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) -{ - ... process `e' here ... - elf_end(e); - - off = ...new value...; - if (elf_rand(archive, off) != off) { - ... process error ... - } -} -elf_end(archive); -.Ed -.Pp -To rewind an archive, use: -.Bd -literal -offset indent -Elf *archive; -\&... -if (elf_rand(archive, SARMAG) != SARMAG) { - ... error ... -} -.Ed -.Sh ERRORS -Function -.Fn elf_rand -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar archive -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar archive -was not a descriptor for an -.Xr ar 1 -archive. -.It Bq Er ELF_E_ARCHIVE -Argument -.Ar offset -did not correspond to the start of an archive member header. -.El -.Sh SEE ALSO -.Xr ar 1 , -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_getarsym 3 , -.Xr elf_next 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_rand.c b/lib/libelf/elf_rand.c deleted file mode 100644 index 0b79c5c..0000000 --- a/lib/libelf/elf_rand.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <libelf.h> - -#include "_libelf.h" - -off_t -elf_rand(Elf *ar, off_t offset) -{ - struct ar_hdr *arh; - - if (ar == NULL || ar->e_kind != ELF_K_AR || - (offset & 1) || offset < SARMAG || - offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return 0; - } - - arh = (struct ar_hdr *) (ar->e_rawfile + offset); - - /* a too simple sanity check */ - if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { - LIBELF_SET_ERROR(ARCHIVE, 0); - return 0; - } - - ar->e_u.e_ar.e_next = offset; - - return (offset); -} diff --git a/lib/libelf/elf_rawfile.3 b/lib/libelf/elf_rawfile.3 deleted file mode 100644 index 4458148..0000000 --- a/lib/libelf/elf_rawfile.3 +++ /dev/null @@ -1,76 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd July 3, 2006 -.Dt ELF_RAWFILE 3 -.Os -.Sh NAME -.Nm elf_rawfile -.Nd return uninterpreted contents of an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft char * -.Fn elf_rawfile "Elf *elf" "size_t *sz" -.Sh DESCRIPTION -Function -.Fn elf_rawfile -returns the uninterpreted contents of the file referenced by ELF descriptor -.Ar elf . -.Pp -If argument -.Ar sz -is non-null, the function stores the file's size in bytes -in the location to which it points. -A value of zero is written to this location if an error is -encountered. -.Sh RETURN VALUES -Function -.Fn elf_rawfile -returns a valid pointer if successful or NULL if an error occurs. -.Sh ERRORS -Function -.Fn elf_rawfile -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_SEQUENCE -Argument -.Ar elf -was opened for writing and function -.Fn elf_rawfile -was invoked before -.Xr elf_update 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getident 3 , -.Xr elf_kind 3 , -.Xr elf_update 3 diff --git a/lib/libelf/elf_scn.c b/lib/libelf/elf_scn.c deleted file mode 100644 index 2eefca1..0000000 --- a/lib/libelf/elf_scn.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <errno.h> -#include <gelf.h> -#include <libelf.h> -#include <stdlib.h> - -#include "_libelf.h" - -/* - * Load an ELF section table and create a list of Elf_Scn structures. - */ -int -_libelf_load_scn(Elf *e, void *ehdr) -{ - int ec, swapbytes; - size_t fsz, i, shnum; - uint64_t shoff; - char *src; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf_Scn *scn; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(e != NULL); - assert(ehdr != NULL); - assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); - -#define CHECK_EHDR(E,EH) do { \ - if (fsz != (EH)->e_shentsize || \ - shoff + fsz * shnum > e->e_rawsize) { \ - LIBELF_SET_ERROR(HEADER, 0); \ - return (0); \ - } \ - } while (0) - - ec = e->e_class; - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - shnum = e->e_u.e_elf.e_nscn; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - shoff = (uint64_t) eh32->e_shoff; - CHECK_EHDR(e, eh32); - } else { - eh64 = (Elf64_Ehdr *) ehdr; - shoff = eh64->e_shoff; - CHECK_EHDR(e, eh64); - } - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - - swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); - src = e->e_rawfile + shoff; - - /* - * If the file is using extended numbering then section #0 - * would have already been read in. - */ - - i = 0; - if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == - STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); - - i = 1; - src += fsz; - } - - for (; i < shnum; i++, src += fsz) { - if ((scn = _libelf_allocate_scn(e, i)) == NULL) - return (0); - - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, - (size_t) 1, swapbytes); - - if (ec == ELFCLASS32) { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr32.sh_offset; - scn->s_size = scn->s_shdr.s_shdr32.sh_size; - } else { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr64.sh_offset; - scn->s_size = scn->s_shdr.s_shdr64.sh_size; - } - } - - e->e_flags |= LIBELF_F_SHDRS_LOADED; - - return (1); -} - - -Elf_Scn * -elf_getscn(Elf *e, size_t index) -{ - int ec; - void *ehdr; - Elf_Scn *s; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_scn(e, ehdr) == 0) - return (NULL); - - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) - if (s->s_ndx == index) - return (s); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -size_t -elf_ndxscn(Elf_Scn *s) -{ - if (s == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (SHN_UNDEF); - } - return (s->s_ndx); -} - -Elf_Scn * -elf_newscn(Elf *e) -{ - int ec; - void *ehdr; - Elf_Scn *scn; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - /* - * The application may be asking for a new section descriptor - * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We - * need to bring in the existing section information before - * appending a new one to the list. - * - * Per the ELF(3) API, an application is allowed to open a - * file using ELF_C_READ, mess with its internal structure and - * use elf_update(...,ELF_C_NULL) to compute its new layout. - */ - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_scn(e, ehdr) == 0) - return (NULL); - - if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - assert(e->e_u.e_elf.e_nscn == 0); - if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == - NULL) - return (NULL); - e->e_u.e_elf.e_nscn++; - } - - assert(e->e_u.e_elf.e_nscn > 0); - - if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) - return (NULL); - - e->e_u.e_elf.e_nscn++; - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - return (scn); -} - -Elf_Scn * -elf_nextscn(Elf *e, Elf_Scn *s) -{ - if (e == NULL || (e->e_kind != ELF_K_ELF) || - (s && s->s_elf != e)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (s == NULL ? elf_getscn(e, (size_t) 1) : - STAILQ_NEXT(s, s_next)); -} diff --git a/lib/libelf/elf_shnum.c b/lib/libelf/elf_shnum.c deleted file mode 100644 index 50cd0f5..0000000 --- a/lib/libelf/elf_shnum.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <libelf.h> - -#include "_libelf.h" - -static int -_libelf_getshdrnum(Elf *e, size_t *shnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *shnum = e->e_u.e_elf.e_nscn; - - return (0); -} - -int -elf_getshdrnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum)); -} - -/* Deprecated API. */ -int -elf_getshnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum) >= 0); -} diff --git a/lib/libelf/elf_shstrndx.c b/lib/libelf/elf_shstrndx.c deleted file mode 100644 index 2c8b1b4..0000000 --- a/lib/libelf/elf_shstrndx.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <libelf.h> - -#include "_libelf.h" - -static int -_libelf_getshdrstrndx(Elf *e, size_t *strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *strndx = e->e_u.e_elf.e_strndx; - - return (0); -} - -int -elf_getshdrstrndx(Elf *e, size_t *strndx) -{ - return (_libelf_getshdrstrndx(e, strndx)); -} - -int -elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ -{ - return (_libelf_getshdrstrndx(e, strndx) >= 0); -} - -int -elf_setshstrndx(Elf *e, size_t strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - return (_libelf_setshstrndx(e, eh, ec, strndx)); -} diff --git a/lib/libelf/elf_strptr.3 b/lib/libelf/elf_strptr.3 deleted file mode 100644 index d2282df..0000000 --- a/lib/libelf/elf_strptr.3 +++ /dev/null @@ -1,116 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd December 16, 2006 -.Dt ELF_STRPTR 3 -.Os -.Sh NAME -.Nm elf_strptr -.Nd retrieve a string pointer in a string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "char *" -.Fn elf_strptr "Elf *elf" "size_t scndx" "size_t stroffset" -.Sh DESCRIPTION -Function -.Fn elf_strptr -allows an application to convert a string table offset to a string -pointer, correctly translating the offset in the presence -of multiple -.Vt Elf_Data -descriptors covering the contents of the section. -.Pp -Argument -.Ar elf -is a descriptor for an ELF object. -Argument -.Ar scndx -is the section index for an ELF string table. -Argument -.Ar stroffset -is the index of the desired string in the string -table. -.Sh RETURN VALUES -Function -.Fn elf_strptr -returns a valid pointer on success or NULL in case an error was -encountered. -.Sh ERRORS -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar scndx -was not the section index for a string table. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar stroffset -exceeded the size of the string table. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar stroffset -index an unallocated region of the string table. -.It Bq Er ELF_E_DATA -Offset -.Ar stroffset -indexed a region that was not covered by any Elf_Data -descriptor. -.It Bq Er ELF_E_DATA -An erroneous -.Vt Elf_Data -descriptor was part of the section specified by argument -.Ar scndx . -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -contained an invalid section header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -Section -.Ar scndx -contained a malformed section header. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getshdr 3 , -.Xr elf64_getshdr 3 , -.Xr elf_getdata 3 , -.Xr elf_rawdata 3 , -.Xr gelf 3 , -.Xr gelf_getshdr 3 diff --git a/lib/libelf/elf_strptr.c b/lib/libelf/elf_strptr.c deleted file mode 100644 index e137622..0000000 --- a/lib/libelf/elf_strptr.c +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -/* - * Convert an ELF section#,offset pair to a string pointer. - */ - -char * -elf_strptr(Elf *e, size_t scndx, size_t offset) -{ - Elf_Scn *s; - Elf_Data *d; - size_t alignment, count; - GElf_Shdr shdr; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((s = elf_getscn(e, scndx)) == NULL || - gelf_getshdr(s, &shdr) == NULL) - return (NULL); - - if (/*shdr.sh_type != SHT_STRTAB || */ - offset >= shdr.sh_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - d = NULL; - if (e->e_flags & ELF_F_LAYOUT) { - - /* - * The application is taking responsibility for the - * ELF object's layout, so we can directly translate - * an offset to a `char *' address using the `d_off' - * members of Elf_Data descriptors. - */ - while ((d = elf_getdata(s, d)) != NULL) { - - if (d->d_buf == 0 || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if (offset >= d->d_off && - offset < d->d_off + d->d_size) - return ((char *) d->d_buf + offset - d->d_off); - } - } else { - /* - * Otherwise, the `d_off' members are not useable and - * we need to compute offsets ourselves, taking into - * account 'holes' in coverage of the section introduced - * by alignment requirements. - */ - count = (size_t) 0; /* cumulative count of bytes seen */ - while ((d = elf_getdata(s, d)) != NULL && count <= offset) { - - if (d->d_buf == NULL || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((alignment = d->d_align) > 1) { - if ((alignment & (alignment - 1)) != 0) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - count = roundup2(count, alignment); - } - - if (offset < count) { - /* offset starts in the 'hole' */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (offset < count + d->d_size) { - if (d->d_buf != NULL) - return ((char *) d->d_buf + - offset - count); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - count += d->d_size; - } - } - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/lib/libelf/elf_types.m4 b/lib/libelf/elf_types.m4 deleted file mode 100644 index 9d7add8..0000000 --- a/lib/libelf/elf_types.m4 +++ /dev/null @@ -1,315 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * ELF types, defined in the "enum Elf_Type" API. - * - * The members of the list form a 3-tuple: (name, C-type-suffix, OSversion). - * + `name' is an Elf_Type symbol without the `ELF_T_' prefix. - * + `C-type-suffix' is the suffix for Elf32_ and Elf64_ type names. - * + `version' is the OS version the symbol first appeared in. - * - * OS revisions of note are: - * 600102 - The earliest (6.0-STABLE) version supported by this code. - * 700009 - Symbol versioning and ELF64 type changes. - * 700025 - More ELF types and the introduction of libelf. - */ - -define(`ELF_TYPE_LIST', - ``ADDR, Addr, 600102', - `BYTE, Byte, 600102', - `CAP, Cap, 700025', - `DYN, Dyn, 600102', - `EHDR, Ehdr, 600102', - `GNUHASH, -, 800062', - `HALF, Half, 600102', - `LWORD, Lword, 700025', - `MOVE, Move, 700025', - `MOVEP, MoveP, 700025', - `NOTE, Note, 600102', - `OFF, Off, 600102', - `PHDR, Phdr, 600102', - `REL, Rel, 600102', - `RELA, Rela, 600102', - `SHDR, Shdr, 600102', - `SWORD, Sword, 600102', - `SXWORD, Sxword, 700009', - `SYMINFO, Syminfo, 700025', - `SYM, Sym, 600102', - `VDEF, Verdef, 700009', - `VNEED, Verneed, 700009', - `WORD, Word, 600102', - `XWORD, Xword, 700009', - `NUM, _, _'') - -/* - * DEFINE_STRUCT(NAME,MEMBERLIST...) - * - * Map a type name to its members. - * - * Each member-list element comprises of pairs of (field name, type), - * in the sequence used in the file representation of `NAME'. - * - * Each member list element comprises a pair containing a field name - * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, - * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. - * - * The last element of a member list is the null element: `_,_'. - */ - -define(`DEFINE_STRUCT',`define(`$1_DEF',shift($@))dnl') - -DEFINE_STRUCT(`Elf32_Cap', - ``c_tag, WORD', - `c_un.c_val, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Cap', - ``c_tag, XWORD', - `c_un.c_val, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Dyn', - ``d_tag, SWORD', - `d_un.d_ptr, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Dyn', - ``d_tag, SXWORD', - `d_un.d_ptr, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Ehdr', - ``e_ident, IDENT', - `e_type, HALF', - `e_machine, HALF', - `e_version, WORD', - `e_entry, ADDR', - `e_phoff, OFF', - `e_shoff, OFF', - `e_flags, WORD', - `e_ehsize, HALF', - `e_phentsize, HALF', - `e_phnum, HALF', - `e_shentsize, HALF', - `e_shnum, HALF', - `e_shstrndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Ehdr', - ``e_ident, IDENT', - `e_type, HALF', - `e_machine, HALF', - `e_version, WORD', - `e_entry, ADDR', - `e_phoff, OFF', - `e_shoff, OFF', - `e_flags, WORD', - `e_ehsize, HALF', - `e_phentsize, HALF', - `e_phnum, HALF', - `e_shentsize, HALF', - `e_shnum, HALF', - `e_shstrndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Move', - ``m_value, LWORD', - `m_info, WORD', - `m_poffset, WORD', - `m_repeat, HALF', - `m_stride, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Move', - ``m_value, LWORD', - `m_info, XWORD', - `m_poffset, XWORD', - `m_repeat, HALF', - `m_stride, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Phdr', - ``p_type, WORD', - `p_offset, OFF', - `p_vaddr, ADDR', - `p_paddr, ADDR', - `p_filesz, WORD', - `p_memsz, WORD', - `p_flags, WORD', - `p_align, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Phdr', - ``p_type, WORD', - `p_flags, WORD', - `p_offset, OFF', - `p_vaddr, ADDR', - `p_paddr, ADDR', - `p_filesz, XWORD', - `p_memsz, XWORD', - `p_align, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Rel', - ``r_offset, ADDR', - `r_info, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Rel', - ``r_offset, ADDR', - `r_info, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Rela', - ``r_offset, ADDR', - `r_info, WORD', - `r_addend, SWORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Rela', - ``r_offset, ADDR', - `r_info, XWORD', - `r_addend, SXWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Shdr', - ``sh_name, WORD', - `sh_type, WORD', - `sh_flags, WORD', - `sh_addr, ADDR', - `sh_offset, OFF', - `sh_size, WORD', - `sh_link, WORD', - `sh_info, WORD', - `sh_addralign, WORD', - `sh_entsize, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Shdr', - ``sh_name, WORD', - `sh_type, WORD', - `sh_flags, XWORD', - `sh_addr, ADDR', - `sh_offset, OFF', - `sh_size, XWORD', - `sh_link, WORD', - `sh_info, WORD', - `sh_addralign, XWORD', - `sh_entsize, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Sym', - ``st_name, WORD', - `st_value, ADDR', - `st_size, WORD', - `st_info, BYTE', - `st_other, BYTE', - `st_shndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Sym', - ``st_name, WORD', - `st_info, BYTE', - `st_other, BYTE', - `st_shndx, HALF', - `st_value, ADDR', - `st_size, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Syminfo', - ``si_boundto, HALF', - `si_flags, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Syminfo', - ``si_boundto, HALF', - `si_flags, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verdaux', - ``vda_name, WORD', - `vda_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verdaux', - ``vda_name, WORD', - `vda_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verdef', - ``vd_version, HALF', - `vd_flags, HALF', - `vd_ndx, HALF', - `vd_cnt, HALF', - `vd_hash, WORD', - `vd_aux, WORD', - `vd_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verdef', - ``vd_version, HALF', - `vd_flags, HALF', - `vd_ndx, HALF', - `vd_cnt, HALF', - `vd_hash, WORD', - `vd_aux, WORD', - `vd_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verneed', - ``vn_version, HALF', - `vn_cnt, HALF', - `vn_file, WORD', - `vn_aux, WORD', - `vn_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verneed', - ``vn_version, HALF', - `vn_cnt, HALF', - `vn_file, WORD', - `vn_aux, WORD', - `vn_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Vernaux', - ``vna_hash, WORD', - `vna_flags, HALF', - `vna_other, HALF', - `vna_name, WORD', - `vna_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Vernaux', - ``vna_hash, WORD', - `vna_flags, HALF', - `vna_other, HALF', - `vna_name, WORD', - `vna_next, WORD', - `_,_'') diff --git a/lib/libelf/elf_update.3 b/lib/libelf/elf_update.3 deleted file mode 100644 index 8803730..0000000 --- a/lib/libelf/elf_update.3 +++ /dev/null @@ -1,286 +0,0 @@ -.\" Copyright (c) 2006,2007-2008 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd March 19, 2008 -.Dt ELF_UPDATE 3 -.Os -.Sh NAME -.Nm elf_update -.Nd update an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_update "Elf *elf" "Elf_Cmd cmd" -.Sh DESCRIPTION -Function -.Fn elf_update -causes the library to recalculate the structure of an ELF -object and optionally write out the image of the object -to file. -.Pp -Argument -.Ar elf -is a descriptor to an ELF object. -Argument -.Ar cmd -can take on the following values: -.Bl -tag -width "ELF_C_WRITE" -.It Dv ELF_C_NULL -The library will recalculate structural information flagging -modified structures with the -.Dv ELF_F_DIRTY -flag, but will not write back data to the underlying file image. -.It Dv ELF_C_WRITE -The library will recalculate structural information and will -also write the new image to the underlying file. -.El -.Ss File Layout -If the -.Dv ELF_F_LAYOUT -flag has been set on the ELF descriptor, the application assumes full -responsibility for the layout of the ELF object. -If this flag is not set, the ELF library will compute the layout of the -file from its associated section descriptors. -.Pp -It is the application's responsibility to manage the following -structure members in the ELF file: -.Bl -tag -width indent -.It "Executable Header" -The ELF executable header is described in -.Xr elf 5 . -The following members of the ELF executable header are the application's -responsibility: -.Pp -.Bl -tag -width "e_ident[EI_OSABI]" -compact -.It Va e_entry -Set to the desired entry address for executables. -.It Va e_flags -Set to the desired processor specific flags. -.It Va "e_ident[EI_DATA]" -Must be set to one of -.Dv ELFDATA2LSB -or -.Dv ELFDATA2MSB . -.It Va "e_ident[EI_OSABI]" -Set to the OS ABI desired. -For -.Fx -executables, this field should be set to -.Dv ELFOSABI_FREEBSD . -.It Va e_machine -Set to the desired machine architecture, one of the -.Dv EM_* -values in -.In sys/elf_common.h . -.It Va e_phoff -If the application is managing the object's layout, it must -set this field to the file offset of the ELF program header table. -.It Va e_shoff -If the application is managing the object's layout, it must -set this field to the file offset of the ELF section header table. -.It Va e_shstrndx -Set to the index of the string table containing -section names. -.It Va e_type -Set to the type of the ELF object, one of the -.Dv ET_* -values in -.In sys/elf_common.h . -.It Va e_version -Set to the desired version of the ELF object. -.El -.It "Program Header" -All fields of the entries in the program header table are -under application control. -.It "Section Header" -The ELF section header is described in -.Xr elf 5 . -The following members of the ELF section header are the -application's responsibility: -.Pp -.Bl -tag -width "sh_addralign" -compact -.It Va sh_addr -Set to the physical memory address where the section should reside. -.It Va sh_addralign -If the application is managing the file layout, it must set this -field to the desired alignment for the section's contents. -This value must be a power of two. -.It Va sh_entsize -Set to the size of each entry, for sections containing fixed size -elements, or set to zero for sections without fixed size elements. -If the application is not managing file layout, it may leave this -field as zero for those sections whose types known to the library. -.It Va sh_flags -Set to the desired section flags. -.It Va sh_info -Set as described in -.Xr elf 5 . -.It Va sh_link -Set as described in -.Xr elf 5 . -.It Va sh_name -Set to the index of the section's name in the string table containing -section names. -.It Va sh_offset -If the application is managing the file layout, it must set this -field to the file offset of the section's contents. -.It Va sh_size -If the application is managing the file layout, it must set this -field to the file size of the section's contents. -.It Va sh_type -Set to the type of the section. -.El -.El -.Pp -Gaps in the coverage of the file's contents will be set to the fill value -specified by -.Xr elf_fill 3 . -.Pp -If the application has requested full control over the file's layout by -setting the -.Dv ELF_F_LAYOUT -flag on the ELF descriptor, it should ensure that there are no -gaps in the coverage of the file's contents. -.Pp -All pointers to -.Vt Elf_Scn -and -.Vt Elf_Data -descriptors associated with descriptor -.Ar elf -should be considered as invalid after a call to -.Fn elf_update . -.Sh RETURN VALUES -Function -.Fn elf_update -returns the total size of the file image if successful, or -1 if an -error occurred. -.Sh ERRORS -This function may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -was not recognized. -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -The -.Va e_ident[EI_CLASS] -field of the executable header of argument -.Ar elf -did not match the class of the file. -.It Bq Er ELF_E_DATA -An -.Vt Elf_Data -descriptor contained in argument -.Ar elf -specified a type incompatible with its containing section. -.It Bq Er ELF_E_HEADER -The ELF header in argument -.Ar elf -requested a different byte order from the byte order already -associated with the file. -.It Bq Er ELF_E_IO -An I/O error was encountered. -.It Bq Er ELF_E_LAYOUT -An -.Vt Elf_Data -descriptor contained in argument -.Ar elf -specified an alignment incompatible with its containing section. -.It Bq Er ELF_E_LAYOUT -Argument -.Ar elf -contained section descriptors that overlapped in extent. -.It Bq Er ELF_E_LAYOUT -Argument -.Ar elf -contained section descriptors that were incorrectly aligned or were -too small for their data. -.It Bq Er ELF_E_LAYOUT -The flag -.Dv ELF_F_LAYOUT -was set on the Elf descriptor and the section header table overlapped -an extent in the object mapped by a section descriptor. -.It Bq Er ELF_E_MODE -An -.Dv ELF_C_WRITE -operation was requested with an ELF descriptor that was not opened for -writing or updating. -.It Bq Er ELF_E_SECTION -Argument -.Ar elf -contained a section with an unrecognized type. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -had an illegal section type. -.It Bq Er ELF_E_SEQUENCE -An -.Dv ELF_C_WRITE -operation was requested after a prior call to -.Fn elf_cntl elf ELF_C_FDDONE -disassociated the ELF descriptor -.Ar elf -from its underlying file. -.It Bq Er ELF_E_VERSION -Argument -.Ar elf -had an unsupported version or contained an -.Vt Elf_Data -descriptor with an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf32_getphdr 3 , -.Xr elf32_newehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf64_getphdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf_cntl 3 , -.Xr elf_fill 3 , -.Xr elf_flagehdr 3 , -.Xr elf_flagelf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr elf_newdata 3 , -.Xr elf_newscn 3 , -.Xr elf_rawdata 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr gelf_newphdr 3 , -.Xr elf 5 diff --git a/lib/libelf/elf_update.c b/lib/libelf/elf_update.c deleted file mode 100644 index 813d2bcb..0000000 --- a/lib/libelf/elf_update.c +++ /dev/null @@ -1,968 +0,0 @@ -/*- - * Copyright (c) 2006-2008 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/mman.h> -#include <sys/param.h> - -#include <assert.h> -#include <errno.h> -#include <gelf.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "_libelf.h" - -/* - * Layout strategy: - * - * - Case 1: ELF_F_LAYOUT is asserted - * In this case the application has full control over where the - * section header table, program header table, and section data - * will reside. The library only perform error checks. - * - * - Case 2: ELF_F_LAYOUT is not asserted - * - * The library will do the object layout using the following - * ordering: - * - The executable header is placed first, are required by the - * ELF specification. - * - The program header table is placed immediately following the - * executable header. - * - Section data, if any, is placed after the program header - * table, aligned appropriately. - * - The section header table, if needed, is placed last. - * - * There are two sub-cases to be taken care of: - * - * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR - * - * In this sub-case, the underlying ELF object may already have - * content in it, which the application may have modified. The - * library will retrieve content from the existing object as - * needed. - * - * - Case 2b: e->e_cmd == ELF_C_WRITE - * - * The ELF object is being created afresh in this sub-case; - * there is no pre-existing content in the underlying ELF - * object. - */ - -/* - * Compute the extents of a section, by looking at the data - * descriptors associated with it. The function returns 1 if - * successful, or zero if an error was detected. - */ -static int -_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) -{ - int ec; - size_t fsz, msz; - Elf_Data *d; - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - unsigned int elftype; - uint32_t sh_type; - uint64_t d_align; - uint64_t sh_align, sh_entsize, sh_offset, sh_size; - uint64_t scn_size, scn_alignment; - - ec = e->e_class; - - shdr32 = &s->s_shdr.s_shdr32; - shdr64 = &s->s_shdr.s_shdr64; - if (ec == ELFCLASS32) { - sh_type = shdr32->sh_type; - sh_align = (uint64_t) shdr32->sh_addralign; - sh_entsize = (uint64_t) shdr32->sh_entsize; - sh_offset = (uint64_t) shdr32->sh_offset; - sh_size = (uint64_t) shdr32->sh_size; - } else { - sh_type = shdr64->sh_type; - sh_align = shdr64->sh_addralign; - sh_entsize = shdr64->sh_entsize; - sh_offset = shdr64->sh_offset; - sh_size = shdr64->sh_size; - } - - assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); - - elftype = _libelf_xlate_shtype(sh_type); - if (elftype > ELF_T_LAST) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - if (sh_align == 0) - sh_align = _libelf_falign(elftype, ec); - - /* - * Check the section's data buffers for sanity and compute the - * section's alignment. - * Compute the section's size and alignment using the data - * descriptors associated with the section. - */ - if (STAILQ_EMPTY(&s->s_data)) { - /* - * The section's content (if any) has not been read in - * yet. If section is not dirty marked dirty, we can - * reuse the values in the 'sh_size' and 'sh_offset' - * fields of the section header. - */ - if ((s->s_flags & ELF_F_DIRTY) == 0) { - /* - * If the library is doing the layout, then we - * compute the new start offset for the - * section based on the current offset and the - * section's alignment needs. - * - * If the application is doing the layout, we - * can use the value in the 'sh_offset' field - * in the section header directly. - */ - if (e->e_flags & ELF_F_LAYOUT) - goto updatedescriptor; - else - goto computeoffset; - } - - /* - * Otherwise, we need to bring in the section's data - * from the underlying ELF object. - */ - if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) - return (0); - } - - /* - * Loop through the section's data descriptors. - */ - scn_size = 0L; - scn_alignment = 0L; - STAILQ_FOREACH(d, &s->s_data, d_next) { - if (d->d_type > ELF_T_LAST) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - if (d->d_version != e->e_version) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - if ((d_align = d->d_align) == 0 || (d_align & (d_align - 1))) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * The buffer's size should be a multiple of the - * memory size of the underlying type. - */ - msz = _libelf_msize(d->d_type, ec, e->e_version); - if (d->d_size % msz) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * Compute the section's size. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if ((uint64_t) d->d_off + d->d_size > scn_size) - scn_size = d->d_off + d->d_size; - } else { - scn_size = roundup2(scn_size, d->d_align); - d->d_off = scn_size; - fsz = _libelf_fsize(d->d_type, ec, d->d_version, - d->d_size / msz); - scn_size += fsz; - } - - /* - * The section's alignment is the maximum alignment - * needed for its data buffers. - */ - if (d_align > scn_alignment) - scn_alignment = d_align; - } - - - /* - * If the application is requesting full control over the layout - * of the section, check its values for sanity. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if (scn_alignment > sh_align || sh_offset % sh_align || - sh_size < scn_size) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - goto updatedescriptor; - } - - /* - * Otherwise compute the values in the section header. - * - * The section alignment is the maximum alignment for any of - * its contained data descriptors. - */ - if (scn_alignment > sh_align) - sh_align = scn_alignment; - - /* - * If the section entry size is zero, try and fill in an - * appropriate entry size. Per the elf(5) manual page - * sections without fixed-size entries should have their - * 'sh_entsize' field set to zero. - */ - if (sh_entsize == 0 && - (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, - (size_t) 1)) == 1) - sh_entsize = 0; - - sh_size = scn_size; - -computeoffset: - /* - * Compute the new offset for the section based on - * the section's alignment needs. - */ - sh_offset = roundup(rc, sh_align); - - /* - * Update the section header. - */ - if (ec == ELFCLASS32) { - shdr32->sh_addralign = (uint32_t) sh_align; - shdr32->sh_entsize = (uint32_t) sh_entsize; - shdr32->sh_offset = (uint32_t) sh_offset; - shdr32->sh_size = (uint32_t) sh_size; - } else { - shdr64->sh_addralign = sh_align; - shdr64->sh_entsize = sh_entsize; - shdr64->sh_offset = sh_offset; - shdr64->sh_size = sh_size; - } - -updatedescriptor: - /* - * Update the section descriptor. - */ - s->s_size = sh_size; - s->s_offset = sh_offset; - - return (1); -} - - -/* - * Insert a section in ascending order in the list - */ - -static int -_libelf_insert_section(Elf *e, Elf_Scn *s) -{ - Elf_Scn *t, *prevt; - uint64_t smax, smin, tmax, tmin; - - smin = s->s_offset; - smax = smin + s->s_size; - - prevt = NULL; - STAILQ_FOREACH(t, &e->e_u.e_elf.e_scn, s_next) { - tmin = t->s_offset; - tmax = tmin + t->s_size; - - if (tmax <= smin) { - /* - * 't' lies entirely before 's': ...| t |...| s |... - */ - prevt = t; - continue; - } else if (smax <= tmin) - /* - * 's' lies entirely before 't', and after 'prevt': - * ...| prevt |...| s |...| t |... - */ - break; - else { /* 's' and 't' overlap. */ - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - } - - if (prevt) - STAILQ_INSERT_AFTER(&e->e_u.e_elf.e_scn, prevt, s, s_next); - else - STAILQ_INSERT_HEAD(&e->e_u.e_elf.e_scn, s, s_next); - return (1); -} - -/* - * Recompute section layout. - */ - -static off_t -_libelf_resync_sections(Elf *e, off_t rc) -{ - int ec; - Elf_Scn *s; - size_t sh_type, shdr_start, shdr_end; - - ec = e->e_class; - - /* - * Make a pass through sections, computing the extent of each - * section. Order in increasing order of addresses. - */ - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - sh_type = s->s_shdr.s_shdr32.sh_type; - else - sh_type = s->s_shdr.s_shdr64.sh_type; - - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) - continue; - - if (_libelf_compute_section_extents(e, s, rc) == 0) - return ((off_t) -1); - - if (s->s_size == 0) - continue; - - if (s->s_offset + s->s_size < (size_t) rc) { - /* - * Try insert this section in the - * correct place in the list, - * detecting overlaps if any. - */ - STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, - s_next); - if (_libelf_insert_section(e, s) == 0) - return ((off_t) -1); - } else - rc = s->s_offset + s->s_size; - } - - /* - * If the application is controlling file layout, check for an - * overlap between this section's extents and the SHDR table. - */ - if (e->e_flags & ELF_F_LAYOUT) { - - if (e->e_class == ELFCLASS32) - shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr32->e_shoff; - else - shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr64->e_shoff; - - shdr_end = shdr_start + _libelf_fsize(ELF_T_SHDR, e->e_class, - e->e_version, e->e_u.e_elf.e_nscn); - - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { - if (s->s_offset >= shdr_end || - s->s_offset + s->s_size <= shdr_start) - continue; - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - } - - return (rc); -} - -static off_t -_libelf_resync_elf(Elf *e) -{ - int ec, eh_class, eh_type; - unsigned int eh_byteorder, eh_version; - size_t align, fsz; - size_t phnum, shnum; - off_t rc, phoff, shoff; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - rc = 0; - - ec = e->e_class; - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - /* - * Prepare the EHDR. - */ - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return ((off_t) -1); - - eh32 = ehdr; - eh64 = ehdr; - - if (ec == ELFCLASS32) { - eh_byteorder = eh32->e_ident[EI_DATA]; - eh_class = eh32->e_ident[EI_CLASS]; - phoff = (uint64_t) eh32->e_phoff; - shoff = (uint64_t) eh32->e_shoff; - eh_type = eh32->e_type; - eh_version = eh32->e_version; - } else { - eh_byteorder = eh64->e_ident[EI_DATA]; - eh_class = eh64->e_ident[EI_CLASS]; - phoff = eh64->e_phoff; - shoff = eh64->e_shoff; - eh_type = eh64->e_type; - eh_version = eh64->e_version; - } - - if (eh_version == EV_NONE) - eh_version = EV_CURRENT; - - if (eh_version != e->e_version) { /* always EV_CURRENT */ - LIBELF_SET_ERROR(VERSION, 0); - return ((off_t) -1); - } - - if (eh_class != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return ((off_t) -1); - } - - if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { - LIBELF_SET_ERROR(HEADER, 0); - return ((off_t) -1); - } - - shnum = e->e_u.e_elf.e_nscn; - phnum = e->e_u.e_elf.e_nphdr; - - e->e_byteorder = eh_byteorder; - -#define INITIALIZE_EHDR(E,EC,V) do { \ - (E)->e_ident[EI_MAG0] = ELFMAG0; \ - (E)->e_ident[EI_MAG1] = ELFMAG1; \ - (E)->e_ident[EI_MAG2] = ELFMAG2; \ - (E)->e_ident[EI_MAG3] = ELFMAG3; \ - (E)->e_ident[EI_CLASS] = (EC); \ - (E)->e_ident[EI_VERSION] = (V); \ - (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ - (size_t) 1); \ - (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ - ELF_T_PHDR, (EC), (V), (size_t) 1); \ - (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ - (size_t) 1); \ - } while (0) - - if (ec == ELFCLASS32) - INITIALIZE_EHDR(eh32, ec, eh_version); - else - INITIALIZE_EHDR(eh64, ec, eh_version); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); - - /* - * Compute the layout the program header table, if one is - * present. The program header table needs to be aligned to a - * `natural' boundary. - */ - if (phnum) { - fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); - align = _libelf_falign(ELF_T_PHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - /* - * Check offsets for sanity. - */ - if (rc > phoff) { - LIBELF_SET_ERROR(HEADER, 0); - return ((off_t) -1); - } - - if (phoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - - } else - phoff = roundup(rc, align); - - rc = phoff + fsz; - } else - phoff = 0; - - /* - * Compute the layout of the sections associated with the - * file. - */ - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_scn(e, ehdr) == 0) - return ((off_t) -1); - - if ((rc = _libelf_resync_sections(e, rc)) < 0) - return ((off_t) -1); - - /* - * Compute the space taken up by the section header table, if - * one is needed. If ELF_F_LAYOUT is asserted, the - * application may have placed the section header table in - * between existing sections, so the net size of the file need - * not increase due to the presence of the section header - * table. - */ - if (shnum) { - fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, (size_t) 1); - align = _libelf_falign(ELF_T_SHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - if (shoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - } else - shoff = roundup(rc, align); - - if (shoff + fsz * shnum > (size_t) rc) - rc = shoff + fsz * shnum; - } else - shoff = 0; - - /* - * Set the fields of the Executable Header that could potentially use - * extended numbering. - */ - _libelf_setphnum(e, ehdr, ec, phnum); - _libelf_setshnum(e, ehdr, ec, shnum); - - /* - * Update the `e_phoff' and `e_shoff' fields if the library is - * doing the layout. - */ - if ((e->e_flags & ELF_F_LAYOUT) == 0) { - if (ec == ELFCLASS32) { - eh32->e_phoff = (uint32_t) phoff; - eh32->e_shoff = (uint32_t) shoff; - } else { - eh64->e_phoff = (uint64_t) phoff; - eh64->e_shoff = (uint64_t) shoff; - } - } - - return (rc); -} - -/* - * Write out the contents of a section. - */ - -static off_t -_libelf_write_scn(Elf *e, char *nf, Elf_Scn *s, off_t rc) -{ - int ec; - size_t fsz, msz, nobjects; - uint32_t sh_type; - uint64_t sh_off, sh_size; - int elftype; - Elf_Data *d, dst; - - if ((ec = e->e_class) == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_size = s->s_shdr.s_shdr64.sh_size; - } - - /* - * Ignore sections that do not allocate space in the file. - */ - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) - return (rc); - - elftype = _libelf_xlate_shtype(sh_type); - assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); - - sh_off = s->s_offset; - assert(sh_off % _libelf_falign(elftype, ec) == 0); - - /* - * If the section has a `rawdata' descriptor, and the section - * contents have not been modified, use its contents directly. - * The `s_rawoff' member contains the offset into the original - * file, while `s_offset' contains its new location in the - * destination. - */ - - if (STAILQ_EMPTY(&s->s_data)) { - - if ((d = elf_rawdata(s, NULL)) == NULL) - return ((off_t) -1); - - STAILQ_FOREACH(d, &s->s_rawdata, d_next) { - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + - d->d_off - rc); - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_type == ELF_T_BYTE); - assert(d->d_version == e->e_version); - - (void) memcpy(nf + rc, - e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); - - rc += d->d_size; - } - - return (rc); - } - - /* - * Iterate over the set of data descriptors for this section. - * The prior call to _libelf_resync_elf() would have setup the - * descriptors for this step. - */ - - dst.d_version = e->e_version; - - STAILQ_FOREACH(d, &s->s_data, d_next) { - - msz = _libelf_msize(d->d_type, ec, e->e_version); - - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); - - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_version == e->e_version); - assert(d->d_size % msz == 0); - - nobjects = d->d_size / msz; - - fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); - - dst.d_buf = nf + rc; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - rc += fsz; - } - - return ((off_t) rc); -} - -/* - * Write out the file image. - * - * The original file could have been mapped in with an ELF_C_RDWR - * command and the application could have added new content or - * re-arranged its sections before calling elf_update(). Consequently - * its not safe to work `in place' on the original file. So we - * malloc() the required space for the updated ELF object and build - * the object there and write it out to the underlying file at the - * end. Note that the application may have opened the underlying file - * in ELF_C_RDWR and only retrieved/modified a few sections. We take - * care to avoid translating file sections unnecessarily. - * - * Gaps in the coverage of the file by the file's sections will be - * filled with the fill character set by elf_fill(3). - */ - -static off_t -_libelf_write_elf(Elf *e, off_t newsize) -{ - int ec; - off_t maxrc, rc; - size_t fsz, msz, phnum, shnum; - uint64_t phoff, shoff; - void *ehdr; - char *newfile; - Elf_Data dst, src; - Elf_Scn *scn, *tscn; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - assert(e->e_kind == ELF_K_ELF); - assert(e->e_cmd != ELF_C_READ); - assert(e->e_fd >= 0); - - if ((newfile = malloc((size_t) newsize)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return ((off_t) -1); - } - - ec = e->e_class; - - ehdr = _libelf_ehdr(e, ec, 0); - assert(ehdr != NULL); - - phnum = e->e_u.e_elf.e_nphdr; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - - phoff = (uint64_t) eh32->e_phoff; - shnum = eh32->e_shnum; - shoff = (uint64_t) eh32->e_shoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - - phoff = eh64->e_phoff; - shnum = eh64->e_shnum; - shoff = eh64->e_shoff; - } - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - src.d_buf = ehdr; - src.d_size = msz; - src.d_type = ELF_T_EHDR; - src.d_version = dst.d_version = e->e_version; - - rc = 0; - - dst.d_buf = newfile + rc; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - goto error; - - rc += fsz; - - /* - * Write the program header table if present. - */ - - if (phnum != 0 && phoff != 0) { - assert((unsigned) rc <= phoff); - - fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); - - assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); - assert(fsz > 0); - - src.d_buf = _libelf_getphdr(e, ec); - src.d_version = dst.d_version = e->e_version; - src.d_type = ELF_T_PHDR; - src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, - e->e_version); - - dst.d_size = fsz; - - if ((uint64_t) rc < phoff) - (void) memset(newfile + rc, - LIBELF_PRIVATE(fillchar), phoff - rc); - - dst.d_buf = newfile + rc; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - goto error; - - rc = phoff + fsz; - } - - /* - * Write out individual sections. - */ - - STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) - if ((rc = _libelf_write_scn(e, newfile, scn, rc)) < 0) - goto error; - - /* - * Write out the section header table, if required. Note that - * if flag ELF_F_LAYOUT has been set the section header table - * could reside in between byte ranges mapped by section - * descriptors. - */ - if (shnum != 0 && shoff != 0) { - if ((uint64_t) rc < shoff) - (void) memset(newfile + rc, - LIBELF_PRIVATE(fillchar), shoff - rc); - - maxrc = rc; - rc = shoff; - - assert(rc % _libelf_falign(ELF_T_SHDR, ec) == 0); - - src.d_type = ELF_T_SHDR; - src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); - src.d_version = dst.d_version = e->e_version; - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - - STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - src.d_buf = &scn->s_shdr.s_shdr32; - else - src.d_buf = &scn->s_shdr.s_shdr64; - - dst.d_size = fsz; - dst.d_buf = newfile + rc + scn->s_ndx * fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, - ELF_TOFILE) != &dst) - goto error; - } - - rc += e->e_u.e_elf.e_nscn * fsz; - if (maxrc > rc) - rc = maxrc; - } - - assert(rc == newsize); - - /* - * Write out the constructed contents and remap the file in - * read-only. - */ - - if (e->e_rawfile && munmap(e->e_rawfile, e->e_rawsize) < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - if (write(e->e_fd, newfile, (size_t) newsize) != newsize || - lseek(e->e_fd, (off_t) 0, SEEK_SET) < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - if (e->e_cmd != ELF_C_WRITE) { - if ((e->e_rawfile = mmap(NULL, (size_t) newsize, PROT_READ, - MAP_PRIVATE, e->e_fd, (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - e->e_rawsize = newsize; - } - - /* - * Reset flags, remove existing section descriptors and - * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() - * and elf_getscn() will function correctly. - */ - - e->e_flags &= ~ELF_F_DIRTY; - - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) - _libelf_release_scn(scn); - - if (ec == ELFCLASS32) { - free(e->e_u.e_elf.e_ehdr.e_ehdr32); - if (e->e_u.e_elf.e_phdr.e_phdr32) - free(e->e_u.e_elf.e_phdr.e_phdr32); - - e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; - e->e_u.e_elf.e_phdr.e_phdr32 = NULL; - } else { - free(e->e_u.e_elf.e_ehdr.e_ehdr64); - if (e->e_u.e_elf.e_phdr.e_phdr64) - free(e->e_u.e_elf.e_phdr.e_phdr64); - - e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; - e->e_u.e_elf.e_phdr.e_phdr64 = NULL; - } - - free(newfile); - - return (rc); - - error: - free(newfile); - - return ((off_t) -1); -} - -off_t -elf_update(Elf *e, Elf_Cmd c) -{ - int ec; - off_t rc; - - rc = (off_t) -1; - - if (e == NULL || e->e_kind != ELF_K_ELF || - (c != ELF_C_NULL && c != ELF_C_WRITE)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (rc); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (rc); - } - - if (e->e_version == EV_NONE) - e->e_version = EV_CURRENT; - - if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (rc); - } - - if ((rc = _libelf_resync_elf(e)) < 0) - return (rc); - - if (c == ELF_C_NULL) - return (rc); - - if (e->e_cmd == ELF_C_READ) { - /* - * This descriptor was opened in read-only mode or by - * elf_memory(). - */ - if (e->e_fd) - LIBELF_SET_ERROR(MODE, 0); - else - LIBELF_SET_ERROR(ARGUMENT, 0); - return ((off_t) -1); - } - - if (e->e_fd < 0) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return ((off_t) -1); - } - - return (_libelf_write_elf(e, rc)); -} diff --git a/lib/libelf/elf_version.3 b/lib/libelf/elf_version.3 deleted file mode 100644 index e918710..0000000 --- a/lib/libelf/elf_version.3 +++ /dev/null @@ -1,95 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd June 1, 2006 -.Dt ELF_VERSION 3 -.Os -.Sh NAME -.Nm elf_version -.Nd retrieve or set ELF library operating version -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft unsigned int -.Fn elf_version "unsigned int version" -.Sh DESCRIPTION -The -.Fn elf_version -function is used to query the current operating version of the ELF -library, and to inform the ELF library about the application's desired -operating version. -.Pp -If the argument -.Ar version -is -.Dv EV_NONE , -the -.Fn elf_version -function returns the currently configured operating version for the -ELF library. -.Pp -If the argument -.Ar version -is not -.Dv EV_NONE , -and if argument -.Ar version -is supported by the ELF library, function -.Fn elf_version -sets the library's operating version to -.Ar version , -and returns the previous value of the operating version. -If argument -.Ar version -cannot be supported, then the -.Fn elf_version -function returns -.Dv EV_NONE . -.Sh RETURN VALUES -The -.Fn elf_version -function returns the currently configured ELF library version, or -.Dv EV_NONE -if an unsupported version is requested. -.Sh EXAMPLES -An application program would inform the ELF library about its desired -operating version and check for an error using the following code -snippet: -.Bd -literal -offset indent -if (elf_version(EV_CURRENT) == EV_NONE) - err(EX_SOFTWARE, "ELF library too old"); -.Ed -.Sh ERRORS -Function -.Fn elf_version -may fail with the following error: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er "ELF_E_VERSION" -An unsupported library version number was requested. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/lib/libelf/elf_version.c b/lib/libelf/elf_version.c deleted file mode 100644 index 7f66d42..0000000 --- a/lib/libelf/elf_version.c +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" - -unsigned int -elf_version(unsigned int v) -{ - unsigned int old; - - if ((old = LIBELF_PRIVATE(version)) == EV_NONE) - old = EV_CURRENT; - - if (v == EV_NONE) - return old; - if (v > EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return EV_NONE; - } - - LIBELF_PRIVATE(version) = v; - return (old); -} diff --git a/lib/libelf/gelf.3 b/lib/libelf/gelf.3 deleted file mode 100644 index 1c2f010..0000000 --- a/lib/libelf/gelf.3 +++ /dev/null @@ -1,201 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd September 1, 2006 -.Dt GELF 3 -.Os -.Sh NAME -.Nm GElf -.Nd class-independent API for ELF manipulation -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Sh DESCRIPTION -This manual page describes a class independent API for manipulating -ELF objects. -This API allows an application to operate on ELF descriptors without -needing to the know the ELF class of the descriptor. -.Pp -The GElf API may be used alongside the ELF API without restriction. -.Ss GElf Data Structures -The GElf API defines the following class-independent data structures: -.Bl -tag -width GElf_Sxword -.It Vt GElf_Addr -A representation of ELF addresses. -.It Vt GElf_Dyn -A class-independent representation of ELF -.Sy .dynamic -section entries. -.It Vt GElf_Ehdr -A class-independent representation of an ELF Executable Header. -.It Vt GElf_Half -An unsigned 16 bit quantity. -.It Vt GElf_Off -A class-independent representation of a ELF offset. -.It Vt GElf_Phdr -A class-independent representation of an ELF Program Header Table -entry. -.It Vt GElf_Rel -A class-independent representation of an ELF relocation entry. -.It Vt GElf_Rela -A class-independent representation of an ELF relocation entry with -addend. -.It Vt GElf_Shdr -A class-independent representation of an ELF Section Header Table -entry. -.It Vt GElf_Sword -A signed 32 bit quantity. -.It Vt GElf_Sxword -A signed 64 bit quantity. -.It Vt GElf_Sym -A class-independent representation of an ELF symbol table entry. -.It Vt GElf_Word -An unsigned 32 bit quantity. -.It Vt GElf_Xword -An unsigned 64 bit quantity. -.El -.Pp -These data structures are sized to be compatible with the -corresponding 64 bit ELF structures, and have the same internal -structure as their 64 bit class-dependent counterparts. -Class-dependent ELF structures are described in -.Xr elf 5 . -.Ss GElf Programming Model -GElf functions always return a -.Em copy -of the underlying (class-dependent) ELF data structure. -The programming model with GElf is as follows: -.Bl -enum -.It -An application will retrieve data from an ELF descriptor using a -.Fn gelf_get_* -function. -This will copy out data into a private -.Vt GElf_* -data structure. -.It -The application will work with its private copy of the GElf -structure. -.It -Once done, the application copies the new values back to the -underlying ELF data structure using the -.Fn gelf_update_* -functions. -.It -The application will then use the -.Fn elf_flag* -APIs to indicate to the ELF library that an ELF data structure is dirty. -.El -.Pp -When updating an underlying 32 bit ELF data structure, the GElf -routines will signal an error if a GElf value is out of range -for the underlying ELF data type. -.Ss Namespace use -The GElf interface uses the following symbols: -.Bl -tag -width 8n -.It GElf_* -Class-independent data types. -.It gelf_* -For functions defined in the API set. -.El -.Ss GElf Programming APIs -This section provides an overview of the GElf programming APIs. -Further information is provided in the manual page of each function -listed here. -.Bl -tag -width 2n -.It "Allocating ELF Data Structures" -.Bl -tag -width 19n -compact -.It Fn gelf_newehdr -Allocate a new ELF Executable Header. -.It Fn gelf_newphdr -Allocate a new ELF Program Header Table. -.El -.It "Data Translation" -.Bl -tag -width 19n -compact -.It Fn gelf_xlatetof -Translate the native representation of an ELF data structure to its -file representation. -.It Fn gelf_xlatetom -Translate from the file representation of an ELF data structure to a -native representation. -.El -.It "Retrieving ELF Data" -.Bl -tag -width 19n -compact -.It Fn gelf_getdyn -Retrieve an ELF -.Sy .dynamic -table entry. -.It Fn gelf_getehdr -Retrieve an ELF Executable Header from the underlying ELF descriptor. -.It Fn gelf_getphdr -Retrieve an ELF Program Header Table entry from the underlying ELF descriptor. -.It Fn gelf_getrel -Retrieve an ELF relocation entry. -.It Fn gelf_getrela -Retrieve an ELF relocation entry with addend. -.It Fn gelf_getshdr -Retrieve an ELF Section Header Table entry from the underlying ELF descriptor. -.It Fn gelf_getsym -Retrieve an ELF symbol table entry. -.El -.It Queries -.Bl -tag -width 19n -compact -.It Fn gelf_checksum -Retrieves the ELF checksum for an ELF descriptor. -.It Fn gelf_fsize -Retrieves the size of the file representation of an ELF type. -.It Fn gelf_getclass -Retrieves the ELF class of an ELF descriptor. -.El -.It "Updating ELF Data" -.Bl -tag -width 19n -compact -.It Fn gelf_update_dyn -Copy back an ELF -.Sy .dynamic -Table entry. -.It Fn gelf_update_phdr -Copy back an ELF Program Header Table entry. -.It Fn gelf_update_rel -Copy back an ELF relocation entry. -.It Fn gelf_update_rela -Copy back an ELF relocation with addend entry. -.It Fn gelf_update_shdr -Copy back an ELF Section Header Table entry. -.It Fn gelf_update_sym -Copy back an ELF symbol table entry. -.El -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf 5 -.Sh HISTORY -The GELF(3) API first appeared in System V Release 4. -This implementation of the API first appeared in -.Fx 7.0 . -.Sh AUTHORS -The GElf API was implemented by -.An "Joseph Koshy" -.Aq jkoshy@FreeBSD.org . diff --git a/lib/libelf/gelf.h b/lib/libelf/gelf.h deleted file mode 100644 index ad852d5..0000000 --- a/lib/libelf/gelf.h +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _GELF_H_ -#define _GELF_H_ - -#include <sys/cdefs.h> - -#include <libelf.h> -#include <osreldate.h> - -typedef Elf64_Addr GElf_Addr; /* Addresses */ -typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ -typedef Elf64_Off GElf_Off; /* Offsets */ -typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ -typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ -typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ -typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ - -typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ -typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ -typedef Elf64_Phdr GElf_Phdr; /* Program header */ -typedef Elf64_Shdr GElf_Shdr; /* Section header */ -typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ -typedef Elf64_Rel GElf_Rel; /* Relocation entries */ -typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ - -#if __FreeBSD_version >= 700025 -typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ -typedef Elf64_Move GElf_Move; /* Move entries */ -typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ -#endif - -#define GELF_M_INFO ELF64_M_INFO -#define GELF_M_SIZE ELF64_M_SIZE -#define GELF_M_SYM ELF64_M_SYM - -#define GELF_R_INFO ELF64_R_INFO -#define GELF_R_SYM ELF64_R_SYM -#define GELF_R_TYPE ELF64_R_TYPE -#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA -#define GELF_R_TYPE_ID ELF64_R_TYPE_ID -#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO - -#define GELF_ST_BIND ELF64_ST_BIND -#define GELF_ST_INFO ELF64_ST_INFO -#define GELF_ST_TYPE ELF64_ST_TYPE -#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY - -__BEGIN_DECLS -long gelf_checksum(Elf *_elf); -size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, - unsigned int _version); -int gelf_getclass(Elf *_elf); -GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); -GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); -GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); -GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); -GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); -GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); -GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); -GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, - int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); -void * gelf_newehdr(Elf *_elf, int _class); -void * gelf_newphdr(Elf *_elf, size_t _phnum); -int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); -int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); -int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); -int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); -int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); -int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); -int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); -int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, - int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); -Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); -Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); - -#if __FreeBSD_version >= 700025 -GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); -GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); -GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); -int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); -int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); -int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); -#endif -__END_DECLS - -#endif /* _GELF_H_ */ diff --git a/lib/libelf/gelf_cap.c b/lib/libelf/gelf_cap.c deleted file mode 100644 index 76338a8..0000000 --- a/lib/libelf/gelf_cap.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -#if __FreeBSD_version >= 700025 - -GElf_Cap * -gelf_getcap(Elf_Data *d, int ndx, GElf_Cap *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - cap32 = (Elf32_Cap *) d->d_buf + ndx; - - dst->c_tag = cap32->c_tag; - dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; - - } else { - - cap64 = (Elf64_Cap *) d->d_buf + ndx; - - *dst = *cap64; - } - - return (dst); -} - -int -gelf_update_cap(Elf_Data *d, int ndx, GElf_Cap *gc) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gc == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - cap32 = (Elf32_Cap *) d->d_buf + ndx; - - LIBELF_COPY_U32(cap32, gc, c_tag); - LIBELF_COPY_U32(cap32, gc, c_un.c_val); - } else { - cap64 = (Elf64_Cap *) d->d_buf + ndx; - - *cap64 = *gc; - } - - return (1); -} - -#endif /* __FreeBSD_version >= 700025 */ diff --git a/lib/libelf/gelf_checksum.3 b/lib/libelf/gelf_checksum.3 deleted file mode 100644 index 99870f0..0000000 --- a/lib/libelf/gelf_checksum.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_CHECKSUM 3 -.Os -.Sh NAME -.Nm elf32_checksum , -.Nm elf64_checksum , -.Nm gelf_checksum -.Nd return the checksum of an ELF object -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft long -.Fn elf32_checksum "Elf *elf" -.Ft long -.Fn elf64_checksum "Elf *elf" -.In gelf.h -.Ft long -.Fn gelf_checksum "Elf *elf" -.Sh DESCRIPTION -These functions return a simple checksum of the ELF object described -by their argument -.Ar elf . -The checksum is computed in way that allows its value to remain -unchanged in presence of modifications to the ELF object by utilities -like -.Xr strip 1 . -.Pp -Function -.Fn elf32_checksum -returns a checksum for an ELF descriptor -.Ar elf -of class -.Dv ELFCLASS32 . -.Pp -Function -.Fn elf64_checksum -returns a checksum for an ELF descriptor -.Ar elf -of class -.Dv ELFCLASS64 . -.Pp -Function -.Fn gelf_checksum -provides a class-independent way retrieving the checksum -for ELF object -.Ar elf . -.Sh RETURN VALUES -These functions return the checksum of the ELF object, or zero in case -an error was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -The ELF descriptor -.Ar elf -was not opened for reading or updating. -.It Bq Er ELF_E_CLASS -For functions -.Fn elf32_checksum -and -.Fn elf64_checksum , -ELF descriptor -.Ar elf -did not match the class of the called function. -.It Bq Er ELF_E_HEADER -The ELF object specified by argument -.Ar elf -had a malformed executable header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during processing. -.It Bq Er ELF_E_SECTION -The ELF object specified by argument -.Ar elf -contained a section with a malformed section header. -.It Bq Er ELF_E_VERSION -The ELF object was of an unsupported version. -.El -.Sh SEE ALSO -.Xr strip 1 , -.Xr elf 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_checksum.c b/lib/libelf/gelf_checksum.c deleted file mode 100644 index 64eb6c3..0000000 --- a/lib/libelf/gelf_checksum.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> -#include <libelf.h> - -#include "_libelf.h" - -long -elf32_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS32)); -} - -long -elf64_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS64)); -} - -long -gelf_checksum(Elf *e) -{ - int ec; - if (e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - return (_libelf_checksum(e, ec)); -} diff --git a/lib/libelf/gelf_dyn.c b/lib/libelf/gelf_dyn.c deleted file mode 100644 index 329fe93..0000000 --- a/lib/libelf/gelf_dyn.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -GElf_Dyn * -gelf_getdyn(Elf_Data *d, int ndx, GElf_Dyn *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_buf + ndx; - - dst->d_tag = dyn32->d_tag; - dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; - - } else { - - dyn64 = (Elf64_Dyn *) d->d_buf + ndx; - - *dst = *dyn64; - } - - return (dst); -} - -int -gelf_update_dyn(Elf_Data *d, int ndx, GElf_Dyn *ds) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || ds == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_buf + ndx; - - LIBELF_COPY_S32(dyn32, ds, d_tag); - LIBELF_COPY_U32(dyn32, ds, d_un.d_val); - } else { - dyn64 = (Elf64_Dyn *) d->d_buf + ndx; - - *dyn64 = *ds; - } - - return (1); -} diff --git a/lib/libelf/gelf_ehdr.c b/lib/libelf/gelf_ehdr.c deleted file mode 100644 index f3e8c76..0000000 --- a/lib/libelf/gelf_ehdr.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> -#include <libelf.h> -#include <string.h> - -#include "_libelf.h" - -Elf32_Ehdr * -elf32_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 0)); -} - -Elf64_Ehdr * -elf64_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 0)); -} - -GElf_Ehdr * -gelf_getehdr(Elf *e, GElf_Ehdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) - return (NULL); - - (void) memcpy(d->e_ident, eh32->e_ident, sizeof(eh32->e_ident)); - d->e_type = eh32->e_type; - d->e_machine = eh32->e_machine; - d->e_version = eh32->e_version; - d->e_entry = eh32->e_entry; - d->e_phoff = eh32->e_phoff; - d->e_shoff = eh32->e_shoff; - d->e_flags = eh32->e_flags; - d->e_ehsize = eh32->e_ehsize; - d->e_phentsize = eh32->e_phentsize; - d->e_phnum = eh32->e_phnum; - d->e_shentsize = eh32->e_shentsize; - d->e_shnum = eh32->e_shnum; - d->e_shstrndx = eh32->e_shstrndx; - - return (d); - } - - assert(ec == ELFCLASS64); - - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) - return (NULL); - *d = *eh64; - - return (d); -} - -Elf32_Ehdr * -elf32_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 1)); -} - -Elf64_Ehdr * -elf64_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 1)); -} - -void * -gelf_newehdr(Elf *e, int ec) -{ - if (e != NULL && - (ec == ELFCLASS32 || ec == ELFCLASS64)) - return (_libelf_ehdr(e, ec, 1)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -int -gelf_update_ehdr(Elf *e, GElf_Ehdr *s) -{ - int ec; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - eh64 = (Elf64_Ehdr *) ehdr; - *eh64 = *s; - return (1); - } - - eh32 = (Elf32_Ehdr *) ehdr; - - (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); - - eh32->e_type = s->e_type; - eh32->e_machine = s->e_machine; - eh32->e_version = s->e_version; - LIBELF_COPY_U32(eh32, s, e_entry); - LIBELF_COPY_U32(eh32, s, e_phoff); - LIBELF_COPY_U32(eh32, s, e_shoff); - eh32->e_flags = s->e_flags; - eh32->e_ehsize = s->e_ehsize; - eh32->e_phentsize = s->e_phentsize; - eh32->e_phnum = s->e_phnum; - eh32->e_shentsize = s->e_shentsize; - eh32->e_shnum = s->e_shnum; - eh32->e_shstrndx = s->e_shstrndx; - - return (1); -} diff --git a/lib/libelf/gelf_fsize.3 b/lib/libelf/gelf_fsize.3 deleted file mode 100644 index 2f7036b..0000000 --- a/lib/libelf/gelf_fsize.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd February 5, 2008 -.Dt GELF_FSIZE 3 -.Os -.Sh NAME -.Nm gelf_fsize , -.Nm elf32_fsize , -.Nm elf64_fsize -.Nd return the size of a file type -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft size_t -.Fn elf32_fsize "Elf_Type type" "size_t count" "unsigned int version" -.Ft size_t -.Fn elf64_fsize "Elf_Type type" "size_t count" "unsigned int version" -.In gelf.h -.Ft size_t -.Fn gelf_fsize "Elf *elf" "Elf_Type type" "size_t count" "unsigned int version" -.Sh DESCRIPTION -These functions return the size in bytes of the file representation of -.Ar count -numbers of objects of ELF type -.Ar type . -For ELF types that are of variable length, these functions return a -size of one byte. -.Pp -Functions -.Fn elf32_fsize -and -.Fn elf64_fsize -return sizes for files of class -.Dv ELFCLASS32 -and -.Dv ELFCLASS64 -respectively. -Function -.Fn gelf_fsize -returns the size for the class of ELF descriptor -.Ar elf . -.Sh RETURN VALUES -These functions return a non-zero value in case of success, or zero in -case of an error. -.Sh ERRORS -These functions may fail with: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL in a call to -.Fn gelf_fsize . -.It Bq Er ELF_E_ARGUMENT -ELF descriptor -.Ar elf -had an unknown ELF class. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar type -contained an illegal value. -.It Bq Er ELF_E_UNIMPL -Support for ELF type -.Ar type -has not been implemented. -.It Bq Er ELF_E_VERSION -Argument -.Ar version -is not a supported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_fsize.c b/lib/libelf/gelf_fsize.c deleted file mode 100644 index 0137c11..0000000 --- a/lib/libelf/gelf_fsize.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> -#include <libelf.h> - -#include "_libelf.h" - -size_t -elf32_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS32, v, c)); -} - -size_t -elf64_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS64, v, c)); -} - -size_t -gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) - return (_libelf_fsize(t, e->e_class, v, c)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); -} diff --git a/lib/libelf/gelf_getcap.3 b/lib/libelf/gelf_getcap.3 deleted file mode 100644 index e63a263..0000000 --- a/lib/libelf/gelf_getcap.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETCAP 3 -.Os -.Sh NAME -.Nm gelf_getcap , -.Nm gelf_update_cap -.Nd read and update ELF capability information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Cap *" -.Fn gelf_getcap "Elf_Data *data" "int ndx" "GElf_Cap *cap" -.Ft int -.Fn gelf_update_cap "Elf_Data *data" "int ndx" "GElf_Cap *cap" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Cap -or -.Vt Elf64_Cap -information. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_cap . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Cap -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getcap -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar cap -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_cap -converts the class-independent entry pointed to -by argument -.Ar cap -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_cap -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getcap -returns the value of argument -.Ar cap -if successful, or NULL in case of an error. -Function -.Fn gelf_update_cap -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar cap -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_SUNW_cap . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getclass.3 b/lib/libelf/gelf_getclass.3 deleted file mode 100644 index 7f7bc30..0000000 --- a/lib/libelf/gelf_getclass.3 +++ /dev/null @@ -1,61 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd July 3, 2006 -.Dt GELF_GETCLASS 3 -.Os -.Sh NAME -.Nm gelf_getclass -.Nd retrieve the class of an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft int -.Fn gelf_getclass "Elf *elf" -.Sh DESCRIPTION -Function -.Fn gelf_getclass -returns the ELF class of the descriptor supplied in argument -.Ar elf . -.Sh RETURN VALUES -Function -.Fn gelf_getclass -will return one of -.Dv ELFCLASS32 -or -.Dv ELFCLASS64 -if the argument -.Ar elf -is a descriptor for an ELF file. -The value -.Dv ELFCLASSNONE -is returned if argument -.Ar elf -was null, or if it was not a descriptor for an ELF file. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_kind 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getdyn.3 b/lib/libelf/gelf_getdyn.3 deleted file mode 100644 index a755d63..0000000 --- a/lib/libelf/gelf_getdyn.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETDYN 3 -.Os -.Sh NAME -.Nm gelf_getdyn , -.Nm gelf_update_dyn -.Nd read and update ELF dynamic entries -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Dyn *" -.Fn gelf_getdyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" -.Ft int -.Fn gelf_update_dyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Dyn -or -.Vt Elf64_Dyn -information in the -.Sy dynamic -table of an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_DYNAMIC . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Dyn -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getdyn -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar dyn -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_dyn -converts the class-independent entry pointed to -by argument -.Ar dyn -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_dyn -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getdyn -returns the value of argument -.Ar dyn -if successful, or NULL in case of an error. -Function -.Fn gelf_update_dyn -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar dyn -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_DYNAMIC . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getehdr.3 b/lib/libelf/gelf_getehdr.3 deleted file mode 100644 index 8e71c2d..0000000 --- a/lib/libelf/gelf_getehdr.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd December 16, 2006 -.Dt GELF_GETEHDR 3 -.Os -.Sh NAME -.Nm elf32_getehdr , -.Nm elf64_getehdr , -.Nm gelf_getehdr -.Nd retrieve the object file header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Ehdr *" -.Fn elf32_getehdr "Elf *elf" -.Ft "Elf64_Ehdr *" -.Fn elf64_getehdr "Elf *elf" -.In gelf.h -.Ft "GElf_Ehdr *" -.Fn gelf_getehdr "Elf *elf" "GElf_Ehdr *dst" -.Sh DESCRIPTION -These functions retrieve the ELF object file -header from the ELF descriptor -.Ar elf -and return a translated header descriptor to their callers. -.Pp -Functions -.Fn elf32_getehdr -and -.Fn elf64_getehdr -return a pointer to the appropriate class-specific header descriptor -if it exists in the file referenced by descriptor -.Ar elf . -These functions return -.Dv NULL -if an ELF header was not found in file -.Ar elf . -.Pp -Function -.Fn gelf_getehdr -stores a translated copy of the header for ELF file -.Ar elf -into the descriptor pointed to by argument -.Ar dst . -It returns argument -.Ar dst -if successful or -.Dv NULL -in case of failure. -.Sh RETURN VALUES -These functions return a pointer to a translated header descriptor -if successful, or NULL on failure. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -The elf class of descriptor -.Ar elf -was not recognized. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar dst -was null. -.It Bq Er ELF_E_CLASS -The ELF class of descriptor -.Ar elf -did not match that of the API function being called. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -does not have an associated header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during execution. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_E_VERSION -The ELF descriptor -.Ar elf -had an unsupported ELF version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_newehdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf_flagehdr 3 , -.Xr elf_getident 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr elf 5 diff --git a/lib/libelf/gelf_getmove.3 b/lib/libelf/gelf_getmove.3 deleted file mode 100644 index abe398a..0000000 --- a/lib/libelf/gelf_getmove.3 +++ /dev/null @@ -1,120 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETMOVE 3 -.Os -.Sh NAME -.Nm gelf_getmove , -.Nm gelf_update_move -.Nd read and update Elf Move information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Move *" -.Fn gelf_getmove "Elf_Data *data" "int ndx" "GElf_Move *move" -.Ft int -.Fn gelf_update_move "Elf_Data *data" "int ndx" "GElf_Move *move" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Move -and -.Vt Elf64_Move -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_move . -Argument -.Ar ndx -is the index of the move record being retrieved or updated. -The class-independent -.Vt GElf_Move -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getmove -retrieves class-dependent move record at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar move -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_move -converts the class-independent move information pointed to -by argument -.Ar move -to class-dependent form, and writes it to the move record at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_move -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getmove -returns the value of argument -.Ar move -if successful, or NULL in case of an error. -Function -.Fn gelf_update_move -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar move -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of records in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing move information. -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getphdr.3 b/lib/libelf/gelf_getphdr.3 deleted file mode 100644 index 13c588f..0000000 --- a/lib/libelf/gelf_getphdr.3 +++ /dev/null @@ -1,141 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 21, 2007 -.Dt GELF_GETPHDR 3 -.Os -.Sh NAME -.Nm elf32_getphdr , -.Nm elf64_getphdr , -.Nm gelf_getphdr -.Nd retrieve an ELF program header table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Phdr *" -.Fn elf32_getphdr "Elf *elf" -.Ft "Elf64_Phdr *" -.Fn elf64_getphdr "Elf *elf" -.In gelf.h -.Ft "GElf_Phdr *" -.Fn gelf_getphdr "Elf *elf" "int index" "GElf_Phdr *dst" -.Sh DESCRIPTION -These functions retrieve and translate ELF program header information -from an ELF descriptor, if this information exists. -.Pp -Functions -.Fn elf32_getphdr -and -.Fn elf64_getphdr -return a pointer to an array of translated -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors respectively. -These descriptors are described in -.Xr elf 5 . -The number of entries in this array may be determined using the -.Xr elf_getphnum 3 -function. -.Pp -Function -.Fn gelf_getphdr -will retrieve the program header table entry at index -.Ar index -from ELF descriptor -.Ar elf . -The translated program header table entry will be written to the -address pointed to be argument -.Ar dst . -.Pp -Applications may inform the library of modifications to a program header table entry -by using the -.Xr elf_flagphdr 3 -API. -Applications using the -.Xr gelf 3 -interface need to use the -.Xr gelf_update_phdr 3 -API to copy modifications to a program header entry back to the underlying -ELF descriptor. -.Sh RETURN VALUES -The functions a valid pointer if successful, or NULL in case an error -was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar dst -was NULL. -.It Bq Er ELF_E_ARGUMENT -Index -.Ar index -was out of range. -.It Bq Er ELF_E_CLASS -The class of ELF descriptor -.Ar elf -did not match the expected class of the function being called. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -did not possess an executable header. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -had a corrupt executable header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_VERSION -ELF descriptor -.Ar elf -was of an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf_flagphdr 3 , -.Xr elf_getphnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr gelf_newphdr 3 , -.Xr gelf_update_phdr 3 , -.Xr elf 5 diff --git a/lib/libelf/gelf_getrel.3 b/lib/libelf/gelf_getrel.3 deleted file mode 100644 index 6e650a5..0000000 --- a/lib/libelf/gelf_getrel.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETREL 3 -.Os -.Sh NAME -.Nm gelf_getrel , -.Nm gelf_update_rel -.Nd read and update ELF relocation entries -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Rel *" -.Fn gelf_getrel "Elf_Data *data" "int ndx" "GElf_Rel *rel" -.Ft int -.Fn gelf_update_rel "Elf_Data *data" "int ndx" "GElf_Rel *rel" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Rel -or -.Vt Elf64_Rel -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_REL . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Rel -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getrel -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar rel -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_rel -converts the class-independent entry pointed to -by argument -.Ar rel -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_rel -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getrel -returns the value of argument -.Ar rel -if successful, or NULL in case of an error. -Function -.Fn gelf_update_rel -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar rel -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_REL . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getrela.3 b/lib/libelf/gelf_getrela.3 deleted file mode 100644 index dc7e579..0000000 --- a/lib/libelf/gelf_getrela.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETRELA 3 -.Os -.Sh NAME -.Nm gelf_getrela , -.Nm gelf_update_rela -.Nd read and update ELF relocation entries with addends -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Rela *" -.Fn gelf_getrela "Elf_Data *data" "int ndx" "GElf_Rela *rela" -.Ft int -.Fn gelf_update_rela "Elf_Data *data" "int ndx" "GElf_Rela *rela" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Rela -or -.Vt Elf64_Rela -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_RELA . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Rela -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getrela -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar rela -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_rela -converts the class-independent entry pointed to -by argument -.Ar rela -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_rela -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getrela -returns the value of argument -.Ar rela -if successful, or NULL in case of an error. -Function -.Fn gelf_update_rela -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar rela -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_RELA . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/lib/libelf/gelf_getshdr.3 b/lib/libelf/gelf_getshdr.3 deleted file mode 100644 index 851f51f..0000000 --- a/lib/libelf/gelf_getshdr.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 27, 2006 -.Dt GELF_GETSHDR 3 -.Os -.Sh NAME -.Nm elf32_getshdr , -.Nm elf64_getshdr , -.Nm gelf_getshdr -.Nd retrieve the class-dependent section header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Shdr *" -.Fn elf32_getshdr "Elf_Scn *scn" -.Ft "Elf64_Shdr *" -.Fn elf64_getshdr "Elf_Scn *scn" -.In gelf.h -.Ft "GElf_Shdr *" -.Fn gelf_getshdr "Elf_Scn *scn" "GElf_Shdr *shdr" -.Sh DESCRIPTION -These functions return a pointer to the ELF Section Header data -structure associated with section descriptor -.Ar scn . -.Pp -Function -.Fn elf32_getshdr -retrieves a pointer to an -.Vt Elf32_Shdr -structure. -Section descriptor -.Ar scn -must be associated with an ELF descriptor of class -.Dv ELFCLASS32 . -.Pp -Function -.Fn elf64_getshdr -retrieves a pointer to an -.Vt Elf64_Shdr -structure. -Section descriptor -.Ar scn -must be associated with an ELF descriptor of class -.Dv ELFCLASS64 . -.Pp -Function -.Fn gelf_getshdr -copies the values in the section header associated with argument -.Ar scn -to the structure pointed to be argument -.Ar dst . -The -.Vt GElf_Shdr -data structure is described in -.Xr gelf 3 . -.Sh RETURN VALUES -Functions -.Fn elf32_getshdr -and -.Fn elf64_getshdr -return a valid pointer to the appropriate section header on success -or NULL if an error was encountered. -.Pp -Function -.Fn gelf_getshdr -returns argument -.Ar dst -if successful, or NULL if an error was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar scn -or -.Ar shdr -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar scn -was not associated a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -The ELF class associated with the section descriptor -.Ar scn -did not match the class expected by the API. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_update_shdr 3 diff --git a/lib/libelf/gelf_getsym.3 b/lib/libelf/gelf_getsym.3 deleted file mode 100644 index 56a6783..0000000 --- a/lib/libelf/gelf_getsym.3 +++ /dev/null @@ -1,125 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETSYM 3 -.Os -.Sh NAME -.Nm gelf_getsym , -.Nm gelf_update_sym -.Nd read and update symbol information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Sym *" -.Fn gelf_getsym "Elf_Data *data" "int ndx" "GElf_Sym *sym" -.Ft int -.Fn gelf_update_sym "Elf_Data *data" "int ndx" "GElf_Sym *sym" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Sym -and -.Vt Elf64_Sym -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB , -.Dv SHT_DYNSYM -or -.Dv SHT_GNU_versym . -Argument -.Ar ndx -is the index of the symbol being retrieved or updated. -The class-independent -.Vt GElf_Sym -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsym -retrieves class-dependent symbol information at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar sym -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_sym -converts the class-independent symbol information pointed to -by argument -.Ar sym -to class-dependent form, and writes it to the symbol entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_sym -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getsym -returns the value of argument -.Ar sym -if successful, or NULL in case of an error. -Function -.Fn gelf_update_sym -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar sym -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of symbols in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing symbol information. -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsyminfo 3 , -.Xr gelf_update_syminfo 3 diff --git a/lib/libelf/gelf_getsyminfo.3 b/lib/libelf/gelf_getsyminfo.3 deleted file mode 100644 index 12da80f..0000000 --- a/lib/libelf/gelf_getsyminfo.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 29, 2006 -.Dt GELF_GETSYMINFO 3 -.Os -.Sh NAME -.Nm gelf_getsyminfo , -.Nm gelf_update_syminfo -.Nd read and update symbol information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Syminfo *" -.Fn gelf_getsyminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" -.Ft int -.Fn gelf_update_syminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Syminfo -and -.Vt Elf64_Syminfo -records in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_syminfo . -Argument -.Ar ndx -is the index of the record being retrieved or updated. -The class-independent -.Vt GElf_Syminfo -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsyminfo -retrieves class-dependent record at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar syminfo -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_syminfo -converts the class-independent record pointed to -by argument -.Ar syminfo -to class-dependent form, and writes it to the record at index -.Ar ndx -in the data buffer described by argument -.Ar data . -.Sh RETURN VALUES -Function -.Fn gelf_getsyminfo -returns the value of argument -.Ar syminfo -if successful, or NULL in case of an error. -Function -.Fn gelf_update_syminfo -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar syminfo -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of symbols in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing symbol information. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsym 3 , -.Xr gelf_update_sym 3 diff --git a/lib/libelf/gelf_getsymshndx.3 b/lib/libelf/gelf_getsymshndx.3 deleted file mode 100644 index d79c392..0000000 --- a/lib/libelf/gelf_getsymshndx.3 +++ /dev/null @@ -1,162 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd November 5, 2006 -.Dt GELF_GETSYMSHNDX 3 -.Os -.Sh NAME -.Nm gelf_getsymshndx , -.Nm gelf_update_symshndx -.Nd read and update symbol information using extended section indices -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Sym *" -.Fo gelf_getsymshndx -.Fa "Elf_Data *symdata" -.Fa "Elf_Data *xndxdata" -.Fa "int ndx" -.Fa "GElf_Sym *sym" -.Fa "Elf32_Word *xndxptr" -.Fc -.Ft int -.Fo gelf_update_symshndx -.Fa "Elf_Data *symdata" -.Fa "Elf_Data *xndxdata" -.Fa "int ndx" -.Fa "GElf_Sym *sym" -.Fa "Elf32_Word xndx" -.Fc -.Sh DESCRIPTION -These functions are analogous to -.Fn gelf_getsym -and -.Fn gelf_update_sym -respectively, but are capable of handling symbol tables using extended -section numbering. -.Pp -Argument -.Ar symdata -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB . -Argument -.Ar xndxdata -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB_SHNDX . -Argument -.Ar ndx -is the index of the symbol table entry being retrieved or updated. -Argument -.Ar sym -is a pointer to a class-independent -.Vt GElf_Sym -structure. -.Vt GElf_Sym -structures are described in detail in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsymshndx -retrieves symbol information at index -.Ar ndx -from the data descriptor specified by argument -.Ar symdata -and stores in class-independent form in argument -.Ar sym . -In addition it retrieves the extended section index for the -symbol from data buffer -.Ar xndxdata -and stores it into the location pointed to by argument -.Ar xndxptr . -.Pp -Function -.Fn gelf_update_symshndx -updates the underlying symbol table entry in data -descriptor -.Ar symdata -with the information in argument -.Ar sym . -In addition it sets the extended section index in -data buffer -.Ar xndxdata -to the value of argument -.Ar xndx . -.Sh RETURN VALUES -Function -.Fn gelf_getsymshndx -returns the value of argument -.Ar sym -if successful, or NULL in case of an error. -.Pp -Function -.Fn gelf_update_symshndx -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar symdata , -.Ar xndxdata , -.Ar xndxptr -or -.Ar sym -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero, or too large for either of descriptors -.Ar symdata -or -.Ar xndxdata . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar symdata -was not associated with a section of type -.Dv SHT_SYMTAB . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar xndxdata -was not associated with a section of type -.Dv SHT_SYMTAB_SHNDX . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar symdata -and -.Ar xndxdata -were associated with different ELF objects. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsym 3 , -.Xr gelf_update_sym 3 diff --git a/lib/libelf/gelf_move.c b/lib/libelf/gelf_move.c deleted file mode 100644 index d303b18..0000000 --- a/lib/libelf/gelf_move.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -#if __FreeBSD_version >= 700025 - -GElf_Move * -gelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Move *move32; - Elf64_Move *move64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - move32 = (Elf32_Move *) d->d_buf + ndx; - - dst->m_value = move32->m_value; - dst->m_info = (Elf64_Xword) move32->m_info; - dst->m_poffset = (Elf64_Xword) move32->m_poffset; - dst->m_repeat = move32->m_repeat; - dst->m_stride = move32->m_stride; - } else { - - move64 = (Elf64_Move *) d->d_buf + ndx; - - *dst = *move64; - } - - return (dst); -} - -int -gelf_update_move(Elf_Data *d, int ndx, GElf_Move *gm) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Move *move32; - Elf64_Move *move64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gm == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - move32 = (Elf32_Move *) d->d_buf + ndx; - - move32->m_value = gm->m_value; - LIBELF_COPY_U32(move32, gm, m_info); - LIBELF_COPY_U32(move32, gm, m_poffset); - move32->m_repeat = gm->m_repeat; - move32->m_stride = gm->m_stride; - - } else { - move64 = (Elf64_Move *) d->d_buf + ndx; - - *move64 = *gm; - } - - return (1); -} - -#endif /* __FreeBSD_version >= 700025 */ diff --git a/lib/libelf/gelf_newehdr.3 b/lib/libelf/gelf_newehdr.3 deleted file mode 100644 index 4dab647..0000000 --- a/lib/libelf/gelf_newehdr.3 +++ /dev/null @@ -1,186 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 22, 2007 -.Dt GELF_NEWEHDR 3 -.Os -.Sh NAME -.Nm elf32_newehdr , -.Nm elf64_newehdr , -.Nm gelf_newehdr -.Nd retrieve or allocate the object file header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Ehdr *" -.Fn elf32_newehdr "Elf *elf" -.Ft "Elf64_Ehdr *" -.Fn elf64_newehdr "Elf *elf" -.In gelf.h -.Ft "void *" -.Fn gelf_newehdr "Elf *elf" "int elfclass" -.Sh DESCRIPTION -These functions retrieve the ELF header from the ELF descriptor -.Ar elf , -allocating a new header if needed. -File data structures are translated to their in-memory representations -as described in -.Xr elf 3 . -.Pp -Function -.Fn elf32_newehdr -returns a pointer to a 32 bit -.Vt Elf32_Ehdr -structure. -Function -.Fn elf64_newehdr -returns a pointer to a 64 bit -.Vt Elf64_Ehdr -structure. -.Pp -When argument -.Ar elfclass -has value -.Dv ELFCLASS32 , -function -.Fn gelf_newehdr -returns the value returned by -.Fn elf32_newehdr "elf" . -When argument -.Ar elfclass -has value -.Dv ELFCLASS64 -it returns the value returned by -.Fn elf64_newehdr "elf" . -.Pp -If a fresh header structure is allocated, the members of the -structure are initialized as follows: -.Bl -tag -width indent -.It Va "e_ident[EI_MAG0..EI_MAG3]" -Identification bytes at offsets -.Dv EI_MAG0 , -.Dv EI_MAG1 , -.Dv EI_MAG2 -and -.Dv EI_MAG3 -are set to the ELF signature. -.It Va "e_ident[EI_CLASS]" -The identification byte at offset -.Dv EI_CLASS -is set to the ELF class associated with the function being called -or to argument -.Ar elfclass -for function -.Fn gelf_newehdr . -.It Va "e_ident[EI_DATA]" -The identification byte at offset -.Dv EI_DATA -is set to -.Dv ELFDATANONE . -.It Va "e_ident[EI_VERSION]" -The identification byte at offset -.Dv EI_VERSION -is set to the ELF library's operating version set by a prior call to -.Xr elf_version 3 . -.It Va e_machine -is set to -.Dv EM_NONE . -.It Va e_type -is set to -.Dv ELF_K_NONE . -.It Va e_version -is set to the ELF library's operating version set by a prior call to -.Xr elf_version 3 . -.El -.Pp -Other members of the header are set to zero. -The application is responsible for changing these values -as needed before calling -.Fn elf_update . -.Pp -If successful, these three functions set the -.Dv ELF_F_DIRTY -flag on ELF descriptor -.Ar elf . -.Sh RETURN VALUES -These functions return a pointer to a translated header descriptor -if successful, or NULL on failure. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elfclass -had an unsupported value. -.It Bq Er ELF_E_ARGUMENT -The class of the ELF descriptor -.Ar elf -did not match that of the requested operation. -.It Bq Er ELF_E_ARGUMENT -For function -.Fn gelf_newehdr , -the class of argument -.Ar elf -was not -.Dv ELFCLASSNONE -and did not match the argument -.Ar elfclass . -.It Bq Er ELF_E_CLASS -The ELF class of descriptor -.Ar elf -did not match that of the API function being called. -.It Bq Er ELF_E_HEADER -A malformed ELF header was detected. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during execution. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_E_VERSION -The ELF descriptor -.Ar elf -had an unsupported ELF version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_flagdata 3 , -.Xr elf_getident 3 , -.Xr elf_update 3 , -.Xr elf_version 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr elf 5 diff --git a/lib/libelf/gelf_newphdr.3 b/lib/libelf/gelf_newphdr.3 deleted file mode 100644 index bd13e5d..0000000 --- a/lib/libelf/gelf_newphdr.3 +++ /dev/null @@ -1,133 +0,0 @@ -.\" Copyright (c) 2006,2007 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd October 22, 2007 -.Dt GELF_NEWPHDR 3 -.Os -.Sh NAME -.Nm elf32_newphdr , -.Nm elf64_newphdr , -.Nm gelf_newphdr -.Nd allocate an ELF program header table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Phdr *" -.Fn elf32_newphdr "Elf *elf" "size_t count" -.Ft "Elf64_Phdr *" -.Fn elf64_newphdr "Elf *elf" "size_t count" -.In gelf.h -.Ft "void *" -.Fn gelf_newphdr "Elf *elf" "size_t count" -.Sh DESCRIPTION -These functions allocate an ELF Program Header table -for an ELF descriptor. -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors are described further in -.Xr elf 5 . -.Pp -Functions -.Fn elf32_newphdr -and -.Fn elf64_newphdr -allocate a table of -.Ar count -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors respectively, -discarding any existing program header table -already present in the ELF descriptor -.Ar elf . -A value of zero for argument -.Ar count -may be used to delete an existing program header table -from an ELF descriptor. -.Pp -Function -.Fn gelf_newphdr -will return a table of -.Vt Elf32_Phdr -or -.Vt Elf64_Phdr -with -.Ar count -elements depending on the ELF class of ELF descriptor -.Ar elf . -.Pp -The functions set the -.Dv ELF_F_DIRTY -flag on the program header table. -All members of the returned array of Phdr structures -will be initialized to zero. -.Pp -After a successful call to these functions, the pointer returned -by a prior call to -.Fn elf32_getphdr -or -.Fn elf64_getphdr -on the same descriptor -.Ar elf -will no longer be valid. -.Sh RETURN VALUES -The functions a valid pointer if successful, or NULL in case an error -was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -ELF descriptor -.Ar elf -was of an unrecognized class. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SEQUENCE -An executable header was not allocated for ELF descriptor -.Ar elf -before using these APIs. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getphdr 3 , -.Xr elf32_newehdr 3 , -.Xr elf64_getphdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf_flagphdr 3 , -.Xr elf_getphnum 3 , -.Xr gelf 3 , -.Xr gelf_getphdr 3 , -.Xr gelf_newehdr 3 , -.Xr elf 5 diff --git a/lib/libelf/gelf_phdr.c b/lib/libelf/gelf_phdr.c deleted file mode 100644 index 654b99d..0000000 --- a/lib/libelf/gelf_phdr.c +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <gelf.h> -#include <libelf.h> - -#include "_libelf.h" - -Elf32_Phdr * -elf32_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS32)); -} - -Elf64_Phdr * -elf64_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS64)); -} - -GElf_Phdr * -gelf_getphdr(Elf *e, int index, GElf_Phdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf32_Phdr *ep32; - Elf64_Phdr *ep64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - (e->e_kind != ELF_K_ELF) || index < 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || - ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) - return (NULL); - - if (index >= eh32->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep32 += index; - - d->p_type = ep32->p_type; - d->p_offset = ep32->p_offset; - d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; - d->p_paddr = (Elf64_Addr) ep32->p_paddr; - d->p_filesz = (Elf64_Xword) ep32->p_filesz; - d->p_memsz = (Elf64_Xword) ep32->p_memsz; - d->p_flags = ep32->p_flags; - d->p_align = (Elf64_Xword) ep32->p_align; - - } else { - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || - (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) - return (NULL); - - if (index >= eh64->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep64 += index; - - *d = *ep64; - } - - return (d); -} - -Elf32_Phdr * -elf32_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS32, count)); -} - -Elf64_Phdr * -elf64_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS64, count)); -} - -void * -gelf_newphdr(Elf *e, size_t count) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - return (_libelf_newphdr(e, e->e_class, count)); -} - -int -gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) -{ - int ec, phnum; - void *ehdr; - Elf32_Phdr *ph32; - Elf64_Phdr *ph64; - - if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - if (ec == ELFCLASS32) - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - else - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - - if (ndx < 0 || ndx > phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; - *ph64 = *s; - return (1); - } - - ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; - - ph32->p_type = s->p_type; - ph32->p_flags = s->p_flags; - LIBELF_COPY_U32(ph32, s, p_offset); - LIBELF_COPY_U32(ph32, s, p_vaddr); - LIBELF_COPY_U32(ph32, s, p_paddr); - LIBELF_COPY_U32(ph32, s, p_filesz); - LIBELF_COPY_U32(ph32, s, p_memsz); - LIBELF_COPY_U32(ph32, s, p_align); - - return (1); -} diff --git a/lib/libelf/gelf_rel.c b/lib/libelf/gelf_rel.c deleted file mode 100644 index e2a9f90..0000000 --- a/lib/libelf/gelf_rel.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -GElf_Rel * -gelf_getrel(Elf_Data *d, int ndx, GElf_Rel *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rel32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rel32->r_info), - ELF32_R_TYPE(rel32->r_info)); - - } else { - - rel64 = (Elf64_Rel *) d->d_buf + ndx; - - *dst = *rel64; - } - - return (dst); -} - -int -gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_buf + ndx; - - LIBELF_COPY_U32(rel32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - } else { - rel64 = (Elf64_Rel *) d->d_buf + ndx; - - *rel64 = *dr; - } - - return (1); -} diff --git a/lib/libelf/gelf_rela.c b/lib/libelf/gelf_rela.c deleted file mode 100644 index 572e2b7..0000000 --- a/lib/libelf/gelf_rela.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -GElf_Rela * -gelf_getrela(Elf_Data *d, int ndx, GElf_Rela *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rela32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rela32->r_info), - ELF32_R_TYPE(rela32->r_info)); - dst->r_addend = (Elf64_Sxword) rela32->r_addend; - - } else { - - rela64 = (Elf64_Rela *) d->d_buf + ndx; - - *dst = *rela64; - } - - return (dst); -} - -int -gelf_update_rela(Elf_Data *d, int ndx, GElf_Rela *dr) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_buf + ndx; - - LIBELF_COPY_U32(rela32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - - LIBELF_COPY_S32(rela32, dr, r_addend); - } else { - rela64 = (Elf64_Rela *) d->d_buf + ndx; - - *rela64 = *dr; - } - - return (1); -} diff --git a/lib/libelf/gelf_shdr.c b/lib/libelf/gelf_shdr.c deleted file mode 100644 index 3f8f562..0000000 --- a/lib/libelf/gelf_shdr.c +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> -#include <libelf.h> - -#include "_libelf.h" - -Elf32_Shdr * -elf32_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS32)); -} - -Elf64_Shdr * -elf64_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS64)); -} - -GElf_Shdr * -gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) -{ - int ec; - void *sh; - Elf32_Shdr *sh32; - Elf64_Shdr *sh64; - - if (d == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) - return (NULL); - - ec = s->s_elf->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) { - sh32 = (Elf32_Shdr *) sh; - - d->sh_name = sh32->sh_name; - d->sh_type = sh32->sh_type; - d->sh_flags = (Elf64_Xword) sh32->sh_flags; - d->sh_addr = (Elf64_Addr) sh32->sh_addr; - d->sh_offset = (Elf64_Off) sh32->sh_offset; - d->sh_size = (Elf64_Xword) sh32->sh_size; - d->sh_link = sh32->sh_link; - d->sh_info = sh32->sh_info; - d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; - d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; - } else { - sh64 = (Elf64_Shdr *) sh; - *d = *sh64; - } - - return (d); -} - -int -gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) -{ - int ec; - Elf *e; - Elf32_Shdr *sh32; - - - if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || - e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - scn->s_shdr.s_shdr64 = *s; - return (1); - } - - sh32 = &scn->s_shdr.s_shdr32; - - sh32->sh_name = s->sh_name; - sh32->sh_type = s->sh_type; - LIBELF_COPY_U32(sh32, s, sh_flags); - LIBELF_COPY_U32(sh32, s, sh_addr); - LIBELF_COPY_U32(sh32, s, sh_offset); - LIBELF_COPY_U32(sh32, s, sh_size); - sh32->sh_link = s->sh_link; - sh32->sh_info = s->sh_info; - LIBELF_COPY_U32(sh32, s, sh_addralign); - LIBELF_COPY_U32(sh32, s, sh_entsize); - - return (1); -} diff --git a/lib/libelf/gelf_sym.c b/lib/libelf/gelf_sym.c deleted file mode 100644 index ef969ef..0000000 --- a/lib/libelf/gelf_sym.c +++ /dev/null @@ -1,154 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -GElf_Sym * -gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - sym32 = (Elf32_Sym *) d->d_buf + ndx; - - dst->st_name = sym32->st_name; - dst->st_value = (Elf64_Addr) sym32->st_value; - dst->st_size = (Elf64_Xword) sym32->st_size; - dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), - ELF32_ST_TYPE(sym32->st_info)); - dst->st_other = sym32->st_other; - dst->st_shndx = sym32->st_shndx; - } else { - - sym64 = (Elf64_Sym *) d->d_buf + ndx; - - *dst = *sym64; - } - - return (dst); -} - -int -gelf_update_sym(Elf_Data *d, int ndx, GElf_Sym *gs) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - sym32 = (Elf32_Sym *) d->d_buf + ndx; - - sym32->st_name = gs->st_name; - sym32->st_info = gs->st_info; - sym32->st_other = gs->st_other; - sym32->st_shndx = gs->st_shndx; - - LIBELF_COPY_U32(sym32, gs, st_value); - LIBELF_COPY_U32(sym32, gs, st_size); - } else { - sym64 = (Elf64_Sym *) d->d_buf + ndx; - - *sym64 = *gs; - } - - return (1); -} diff --git a/lib/libelf/gelf_syminfo.c b/lib/libelf/gelf_syminfo.c deleted file mode 100644 index 90c1ed9..0000000 --- a/lib/libelf/gelf_syminfo.c +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -#if __FreeBSD_version >= 700025 - -GElf_Syminfo * -gelf_getsyminfo(Elf_Data *d, int ndx, GElf_Syminfo *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; - - dst->si_boundto = syminfo32->si_boundto; - dst->si_flags = syminfo32->si_flags; - - } else { - - syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; - - *dst = *syminfo64; - } - - return (dst); -} - -int -gelf_update_syminfo(Elf_Data *d, int ndx, GElf_Syminfo *gs) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; - - syminfo32->si_boundto = gs->si_boundto; - syminfo32->si_flags = gs->si_flags; - - } else { - syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; - - *syminfo64 = *gs; - } - - return (1); -} - -#endif /* __FreeBSD_version >= 700025 */ diff --git a/lib/libelf/gelf_symshndx.c b/lib/libelf/gelf_symshndx.c deleted file mode 100644 index b8f2103..0000000 --- a/lib/libelf/gelf_symshndx.c +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> - -#include <assert.h> -#include <gelf.h> - -#include "_libelf.h" - -GElf_Sym * -gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, - Elf32_Word *shindex) -{ - int ec; - Elf *e; - Elf_Scn *scn; - size_t msz; - uint32_t sh_type; - - if (gelf_getsym(d, ndx, dst) == 0) - return (NULL); - - if (id == NULL || (scn = id->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf) || - shindex == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - id->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - *shindex = ((Elf32_Word *) id->d_buf)[ndx]; - - return (dst); -} - -int -gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, - Elf32_Word xindex) -{ - int ec; - Elf *e; - Elf_Scn *scn; - size_t msz; - uint32_t sh_type; - - if (gelf_update_sym(d, ndx, gs) == 0) - return (0); - - if (id == NULL || (scn = id->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - d->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - *(((Elf32_Word *) id->d_buf) + ndx) = xindex; - - return (1); -} diff --git a/lib/libelf/gelf_update_ehdr.3 b/lib/libelf/gelf_update_ehdr.3 deleted file mode 100644 index df23a0c..0000000 --- a/lib/libelf/gelf_update_ehdr.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd August 27, 2006 -.Dt GELF_UPDATE_EHDR 3 -.Os -.Sh NAME -.Nm gelf_update_ehdr , -.Nm gelf_update_phdr , -.Nm gelf_update_shdr -.Nd update underlying ELF data structures -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft int -.Fn gelf_update_ehdr "Elf *elf" "GElf_Ehdr *ehdr" -.Ft int -.Fn gelf_update_phdr "Elf *elf" "int ndx" "GElf_Phdr *phdr" -.Ft int -.Fn gelf_update_shdr "Elf_Scn *scn" "GElf_Shdr *shdr" -.Sh DESCRIPTION -These functions are used to update ELF data structures on the underlying -ELF descriptor. -Class-dependent data structures in the underlying ELF descriptor -are updated using the data in the class-independent GElf descriptors -and the underlying ELF data structures are marked -.Dq dirty . -The conversion process signals an error if the values being copied -to the target ELF data structure would exceed representation -limits. -GElf descriptors are described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_update_ehdr -updates the ELF Executable Header with the values in the -class-independent executable header -.Ar ehdr . -.Pp -Function -.Fn gelf_update_phdr -updates the ELF Program Header structure at index -.Ar ndx -with the values in the class-independent program header -.Ar phdr . -.Pp -Function -.Fn gelf_update_shdr -updates the ELF Section Header structure associated with section -descriptor -.Ar scn -with the values in argument -.Ar shdr . -.Sh RETURN VALUES -These functions return a non-zero integer on success, or zero in case -of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar elf , -.Ar ehdr , -.Ar phdr , -.Ar scn , -or -.Ar shdr -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -had an unsupported ELF class. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -exceeded the number of entries in the program header table. -.It Bq Er ELF_E_ARGUMENT -Section descriptor -.Ar scn -was not associated with an ELF descriptor. -.It Bq Er ELF_E_MODE -ELF descriptor -.Ar elf -was not opened for writing or updating. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagelf 3 , -.Xr elf_flagphdr 3 , -.Xr elf_flagshdr 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr gelf_getphdr 3 , -.Xr gelf_getshdr 3 diff --git a/lib/libelf/gelf_xlate.c b/lib/libelf/gelf_xlate.c deleted file mode 100644 index d161984..0000000 --- a/lib/libelf/gelf_xlate.c +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> -#include <libelf.h> -#include <string.h> - -#include "_libelf.h" - - -Elf_Data * -elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); -} - -Elf_Data * -elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE); -} - -Elf_Data * -elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY); -} - -Elf_Data * -elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY); -} - -Elf_Data * -gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOMEMORY)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -Elf_Data * -gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOFILE)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/lib/libelf/gelf_xlatetof.3 b/lib/libelf/gelf_xlatetof.3 deleted file mode 100644 index 453f56f..0000000 --- a/lib/libelf/gelf_xlatetof.3 +++ /dev/null @@ -1,247 +0,0 @@ -.\" Copyright (c) 2006 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $FreeBSD$ -.\" -.Dd July 24, 2006 -.Dt GELF_XLATETOF 3 -.Os -.Sh NAME -.Nm elf32_xlate , -.Nm elf64_xlate , -.Nm gelf_xlate -.Nd translate data between files and memory -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Data *" -.Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.In gelf.h -.Ft "Elf_Data *" -.Fo gelf_xlatetof -.Fa "Elf *elf" -.Fa "Elf_Data *dst" -.Fa "Elf_Data *src" -.Fa "unsigned int encode" -.Fc -.Ft "Elf_Data *" -.Fo gelf_xlatetom -.Fa "Elf *elf" -.Fa "Elf_Data *dst" -.Fa "Elf_Data *src" -.Fa "unsigned int encode" -.Fc -.Sh DESCRIPTION -These functions translate between the file and memory representations -of ELF data structures. -The in-memory representation of an ELF data structure would confirm to -the byte ordering and data alignment restrictions dictated by the host -processor. -A file representation of the same data structure could use a non-native byte -ordering and in addition may be laid out differently with the file. -.Pp -Functions -.Fn elf32_xlatetom , -.Fn elf64_xlatetom , -and -.Fn gelf_xlatetom -translate data from file representations to native, in-memory representations. -Functions -.Fn elf32_xlatetof , -.Fn elf64_xlatetof , -and -.Fn gelf_xlatetof -translate data from in-memory representations to file representations. -.Pp -Argument -.Ar src -denotes an -.Vt Elf_Data -descriptor describing the source to be translated. -The following elements of the descriptor need to be set before -invoking these functions: -.Bl -hang -offset indent -.It Va d_buf -Set to a valid pointer value denoting the beginning of the data area -to be translated. -.It Va d_size -Set to the total size in bytes of the source data area to be -translated. -.It Va d_type -Set to the type of the source data being translated. -This value is one of the values defined in the -.Vt Elf_Type -enumeration. -The -.Vt Elf_Type -enumeration is described in -.Xr elf 3 . -.It Va d_version -Set to the version number of the ELF data structures being -translated. -Currently only version -.Dv EV_CURRENT -is supported. -.El -.Pp -Argument -.Ar dst -describes the destination buffer. -The following elements of the -.Vt Elf_Data -descriptor need to be set before invoking these functions: -.Bl -hang -offset indent -.It Va d_buf -Set to a valid pointer value that denotes the start of the destination -buffer that will hold translated data. -This value may be the same as that of the source buffer, in which case -an in-place conversion will be attempted. -.It Va d_size -Set to the size of the destination buffer in bytes. -This value will be modified if the function call succeeds. -.It Va d_version -Set to the desired version number of the destination. -Currently only version -.Dv EV_CURRENT -is supported. -.El -.Pp -These translations routines allow the source and destination buffers -to coincide, in which case an in-place translation will be done -if the destination is large enough to hold the translated data. -Other kinds of overlap between the source and destination buffers -are not permitted. -.Pp -On successful completion of the translation request the following -fields of the -.Ar dst -descriptor would be modified: -.Bl -hang -offset indent -.It Va d_size -Set to the size in bytes of the translated data. -.It Va d_type -Set to the -.Va d_type -value of the source data descriptor. -.El -.Pp -Argument -.Ar encode -specifies the encoding in which the file objects are represented. -It must be one of: -.Bl -hang -offset indent -.It Dv ELFDATANONE -File objects use the library's native byte ordering. -.It Dv ELFDATA2LSB -File objects use a little-endian ordering. -.It Dv ELFDATA2MSB -File objects use a big-endian ordering. -.El -.Pp -The functions -.Fn gelf_xlatetof -and -.Fn gelf_xlatetom -select the appropriate 32 or 64 bit translations based on the class of argument -.Ar elf . -.Sh RETURN VALUES -These functions return argument -.Ar dst -if successful, or NULL in case of an error. -.Sh EXAMPLES -TODO -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -One of arguments -.Ar src , -.Ar dst -or -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar src -and -.Ar dst -were equal. -.It Bq Er ELF_E_ARGUMENT -The desired encoding parameter was not one of -.Dv ELFDATANONE , -.Dv ELFDATA2LSB -or -.Dv ELFDATA2MSB . -.It Bq Er ELF_E_ARGUMENT -The -.Ar d_type -field of argument -.Ar src -specified an unsupported type. -.It Bq Er ELF_E_DATA -The -.Ar src -argument specified a buffer size that was not an integral multiple of -its underlying type. -.It Bq Er ELF_E_DATA -The -.Ar dst -argument specified a buffer size that was too small. -.It Bq Er ELF_E_DATA -Argument -.Ar dst -specified a destination buffer that overlaps with the source -buffer. -.It Bq Er ELF_E_DATA -The destination buffer for a conversion to memory had an alignment -inappropriate for the underlying ELF type. -.It Bq Er ELF_E_DATA -The source buffer for a conversion to file had an alignment -inappropriate for the underlying ELF type. -.It Bq Er ELF_E_UNIMPL -The version numbers for arguments -.Ar dst -and -.Ar src -were not identical. -.It Bq Er ELF_E_UNIMPL -The argument -.Ar src -requested conversion for a type which is not currently -supported. -.It Bq Er ELF_E_VERSION -Argument -.Ar src -specified an unsupported version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr gelf 3 diff --git a/lib/libelf/libelf.c b/lib/libelf/libelf.c deleted file mode 100644 index 837556e..0000000 --- a/lib/libelf/libelf.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> - -#include <machine/elf.h> -#include <machine/endian.h> - -#include <libelf.h> - -#include "_libelf.h" - -struct _libelf_globals _libelf = { - .libelf_arch = ELF_ARCH, - .libelf_byteorder = ELF_TARG_DATA, - .libelf_class = ELF_TARG_CLASS, - .libelf_error = 0, - .libelf_fillchar = 0, - .libelf_version = EV_NONE -}; - - -#if defined(LIBELF_TEST_HOOKS) -int -_libelf_get_elf_class(Elf *elf) -{ - return elf->e_class; -} - -void -_libelf_set_elf_class(Elf *elf, int c) -{ - elf->e_class = c; -} -#endif /* LIBELF_TEST_HOOKS */ diff --git a/lib/libelf/libelf.h b/lib/libelf/libelf.h deleted file mode 100644 index 2d235b0..0000000 --- a/lib/libelf/libelf.h +++ /dev/null @@ -1,255 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ - -#include <sys/types.h> -#include <sys/elf32.h> -#include <sys/elf64.h> -#include <sys/queue.h> - -/* Library private data structures */ -typedef struct _Elf Elf; -typedef struct _Elf_Scn Elf_Scn; - -/* File types */ -typedef enum { - ELF_K_NONE = 0, - ELF_K_AR, /* `ar' archives */ - ELF_K_COFF, /* COFF files (unsupported) */ - ELF_K_ELF, /* ELF files */ - ELF_K_NUM -} Elf_Kind; - -#define ELF_K_FIRST ELF_K_NONE -#define ELF_K_LAST ELF_K_NUM - -/* Data types */ -typedef enum { - ELF_T_ADDR, - ELF_T_BYTE, - ELF_T_CAP, - ELF_T_DYN, - ELF_T_EHDR, - ELF_T_HALF, - ELF_T_LWORD, - ELF_T_MOVE, - ELF_T_MOVEP, - ELF_T_NOTE, - ELF_T_OFF, - ELF_T_PHDR, - ELF_T_REL, - ELF_T_RELA, - ELF_T_SHDR, - ELF_T_SWORD, - ELF_T_SXWORD, - ELF_T_SYMINFO, - ELF_T_SYM, - ELF_T_VDEF, - ELF_T_VNEED, - ELF_T_WORD, - ELF_T_XWORD, - ELF_T_GNUHASH, /* GNU style hash tables. */ - ELF_T_NUM -} Elf_Type; - -#define ELF_T_FIRST ELF_T_ADDR -#define ELF_T_LAST ELF_T_GNUHASH - -/* Commands */ -typedef enum { - ELF_C_NULL = 0, - ELF_C_CLR, - ELF_C_FDDONE, - ELF_C_FDREAD, - ELF_C_RDWR, - ELF_C_READ, - ELF_C_SET, - ELF_C_WRITE, - ELF_C_NUM -} Elf_Cmd; - -#define ELF_C_FIRST ELF_C_NULL -#define ELF_C_LAST ELF_C_NUM - -/* - * An `Elf_Data' structure describes data in an - * ELF section. - */ -typedef struct _Elf_Data { - /* - * `Public' members that are part of the ELF(3) API. - */ - uint64_t d_align; - void *d_buf; - uint64_t d_off; - uint64_t d_size; - Elf_Type d_type; - unsigned int d_version; - - /* - * Members that are not part of the public API. - */ - Elf_Scn *d_scn; /* containing section */ - unsigned int d_flags; - STAILQ_ENTRY(_Elf_Data) d_next; -} Elf_Data; - -/* - * An `Elf_Arhdr' structure describes an archive - * header. - */ -typedef struct { - time_t ar_date; - char *ar_name; /* archive member name */ - gid_t ar_gid; - mode_t ar_mode; - char *ar_rawname; /* 'raw' member name */ - size_t ar_size; - uid_t ar_uid; -} Elf_Arhdr; - -/* - * An `Elf_Arsym' describes an entry in the archive - * symbol table. - */ -typedef struct { - off_t as_off; /* byte offset to member's header */ - unsigned long as_hash; /* elf_hash() value for name */ - char *as_name; /* null terminated symbol name */ -} Elf_Arsym; - -/* - * Error numbers. - */ - -enum Elf_Error { - ELF_E_NONE, /* No error */ - ELF_E_ARCHIVE, /* Malformed ar(1) archive */ - ELF_E_ARGUMENT, /* Invalid argument */ - ELF_E_CLASS, /* Mismatched ELF class */ - ELF_E_DATA, /* Invalid data descriptor */ - ELF_E_HEADER, /* Missing or malformed ELF header */ - ELF_E_IO, /* I/O error */ - ELF_E_LAYOUT, /* Layout constraint violation */ - ELF_E_MODE, /* Wrong mode for ELF descriptor */ - ELF_E_RANGE, /* Value out of range */ - ELF_E_RESOURCE, /* Resource exhaustion */ - ELF_E_SECTION, /* Invalid section descriptor */ - ELF_E_SEQUENCE, /* API calls out of sequence */ - ELF_E_UNIMPL, /* Feature is unimplemented */ - ELF_E_VERSION, /* Unknown API version */ - ELF_E_NUM /* Max error number */ -}; - -/* - * Flags defined by the API. - */ - -#define ELF_F_LAYOUT 0x001U /* application will layout the file */ -#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ - -__BEGIN_DECLS -Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); -int elf_cntl(Elf *_elf, Elf_Cmd _cmd); -int elf_end(Elf *_elf); -const char *elf_errmsg(int _error); -int elf_errno(void); -void elf_fill(int _fill); -unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -Elf_Arhdr *elf_getarhdr(Elf *_elf); -Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); -off_t elf_getbase(Elf *_elf); -Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); -char *elf_getident(Elf *_elf, size_t *_ptr); -int elf_getphdrnum(Elf *_elf, size_t *_dst); -int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ -Elf_Scn *elf_getscn(Elf *_elf, size_t _index); -int elf_getshdrnum(Elf *_elf, size_t *_dst); -int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ -int elf_getshdrstrndx(Elf *_elf, size_t *_dst); -int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ -unsigned long elf_hash(const char *_name); -Elf_Kind elf_kind(Elf *_elf); -Elf *elf_memory(char *_image, size_t _size); -size_t elf_ndxscn(Elf_Scn *_scn); -Elf_Data *elf_newdata(Elf_Scn *_scn); -Elf_Scn *elf_newscn(Elf *_elf); -Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); -Elf_Cmd elf_next(Elf *_elf); -off_t elf_rand(Elf *_elf, off_t _off); -Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); -char *elf_rawfile(Elf *_elf, size_t *_size); -int elf_setshstrndx(Elf *_elf, size_t _shnum); -char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); -off_t elf_update(Elf *_elf, Elf_Cmd _cmd); -unsigned int elf_version(unsigned int _version); - -long elf32_checksum(Elf *_elf); -size_t elf32_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf32_Ehdr *elf32_getehdr(Elf *_elf); -Elf32_Phdr *elf32_getphdr(Elf *_elf); -Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); -Elf32_Ehdr *elf32_newehdr(Elf *_elf); -Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); - -long elf64_checksum(Elf *_elf); -size_t elf64_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf64_Ehdr *elf64_getehdr(Elf *_elf); -Elf64_Phdr *elf64_getphdr(Elf *_elf); -Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); -Elf64_Ehdr *elf64_newehdr(Elf *_elf); -Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); - -#if defined(LIBELF_TEST_HOOKS) -int _libelf_get_elf_class(Elf *_elf); -int _libelf_get_max_error(void); -const char *_libelf_get_no_error_message(void); -const char *_libelf_get_unknown_error_message(void); -void _libelf_set_elf_class(Elf *_elf, int _class); -void _libelf_set_error(int _error); -#endif /* LIBELF_TEST_HOOKS */ -__END_DECLS - -#endif /* _LIBELF_H_ */ diff --git a/lib/libelf/libelf_align.c b/lib/libelf/libelf_align.c deleted file mode 100644 index 870c9b7..0000000 --- a/lib/libelf/libelf_align.c +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> - -#include <machine/elf.h> -#include <machine/endian.h> - -#include <libelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -struct align { - int a32; - int a64; -}; - -#ifdef __GNUC__ -#define MALIGN(N) { \ - .a32 = __alignof__(Elf32_##N), \ - .a64 = __alignof__(Elf64_##N) \ - } -#define MALIGN64(V) { \ - .a32 = 0, \ - .a64 = __alignof__(Elf64_##V) \ - } -#define MALIGN_WORD() { \ - .a32 = __alignof__(int32_t), \ - .a64 = __alignof__(int64_t) \ - } -#else -#error Need the __alignof__ builtin. -#endif -#define UNSUPPORTED() { \ - .a32 = 0, \ - .a64 = 0 \ - } - -static struct align malign[ELF_T_NUM] = { - [ELF_T_ADDR] = MALIGN(Addr), - [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, -#if __FreeBSD_version >= 700025 - [ELF_T_CAP] = MALIGN(Cap), -#endif - [ELF_T_DYN] = MALIGN(Dyn), - [ELF_T_EHDR] = MALIGN(Ehdr), - [ELF_T_HALF] = MALIGN(Half), -#if __FreeBSD_version >= 700025 - [ELF_T_LWORD] = MALIGN(Lword), - [ELF_T_MOVE] = MALIGN(Move), -#endif - [ELF_T_MOVEP] = UNSUPPORTED(), -#if __FreeBSD_version >= 700025 - [ELF_T_NOTE] = MALIGN(Nhdr), -#endif - [ELF_T_OFF] = MALIGN(Off), - [ELF_T_PHDR] = MALIGN(Phdr), - [ELF_T_REL] = MALIGN(Rel), - [ELF_T_RELA] = MALIGN(Rela), - [ELF_T_SHDR] = MALIGN(Shdr), - [ELF_T_SWORD] = MALIGN(Sword), - [ELF_T_SXWORD] = MALIGN64(Sxword), - [ELF_T_SYM] = MALIGN(Sym), -#if __FreeBSD_version >= 700025 - [ELF_T_SYMINFO] = MALIGN(Syminfo), -#endif -#if __FreeBSD_version >= 700009 - [ELF_T_VDEF] = MALIGN(Verdef), - [ELF_T_VNEED] = MALIGN(Verneed), -#endif - [ELF_T_WORD] = MALIGN(Word), - [ELF_T_XWORD] = MALIGN64(Xword), -#if __FreeBSD_version >= 800062 - [ELF_T_GNUHASH] = MALIGN_WORD() -#endif -}; - -int -_libelf_malign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? malign[t].a32 : - malign[t].a64); -} - -#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } - -static struct align falign[ELF_T_NUM] = { - [ELF_T_ADDR] = FALIGN(4,8), - [ELF_T_BYTE] = FALIGN(1,1), -#if __FreeBSD_version >= 700025 - [ELF_T_CAP] = FALIGN(4,8), -#endif - [ELF_T_DYN] = FALIGN(4,8), - [ELF_T_EHDR] = FALIGN(4,8), - [ELF_T_HALF] = FALIGN(2,2), -#if __FreeBSD_version >= 700025 - [ELF_T_LWORD] = FALIGN(8,8), - [ELF_T_MOVE] = FALIGN(8,8), -#endif - [ELF_T_MOVEP] = UNSUPPORTED(), -#if __FreeBSD_version >= 700025 - [ELF_T_NOTE] = FALIGN(1,1), -#endif - [ELF_T_OFF] = FALIGN(4,8), - [ELF_T_PHDR] = FALIGN(4,8), - [ELF_T_REL] = FALIGN(4,8), - [ELF_T_RELA] = FALIGN(4,8), - [ELF_T_SHDR] = FALIGN(4,8), - [ELF_T_SWORD] = FALIGN(4,4), - [ELF_T_SXWORD] = FALIGN(0,8), - [ELF_T_SYM] = FALIGN(4,8), -#if __FreeBSD_version >= 700025 - [ELF_T_SYMINFO] = FALIGN(2,2), -#endif -#if __FreeBSD_version >= 700009 - [ELF_T_VDEF] = FALIGN(4,4), - [ELF_T_VNEED] = FALIGN(4,4), -#endif - [ELF_T_WORD] = FALIGN(4,4), - [ELF_T_XWORD] = FALIGN(0,8), -#if __FreeBSD_version >= 800062 - [ELF_T_GNUHASH] = FALIGN(4,8) -#endif -}; - -int -_libelf_falign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? falign[t].a32 : - falign[t].a64); -} diff --git a/lib/libelf/libelf_allocate.c b/lib/libelf/libelf_allocate.c deleted file mode 100644 index 1fa1eee..0000000 --- a/lib/libelf/libelf_allocate.c +++ /dev/null @@ -1,209 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -/* - * Internal APIs - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/errno.h> - -#include <assert.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> - -#include "_libelf.h" - -Elf * -_libelf_allocate_elf(void) -{ - Elf *e; - - if ((e = malloc(sizeof(*e))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return NULL; - } - - e->e_activations = 1; - e->e_arhdr = NULL; - e->e_byteorder = ELFDATANONE; - e->e_class = ELFCLASSNONE; - e->e_cmd = ELF_C_NULL; - e->e_fd = -1; - e->e_flags = 0; - e->e_kind = ELF_K_NONE; - e->e_parent = NULL; - e->e_rawfile = NULL; - e->e_rawsize = 0; - e->e_version = LIBELF_PRIVATE(version); - - (void) memset(&e->e_u, 0, sizeof(e->e_u)); - - return (e); -} - -void -_libelf_init_elf(Elf *e, Elf_Kind kind) -{ - assert(e != NULL); - assert(e->e_kind == ELF_K_NONE); - - e->e_kind = kind; - - switch (kind) { - case ELF_K_ELF: - STAILQ_INIT(&e->e_u.e_elf.e_scn); - break; - default: - break; - } -} - -#define FREE(P) do { \ - if (P) \ - free(P); \ - } while (0) - - -Elf * -_libelf_release_elf(Elf *e) -{ - switch (e->e_kind) { - case ELF_K_AR: - FREE(e->e_u.e_ar.e_symtab); - break; - - case ELF_K_ELF: - switch (e->e_class) { - case ELFCLASS32: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); - FREE(e->e_u.e_elf.e_phdr.e_phdr32); - break; - case ELFCLASS64: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); - FREE(e->e_u.e_elf.e_phdr.e_phdr64); - break; - } - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - if (e->e_arhdr) { - FREE(e->e_arhdr->ar_name); - FREE(e->e_arhdr->ar_rawname); - free(e->e_arhdr); - } - - break; - - default: - break; - } - - free(e); - - return (NULL); -} - -Elf_Data * -_libelf_allocate_data(Elf_Scn *s) -{ - Elf_Data *d; - - if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_scn = s; - - return (d); -} - -Elf_Data * -_libelf_release_data(Elf_Data *d) -{ - - if (d->d_flags & LIBELF_F_MALLOCED) - free(d->d_buf); - - free(d); - - return (NULL); -} - -Elf_Scn * -_libelf_allocate_scn(Elf *e, size_t ndx) -{ - Elf_Scn *s; - - if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return (NULL); - } - - s->s_elf = e; - s->s_ndx = ndx; - - STAILQ_INIT(&s->s_data); - STAILQ_INIT(&s->s_rawdata); - - STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); - - return (s); -} - -Elf_Scn * -_libelf_release_scn(Elf_Scn *s) -{ - Elf *e; - Elf_Data *d, *td; - - assert(s != NULL); - - STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { - STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next); - d = _libelf_release_data(d); - } - - STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { - assert((d->d_flags & LIBELF_F_MALLOCED) == 0); - STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next); - d = _libelf_release_data(d); - } - - e = s->s_elf; - - assert(e != NULL); - - STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); - - free(s); - - return (NULL); -} diff --git a/lib/libelf/libelf_ar.c b/lib/libelf/libelf_ar.c deleted file mode 100644 index 7322617..0000000 --- a/lib/libelf/libelf_ar.c +++ /dev/null @@ -1,272 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <assert.h> -#include <ctype.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> - -#include "_libelf.h" - -#define LIBELF_NALLOC_SIZE 16 - -/* - * `ar' archive handling. - * - * `ar' archives start with signature `ARMAG'. Each archive member is - * preceded by a header containing meta-data for the member. This - * header is described in <ar.h> (struct ar_hdr). The header always - * starts on an even address. File data is padded with "\n" - * characters to keep this invariant. - * - * Special considerations for `ar' archives: - * - * The `ar' header only has space for a 16 character file name. File - * names are terminated with a '/', so this effectively leaves 15 - * characters for the actual file name. In order to accomodate longer - * file names, names may be stored in a separate 'string table' and - * referenced indirectly by a member header. The string table itself - * appears as an archive member with name "// ". An indirect file name - * in an `ar' header matches the pattern "/[0-9]*". The digits form a - * decimal number that corresponds to a byte offset into the string - * table where the actual file name of the object starts. Strings in - * the string table are padded to start on even addresses. - * - * Archives may also have a symbol table (see ranlib(1)), mapping - * program symbols to object files inside the archive. A symbol table - * uses a file name of "/ " in its archive header. The symbol table - * is structured as: - * - a 4-byte count of entries stored as a binary value, MSB first - * - 'n' 4-byte offsets, stored as binary values, MSB first - * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. - * - * If the symbol table and string table are is present in an archive - * they must be the very first objects and in that order. - */ - - - -Elf_Arhdr * -_libelf_ar_gethdr(Elf *e) -{ - Elf *parent; - struct ar_hdr *arh; - Elf_Arhdr *eh; - size_t n; - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - arh = (struct ar_hdr *) ((uintptr_t) e->e_rawfile - sizeof(struct ar_hdr)); - - assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG); - assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile + parent->e_rawsize - - sizeof(struct ar_hdr)); - - if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - e->e_arhdr = eh; - eh->ar_name = eh->ar_rawname = NULL; - - if ((eh->ar_name = _libelf_ar_get_name(arh->ar_name, sizeof(arh->ar_name), - parent)) == NULL) - goto error; - - if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, &n) == 0) - goto error; - eh->ar_uid = (uid_t) n; - - if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, &n) == 0) - goto error; - eh->ar_gid = (gid_t) n; - - if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, &n) == 0) - goto error; - eh->ar_mode = (mode_t) n; - - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, &n) == 0) - goto error; - eh->ar_size = n; - - if ((eh->ar_rawname = _libelf_ar_get_string(arh->ar_name, - sizeof(arh->ar_name), 1)) == NULL) - goto error; - - return (eh); - - error: - if (eh) { - if (eh->ar_name) - free(eh->ar_name); - if (eh->ar_rawname) - free(eh->ar_rawname); - free(eh); - } - e->e_arhdr = NULL; - - return (NULL); -} - -Elf * -_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) -{ - Elf *e; - off_t next; - struct ar_hdr *arh; - size_t sz; - - assert(elf->e_kind == ELF_K_AR); - - next = elf->e_u.e_ar.e_next; - - /* - * `next' is only set to zero by elf_next() when the last - * member of an archive is processed. - */ - if (next == (off_t) 0) - return (NULL); - - assert((next & 1) == 0); - - arh = (struct ar_hdr *) (elf->e_rawfile + next); - - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, &sz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - assert(sz > 0); - - arh++; /* skip over archive member header */ - - if ((e = elf_memory((char *) arh, sz)) == NULL) - return (NULL); - - e->e_fd = fd; - e->e_cmd = c; - - elf->e_u.e_ar.e_nchildren++; - e->e_parent = elf; - - return (e); -} - -/* - * An ar(1) symbol table has the following layout: - * - * The first 4 bytes are a binary count of the number of entries in the - * symbol table, stored MSB-first. - * - * Then there are 'n' 4-byte binary offsets, also stored MSB first. - * - * Following this, there are 'n' null-terminated strings. - */ - -#define GET_WORD(P, V) do { \ - (V) = 0; \ - (V) = (P)[0]; (V) <<= 8; \ - (V) += (P)[1]; (V) <<= 8; \ - (V) += (P)[2]; (V) <<= 8; \ - (V) += (P)[3]; \ - } while (0) - -#define INTSZ 4 - -Elf_Arsym * -_libelf_ar_process_symtab(Elf *e, size_t *count) -{ - size_t n, nentries, off; - Elf_Arsym *symtab, *sym; - unsigned char *p, *s, *end; - - assert(e != NULL); - assert(count != NULL); - - if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; - end = p + e->e_u.e_ar.e_rawsymtabsz; - - GET_WORD(p, nentries); - p += INTSZ; - - if (nentries == 0 || p + nentries * INTSZ >= end) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - /* Allocate space for a nentries + a sentinel. */ - if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - s = p + (nentries * INTSZ); /* start of the string table. */ - - for (n = nentries, sym = symtab; n > 0; n--) { - off = 0; - - GET_WORD(p, off); - - sym->as_off = off; - sym->as_hash = elf_hash(s); - sym->as_name = s; - - p += INTSZ; - sym++; - - for (; s < end && *s++ != '\0';) /* skip to next string */ - ; - if (s > end) { - LIBELF_SET_ERROR(ARCHIVE, 0); - free(symtab); - return (NULL); - } - } - - /* Fill up the sentinel entry. */ - sym->as_name = NULL; - sym->as_hash = ~0UL; - sym->as_off = (off_t) 0; - - *count = e->e_u.e_ar.e_symtabsz = nentries + 1; - e->e_u.e_ar.e_symtab = symtab; - - return (symtab); -} diff --git a/lib/libelf/libelf_ar_util.c b/lib/libelf/libelf_ar_util.c deleted file mode 100644 index 3834ac4..0000000 --- a/lib/libelf/libelf_ar_util.c +++ /dev/null @@ -1,253 +0,0 @@ -/*- - * Copyright (c) 2006,2009 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <ar.h> -#include <assert.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> - -#include "_libelf.h" - -/* - * Convert a string bounded by `start' and `start+sz' (exclusive) to a - * number in the specified base. - */ -int -_libelf_ar_get_number(char *s, size_t sz, int base, size_t *ret) -{ - int c, v; - size_t r; - char *e; - - assert(base <= 10); - - e = s + sz; - - /* skip leading blanks */ - for (;s < e && (c = *s) == ' '; s++) - ; - - r = 0L; - for (;s < e; s++) { - if ((c = *s) == ' ') - break; - if (c < '0' || c > '9') - return (0); - v = c - '0'; - if (v >= base) /* Illegal digit. */ - break; - r *= base; - r += v; - } - - *ret = r; - - return (1); -} - -/* - * Retrieve a string from a name field. If `rawname' is set, leave - * ar(1) control characters in. - */ -char * -_libelf_ar_get_string(const char *buf, size_t bufsize, int rawname) -{ - const char *q; - char *r; - size_t sz; - - if (rawname) - sz = bufsize + 1; - else { - /* Skip back over trailing blanks. */ - for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) - ; - - if (q < buf) { - /* - * If the input buffer only had blanks in it, - * return a zero-length string. - */ - buf = ""; - sz = 1; - } else { - /* - * Remove the trailing '/' character, but only - * if the name isn't one of the special names - * "/" and "//". - */ - if (q > buf + 1 || - (q == (buf + 1) && *buf != '/')) - q--; - - sz = q - buf + 2; /* Space for a trailing NUL. */ - } - } - - if ((r = malloc(sz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(r, buf, sz); - r[sz - 1] = '\0'; - - return (r); -} - -/* - * Retrieve the full name of the archive member. - */ -char * -_libelf_ar_get_name(char *buf, size_t bufsize, Elf *e) -{ - char c, *q, *r, *s; - size_t len; - size_t offset; - - assert(e->e_kind == ELF_K_AR); - - if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { - /* - * The value in field ar_name is a decimal offset into - * the archive string table where the actual name - * resides. - */ - if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, - &offset) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - if (offset > e->e_u.e_ar.e_rawstrtabsz) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - s = q = e->e_u.e_ar.e_rawstrtab + offset; - r = e->e_u.e_ar.e_rawstrtab + e->e_u.e_ar.e_rawstrtabsz; - - for (s = q; s < r && *s != '/'; s++) - ; - len = s - q + 1; /* space for the trailing NUL */ - - if ((s = malloc(len)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(s, q, len); - s[len - 1] = '\0'; - - return (s); - } - - /* - * Normal 'name' - */ - return (_libelf_ar_get_string(buf, bufsize, 0)); -} - -/* - * Open an 'ar' archive. - */ -Elf * -_libelf_ar_open(Elf *e) -{ - int i; - char *s, *end; - size_t sz; - struct ar_hdr arh; - - e->e_kind = ELF_K_AR; - e->e_u.e_ar.e_nchildren = 0; - e->e_u.e_ar.e_next = (off_t) -1; - - /* - * Look for special members. - */ - - s = e->e_rawfile + SARMAG; - end = e->e_rawfile + e->e_rawsize; - - assert(e->e_rawsize > 0); - - /* - * Look for magic names "/ " and "// " in the first two entries - * of the archive. - */ - for (i = 0; i < 2; i++) { - - if (s + sizeof(arh) > end) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - (void) memcpy(&arh, s, sizeof(arh)); - - if (arh.ar_fmag[0] != '`' || arh.ar_fmag[1] != '\n') { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - if (arh.ar_name[0] != '/') /* not a special symbol */ - break; - - if (_libelf_ar_get_number(arh.ar_size, sizeof(arh.ar_size), - 10, &sz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - assert(sz > 0); - - s += sizeof(arh); - - if (arh.ar_name[1] == ' ') { /* "/ " => symbol table */ - - e->e_u.e_ar.e_rawsymtab = s; - e->e_u.e_ar.e_rawsymtabsz = sz; - - } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { - - /* "// " => string table for long file names */ - e->e_u.e_ar.e_rawstrtab = s; - e->e_u.e_ar.e_rawstrtabsz = sz; - } - - sz = LIBELF_ADJUST_AR_SIZE(sz); - - s += sz; - } - - e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); - - return (e); -} diff --git a/lib/libelf/libelf_checksum.c b/lib/libelf/libelf_checksum.c deleted file mode 100644 index c7eb8a0..0000000 --- a/lib/libelf/libelf_checksum.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> - -#include "_libelf.h" - -static unsigned long -_libelf_sum(unsigned long c, const unsigned char *s, size_t size) -{ - if (s == NULL || size == 0) - return (c); - - while (size--) - c += *s++; - - return (c); -} - -unsigned long -_libelf_checksum(Elf *e, int elfclass) -{ - size_t shn; - Elf_Scn *scn; - Elf_Data *d; - unsigned long checksum; - GElf_Ehdr eh; - GElf_Shdr shdr; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - - if (e->e_class != elfclass) { - LIBELF_SET_ERROR(CLASS, 0); - return (0L); - } - - if (gelf_getehdr(e, &eh) == NULL) - return (0); - - /* - * Iterate over all sections in the ELF file, computing the - * checksum along the way. - * - * The first section is always SHN_UNDEF and can be skipped. - * Non-allocatable sections are skipped, as are sections that - * could be affected by utilities such as strip(1). - */ - - checksum = 0; - for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { - if ((scn = elf_getscn(e, shn)) == NULL) - return (0); - if (gelf_getshdr(scn, &shdr) == NULL) - return (0); - if ((shdr.sh_flags & SHF_ALLOC) == 0 || - shdr.sh_type == SHT_DYNAMIC || - shdr.sh_type == SHT_DYNSYM) - continue; - - d = NULL; - while ((d = elf_rawdata(scn, d)) != NULL) - checksum = _libelf_sum(checksum, - (unsigned char *) d->d_buf, d->d_size); - } - - /* - * Return a 16-bit checksum compatible with Solaris. - */ - return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); -} diff --git a/lib/libelf/libelf_convert.m4 b/lib/libelf/libelf_convert.m4 deleted file mode 100644 index 15bb6d1..0000000 --- a/lib/libelf/libelf_convert.m4 +++ /dev/null @@ -1,909 +0,0 @@ -/*- - * Copyright (c) 2006-2008 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/elf32.h> -#include <sys/elf64.h> - -#include <assert.h> -#include <libelf.h> -#include <osreldate.h> -#include <string.h> - -#include "_libelf.h" - -/* WARNING: GENERATED FROM __file__. */ - -/* - * Macros to swap various integral quantities. - */ - -#define SWAP_HALF(X) do { \ - uint16_t _x = (uint16_t) (X); \ - uint16_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_WORD(X) do { \ - uint32_t _x = (uint32_t) (X); \ - uint32_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR32(X) SWAP_WORD(X) -#define SWAP_OFF32(X) SWAP_WORD(X) -#define SWAP_SWORD(X) SWAP_WORD(X) -#define SWAP_WORD64(X) do { \ - uint64_t _x = (uint64_t) (X); \ - uint64_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR64(X) SWAP_WORD64(X) -#define SWAP_LWORD(X) SWAP_WORD64(X) -#define SWAP_OFF64(X) SWAP_WORD64(X) -#define SWAP_SXWORD(X) SWAP_WORD64(X) -#define SWAP_XWORD(X) SWAP_WORD64(X) - -/* - * Write out various integral values. The destination pointer could - * be unaligned. Values are written out in native byte order. The - * destination pointer is incremented after the write. - */ -#define WRITE_BYTE(P,X) do { \ - char *const _p = (char *) (P); \ - _p[0] = (char) (X); \ - (P) = _p + 1; \ - } while (0) -#define WRITE_HALF(P,X) do { \ - uint16_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - (P) = _p + 2; \ - } while (0) -#define WRITE_WORD(P,X) do { \ - uint32_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - (P) = _p + 4; \ - } while (0) -#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) -#define WRITE_OFF32(P,X) WRITE_WORD(P,X) -#define WRITE_SWORD(P,X) WRITE_WORD(P,X) -#define WRITE_WORD64(P,X) do { \ - uint64_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - _p[4] = _q[4]; \ - _p[5] = _q[5]; \ - _p[6] = _q[6]; \ - _p[7] = _q[7]; \ - (P) = _p + 8; \ - } while (0) -#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) -#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) -#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_IDENT(P,X) do { \ - (void) memcpy((P), (X), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -/* - * Read in various integral values. The source pointer could be - * unaligned. Values are read in native byte order. The source - * pointer is incremented appropriately. - */ - -#define READ_BYTE(P,X) do { \ - const char *const _p = \ - (const char *) (P); \ - (X) = _p[0]; \ - (P) = (P) + 1; \ - } while (0) -#define READ_HALF(P,X) do { \ - uint16_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - (P) = (P) + 2; \ - (X) = _t; \ - } while (0) -#define READ_WORD(P,X) do { \ - uint32_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - (P) = (P) + 4; \ - (X) = _t; \ - } while (0) -#define READ_ADDR32(P,X) READ_WORD(P,X) -#define READ_OFF32(P,X) READ_WORD(P,X) -#define READ_SWORD(P,X) READ_WORD(P,X) -#define READ_WORD64(P,X) do { \ - uint64_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - _q[4] = _p[4]; \ - _q[5] = _p[5]; \ - _q[6] = _p[6]; \ - _q[7] = _p[7]; \ - (P) = (P) + 8; \ - (X) = _t; \ - } while (0) -#define READ_ADDR64(P,X) READ_WORD64(P,X) -#define READ_LWORD(P,X) READ_WORD64(P,X) -#define READ_OFF64(P,X) READ_WORD64(P,X) -#define READ_SXWORD(P,X) READ_WORD64(P,X) -#define READ_XWORD(P,X) READ_WORD64(P,X) -#define READ_IDENT(P,X) do { \ - (void) memcpy((X), (P), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) - -divert(-1) - -/* - * Generate conversion routines for converting between in-memory and - * file representations of Elf data structures. - * - * `In-memory' representations of an Elf data structure use natural - * alignments and native byte ordering. This allows arithmetic and - * casting to work as expected. On the other hand the `file' - * representation of an ELF data structure could be packed tighter - * than its `in-memory' representation, and could be of a differing - * byte order. An additional complication is that `ar' only pads data - * to even addresses and so ELF archive member data being read from - * inside an `ar' archive could end up at misaligned memory addresses. - * - * Consequently, casting the `char *' pointers that point to memory - * representations (i.e., source pointers for the *_tof() functions - * and the destination pointers for the *_tom() functions), is safe, - * as these pointers should be correctly aligned for the memory type - * already. However, pointers to file representations have to be - * treated as being potentially unaligned and no casting can be done. - */ - -include(SRCDIR`/elf_types.m4') - -/* - * `IGNORE'_* flags turn off generation of template code. - */ - -define(`IGNORE', - `define(IGNORE_$1`'32, 1) - define(IGNORE_$1`'64, 1)') - -IGNORE(MOVEP) -IGNORE(NOTE) -IGNORE(GNUHASH) - -define(IGNORE_BYTE, 1) /* 'lator, leave 'em bytes alone */ -define(IGNORE_GNUHASH, 1) -define(IGNORE_NOTE, 1) -define(IGNORE_SXWORD32, 1) -define(IGNORE_XWORD32, 1) - -/* - * `BASE'_XXX flags cause class agnostic template functions - * to be generated. - */ - -define(`BASE_BYTE', 1) -define(`BASE_HALF', 1) -define(`BASE_NOTE', 1) -define(`BASE_WORD', 1) -define(`BASE_LWORD', 1) -define(`BASE_SWORD', 1) -define(`BASE_XWORD', 1) -define(`BASE_SXWORD', 1) - -/* - * `SIZEDEP'_XXX flags cause 32/64 bit variants to be generated - * for each primitive type. - */ - -define(`SIZEDEP_ADDR', 1) -define(`SIZEDEP_OFF', 1) - -/* - * `Primitive' ELF types are those that are an alias for an integral - * type. They have no internal structure. These can be copied using - * a `memcpy()', and byteswapped in straightforward way. - * - * Macro use: - * `$1': Name of the ELF type. - * `$2': C structure name suffix - * `$3': ELF class specifier for symbols, one of [`', `32', `64'] - * `$4': ELF class specifier for types, one of [`32', `64'] - */ -define(`MAKEPRIM_TO_F',` -static int -libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$4_$2 t, *s = (Elf$4_$2 *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_$1$3(t); - WRITE_$1$3(dst,t); - } - - return (1); -} -') - -define(`MAKEPRIM_TO_M',` -static int -libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$4_$2 t, *d = (Elf$4_$2 *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf$4_$2)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_$1$3(src,t); - SWAP_$1$3(t); - *d++ = t; - } - - return (1); -} -') - -define(`SWAP_FIELD', - `ifdef(`IGNORE_'$2,`', - `ifelse(BASE_$2,1, - `SWAP_$2(t.$1); - ', - `ifelse($2,BYTE,`', - `ifelse($2,IDENT,`', - `SWAP_$2'SZ()`(t.$1); - ')')')')') -define(`SWAP_MEMBERS', - `ifelse($#,1,`/**/', - `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') - -define(`SWAP_STRUCT', - `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ - SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - -define(`WRITE_FIELD', - `ifelse(BASE_$2,1, - `WRITE_$2(dst,t.$1); - ', - `ifelse($2,IDENT, - `WRITE_$2(dst,t.$1); - ', - `WRITE_$2'SZ()`(dst,t.$1); - ')')') -define(`WRITE_MEMBERS', - `ifelse($#,1,`/**/', - `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') - -define(`WRITE_STRUCT', - `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ - WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - -define(`READ_FIELD', - `ifelse(BASE_$2,1, - `READ_$2(s,t.$1); - ', - `ifelse($2,IDENT, - `READ_$2(s,t.$1); - ', - `READ_$2'SZ()`(s,t.$1); - ')')') - -define(`READ_MEMBERS', - `ifelse($#,1,`/**/', - `READ_FIELD($1)READ_MEMBERS(shift($@))')') - -define(`READ_STRUCT', - `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ - READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - -/* - * Converters for non-integral ELF data structures. - * - * When converting data to file representation, the source pointer - * will be naturally aligned for a data structure's in-memory - * representation. When converting data to memory, the destination - * pointer will be similarly aligned. - * - * For in-place conversions, when converting to file representations, - * the source buffer is large enough to hold `file' data. When - * converting from file to memory, we need to be careful to work - * `backwards', to avoid overwriting unconverted data. - * - * Macro use: - * `$1': Name of the ELF type. - * `$2': C structure name suffix. - * `$3': ELF class specifier, one of [`', `32', `64'] - */ - -define(`MAKE_TO_F', - `ifdef(`IGNORE_'$1$3,`',` -static int -libelf_cvt$3_$1_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *s; - size_t c; - - (void) dsz; - - s = (Elf$3_$2 *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - SWAP_STRUCT($2,$3) - } - WRITE_STRUCT($2,$3) - } - - return (1); -} -')') - -define(`MAKE_TO_M', - `ifdef(`IGNORE_'$1$3,`',` -static int -libelf_cvt$3_$1_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); - d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf$3_$2)) - return (0); - - while (count--) { - s = s0; - READ_STRUCT($2,$3) - if (byteswap) { - SWAP_STRUCT($2,$3) - } - *d-- = t; s0 -= fsz; - } - - return (1); -} -')') - -/* - * Make type convertor functions from the type definition - * of the ELF type: - * - if the type is a base (i.e., `primitive') type: - * - if it is marked as to be ignored (i.e., `IGNORE_'TYPE) - * is defined, we skip the code generation step. - * - if the type is declared as `SIZEDEP', then 32 and 64 bit - * variants of the conversion functions are generated. - * - otherwise a 32 bit variant is generated. - * - if the type is a structure type, we generate 32 and 64 bit - * variants of the conversion functions. - */ - -define(`MAKE_TYPE_CONVERTER', - `#if __FreeBSD_version >= $3 /* $1 */ -ifdef(`BASE'_$1, - `ifdef(`IGNORE_'$1,`', - `MAKEPRIM_TO_F($1,$2,`',64) - MAKEPRIM_TO_M($1,$2,`',64)')', - `ifdef(`SIZEDEP_'$1, - `MAKEPRIM_TO_F($1,$2,32,32)dnl - MAKEPRIM_TO_M($1,$2,32,32)dnl - MAKEPRIM_TO_F($1,$2,64,64)dnl - MAKEPRIM_TO_M($1,$2,64,64)', - `MAKE_TO_F($1,$2,32)dnl - MAKE_TO_F($1,$2,64)dnl - MAKE_TO_M($1,$2,32)dnl - MAKE_TO_M($1,$2,64)')') -#endif /* $1 */ -') - -define(`MAKE_TYPE_CONVERTERS', - `ifelse($#,1,`', - `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') - -divert(0) - -/* - * Sections of type ELF_T_BYTE are never byteswapped, consequently a - * simple memcpy suffices for both directions of conversion. - */ - -static int -libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - (void) byteswap; - if (dsz < count) - return (0); - if (dst != src) - (void) memcpy(dst, src, count); - return (1); -} - -MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) - -#if __FreeBSD_version >= 800062 -/* - * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit - * words. Bloom filter data comes next, followed by hash buckets and the - * hash chain. - * - * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit - * wide on ELFCLASS32 objects. The other objects in this section are 32 - * bits wide. - * - * Argument `srcsz' denotes the number of bytes to be converted. In the - * 32-bit case we need to translate `srcsz' to a count of 32-bit words. - */ - -static int -libelf_cvt32_GNUHASH_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -libelf_cvt32_GNUHASH_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -libelf_cvt64_GNUHASH_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - size_t sz; - uint64_t t64, *bloom64; - Elf_GNU_Hash_Header *gh; - uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; - uint32_t *buckets, *chains; - - sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ - if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) - return (0); - - /* Read in the section header and byteswap if needed. */ - READ_WORD(src, nbuckets); - READ_WORD(src, symndx); - READ_WORD(src, maskwords); - READ_WORD(src, shift2); - - srcsz -= sz; - - if (byteswap) { - SWAP_WORD(nbuckets); - SWAP_WORD(symndx); - SWAP_WORD(maskwords); - SWAP_WORD(shift2); - } - - /* Check source buffer and destination buffer sizes. */ - sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); - if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; - gh->gh_nbuckets = nbuckets; - gh->gh_symndx = symndx; - gh->gh_maskwords = maskwords; - gh->gh_shift2 = shift2; - - dsz -= sizeof(Elf_GNU_Hash_Header); - dst += sizeof(Elf_GNU_Hash_Header); - - bloom64 = (uint64_t *) (uintptr_t) dst; - - /* Copy bloom filter data. */ - for (n = 0; n < maskwords; n++) { - READ_XWORD(src, t64); - if (byteswap) - SWAP_XWORD(t64); - bloom64[n] = t64; - } - - /* The hash buckets follows the bloom filter. */ - dst += maskwords * sizeof(uint64_t); - buckets = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nbuckets; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - buckets[n] = t32; - } - - dst += nbuckets * sizeof(uint32_t); - - /* The hash chain follows the hash buckets. */ - dsz -= sz; - srcsz -= sz; - - if (dsz < srcsz) /* Destination lacks space. */ - return (0); - - nchains = srcsz / sizeof(uint32_t); - chains = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nchains; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - *chains++ = t32; - } - - return (1); -} - -static int -libelf_cvt64_GNUHASH_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - uint32_t *s32; - size_t sz, hdrsz; - uint64_t *s64, t64; - Elf_GNU_Hash_Header *gh; - uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; - - hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ - if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; - - t0 = nbuckets = gh->gh_nbuckets; - t1 = gh->gh_symndx; - t2 = maskwords = gh->gh_maskwords; - t3 = gh->gh_shift2; - - src += sizeof(Elf_GNU_Hash_Header); - srcsz -= sizeof(Elf_GNU_Hash_Header); - dsz -= hdrsz; - - sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * - sizeof(uint64_t); - - if (srcsz < sz || dsz < sz) - return (0); - - /* Write out the header. */ - if (byteswap) { - SWAP_WORD(t0); - SWAP_WORD(t1); - SWAP_WORD(t2); - SWAP_WORD(t3); - } - - WRITE_WORD(dst, t0); - WRITE_WORD(dst, t1); - WRITE_WORD(dst, t2); - WRITE_WORD(dst, t3); - - /* Copy the bloom filter and the hash table. */ - s64 = (uint64_t *) (uintptr_t) src; - for (n = 0; n < maskwords; n++) { - t64 = *s64++; - if (byteswap) - SWAP_XWORD(t64); - WRITE_WORD64(dst, t64); - } - - s32 = (uint32_t *) s64; - for (n = 0; n < nbuckets; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - srcsz -= sz; - dsz -= sz; - - /* Copy out the hash chains. */ - if (dsz < srcsz) - return (0); - - nchains = srcsz / sizeof(uint32_t); - for (n = 0; n < nchains; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - return (1); -} -#endif - -/* - * Elf_Note structures comprise a fixed size header followed by variable - * length strings. The fixed size header needs to be byte swapped, but - * not the strings. - * - * Argument `count' denotes the total number of bytes to be converted. - * The destination buffer needs to be at least `count' bytes in size. - */ -static int -libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz, hdrsz; - - if (dsz < count) /* Destination buffer is too small. */ - return (0); - - hdrsz = 3 * sizeof(uint32_t); - if (count < hdrsz) /* Source too small. */ - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - /* Process all notes in the section. */ - while (count > hdrsz) { - /* Read the note header. */ - READ_WORD(src, namesz); - READ_WORD(src, descsz); - READ_WORD(src, type); - - /* Translate. */ - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - /* Copy out the translated note header. */ - en = (Elf_Note *) (uintptr_t) dst; - en->n_namesz = namesz; - en->n_descsz = descsz; - en->n_type = type; - - dsz -= sizeof(Elf_Note); - dst += sizeof(Elf_Note); - count -= hdrsz; - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz || dsz < sz) /* Buffers are too small. */ - return (0); - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - - count -= sz; - dsz -= sz; - } - - return (1); -} - -static int -libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz; - - if (dsz < count) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - while (count > sizeof(Elf_Note)) { - - en = (Elf_Note *) (uintptr_t) src; - namesz = en->n_namesz; - descsz = en->n_descsz; - type = en->n_type; - - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - WRITE_WORD(dst, namesz); - WRITE_WORD(dst, descsz); - WRITE_WORD(dst, type); - - src += sizeof(Elf_Note); - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz) - sz = count; - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - count -= sz; - } - - return (1); -} - -struct converters { - int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); -}; - -divert(-1) -define(`CONV', - `ifdef(`IGNORE_'$1$2, - `.$3$2 = NULL', - `ifdef(`BASE_'$1, - `.$3$2 = libelf_cvt_$1_$3', - `ifdef(`SIZEDEP_'$1, - `.$3$2 = libelf_cvt_$1$2_$3', - `.$3$2 = libelf_cvt$2_$1_$3')')')') - -define(`CONVERTER_NAME', - `ifdef(`IGNORE_'$1,`', - `#if __FreeBSD_version >= $3 - [ELF_T_$1] = { - CONV($1,32,tof), CONV($1,32,tom), - CONV($1,64,tof), CONV($1,64,tom) }, -#endif -')') - -define(`CONVERTER_NAMES', - `ifelse($#,1,`', - `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') - -undefine(`IGNORE_BYTE32', `IGNORE_BYTE64') -divert(0) - -static struct converters cvt[ELF_T_NUM] = { -CONVERTER_NAMES(ELF_TYPE_LIST) - - /* - * Types that needs hand-coded converters follow. - */ - - [ELF_T_BYTE] = { - .tof32 = libelf_cvt_BYTE_tox, - .tom32 = libelf_cvt_BYTE_tox, - .tof64 = libelf_cvt_BYTE_tox, - .tom64 = libelf_cvt_BYTE_tox - }, - -#if __FreeBSD_version >= 800062 - [ELF_T_GNUHASH] = { - .tof32 = libelf_cvt32_GNUHASH_tof, - .tom32 = libelf_cvt32_GNUHASH_tom, - .tof64 = libelf_cvt64_GNUHASH_tof, - .tom64 = libelf_cvt64_GNUHASH_tom - }, -#endif - - [ELF_T_NOTE] = { - .tof32 = libelf_cvt_NOTE_tof, - .tom32 = libelf_cvt_NOTE_tom, - .tof64 = libelf_cvt_NOTE_tof, - .tom64 = libelf_cvt_NOTE_tom - } -}; - -int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) -{ - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (t >= ELF_T_NUM || - (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || - (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) - return (NULL); - - return ((elfclass == ELFCLASS32) ? - (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : - (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); -} diff --git a/lib/libelf/libelf_data.c b/lib/libelf/libelf_data.c deleted file mode 100644 index 17808ef..0000000 --- a/lib/libelf/libelf_data.c +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -int -_libelf_xlate_shtype(uint32_t sht) -{ - switch (sht) { - case SHT_DYNAMIC: - return (ELF_T_DYN); - case SHT_DYNSYM: - return (ELF_T_SYM); - case SHT_FINI_ARRAY: - return (ELF_T_ADDR); -#if __FreeBSD_version >= 800062 - case SHT_GNU_HASH: - return (ELF_T_GNUHASH); -#endif - case SHT_GROUP: - return (ELF_T_WORD); - case SHT_HASH: - return (ELF_T_WORD); - case SHT_INIT_ARRAY: - return (ELF_T_ADDR); - case SHT_NOBITS: - return (ELF_T_BYTE); - case SHT_NOTE: - return (ELF_T_NOTE); - case SHT_PREINIT_ARRAY: - return (ELF_T_ADDR); - case SHT_PROGBITS: - return (ELF_T_BYTE); - case SHT_REL: - return (ELF_T_REL); - case SHT_RELA: - return (ELF_T_RELA); - case SHT_STRTAB: - return (ELF_T_BYTE); - case SHT_SYMTAB: - return (ELF_T_SYM); - case SHT_SYMTAB_SHNDX: - return (ELF_T_WORD); -#if __FreeBSD_version >= 700025 - case SHT_GNU_verdef: /* == SHT_SUNW_verdef */ - return (ELF_T_VDEF); - case SHT_GNU_verneed: /* == SHT_SUNW_verneed */ - return (ELF_T_VNEED); - case SHT_GNU_versym: /* == SHT_SUNW_versym */ - return (ELF_T_HALF); - case SHT_SUNW_move: - return (ELF_T_MOVE); - case SHT_SUNW_syminfo: - return (ELF_T_SYMINFO); - case SHT_SUNW_dof: - return (ELF_T_BYTE); -#endif - case SHT_ARM_PREEMPTMAP: - /* FALLTHROUGH */ - case SHT_ARM_ATTRIBUTES: - /* FALLTHROUGH */ - case SHT_ARM_DEBUGOVERLAY: - /* FALLTHROUGH */ - case SHT_ARM_OVERLAYSECTION: - /* FALLTHROUGH */ - case SHT_MIPS_DWARF: - /* FALLTHROUGH */ - case SHT_MIPS_REGINFO: - /* FALLTHROUGH */ - case SHT_MIPS_OPTIONS: - /* FALLTHROUGH */ - case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND == SHT_ARM_EXIDX */ - return (ELF_T_BYTE); - default: - return (-1); - } -} diff --git a/lib/libelf/libelf_ehdr.c b/lib/libelf/libelf_ehdr.c deleted file mode 100644 index 3b83f2c..0000000 --- a/lib/libelf/libelf_ehdr.c +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <gelf.h> -#include <libelf.h> -#include <stdlib.h> - -#include "_libelf.h" - -/* - * Retrieve counts for sections, phdrs and the section string table index - * from section header #0 of the ELF object. - */ -static int -_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, - uint16_t strndx) -{ - Elf_Scn *scn; - size_t fsz; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - uint32_t shtype; - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); - assert(fsz > 0); - - if (e->e_rawsize < shoff + fsz) { /* raw file too small */ - LIBELF_SET_ERROR(HEADER, 0); - return (0); - } - - if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) - return (0); - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), - e->e_rawfile + shoff, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - -#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ - scn->s_shdr.s_shdr64.M) - - if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); - e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : - GET_SHDR_MEMBER(sh_info); - e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : - GET_SHDR_MEMBER(sh_link); -#undef GET_SHDR_MEMBER - - return (1); -} - -#define EHDR_INIT(E,SZ) do { \ - Elf##SZ##_Ehdr *eh = (E); \ - eh->e_ident[EI_MAG0] = ELFMAG0; \ - eh->e_ident[EI_MAG1] = ELFMAG1; \ - eh->e_ident[EI_MAG2] = ELFMAG2; \ - eh->e_ident[EI_MAG3] = ELFMAG3; \ - eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ - eh->e_ident[EI_DATA] = ELFDATANONE; \ - eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ - eh->e_machine = EM_NONE; \ - eh->e_type = ELF_K_NONE; \ - eh->e_version = LIBELF_PRIVATE(version); \ - } while (0) - -void * -_libelf_ehdr(Elf *e, int ec, int allocate) -{ - void *ehdr; - size_t fsz, msz; - uint16_t phnum, shnum, strndx; - uint64_t shoff; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (e->e_class != ELFCLASSNONE && e->e_class != ec) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if (e->e_version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (NULL); - } - - if (e->e_class == ELFCLASSNONE) - e->e_class = ec; - - if (ec == ELFCLASS32) - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr != NULL) /* already have a translated ehdr */ - return (ehdr); - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((ehdr = calloc((size_t) 1, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; - EHDR_INIT(ehdr,32); - } else { - e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; - EHDR_INIT(ehdr,64); - } - - if (allocate) - e->e_flags |= ELF_F_DIRTY; - - if (e->e_cmd == ELF_C_WRITE) - return (ehdr); - - xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); - (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - /* - * If extended numbering is being used, read the correct - * number of sections and program header entries. - */ - if (ec == ELFCLASS32) { - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; - } else { - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; - } - - if (shnum >= SHN_LORESERVE || - (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || - strndx == SHN_XINDEX))) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ - e->e_u.e_elf.e_nphdr = phnum; - e->e_u.e_elf.e_nscn = shnum; - e->e_u.e_elf.e_strndx = strndx; - } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) - return (NULL); - - return (ehdr); -} diff --git a/lib/libelf/libelf_extended.c b/lib/libelf/libelf_extended.c deleted file mode 100644 index 6e45d81..0000000 --- a/lib/libelf/libelf_extended.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <libelf.h> - -#include "_libelf.h" - -/* - * Retrieve section #0, allocating a new section if needed. - */ -static Elf_Scn * -_libelf_getscn0(Elf *e) -{ - Elf_Scn *s; - - if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) - return (s); - - return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); -} - -int -_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) -{ - Elf_Scn *scn; - - if (shnum >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_size = shnum; - else - scn->s_shdr.s_shdr64.sh_size = shnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shnum = 0; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shnum = shnum; - else - ((Elf64_Ehdr *) eh)->e_shnum = shnum; - - - return (1); -} - -int -_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) -{ - Elf_Scn *scn; - - if (shstrndx >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_link = shstrndx; - else - scn->s_shdr.s_shdr64.sh_link = shstrndx; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shstrndx = SHN_XINDEX; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; - else - ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; - - return (1); -} - -int -_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) -{ - Elf_Scn *scn; - - if (phnum >= PN_XNUM) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_info = phnum; - else - scn->s_shdr.s_shdr64.sh_info = phnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - phnum = PN_XNUM; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_phnum = phnum; - else - ((Elf64_Ehdr *) eh)->e_phnum = phnum; - - return (1); -} - diff --git a/lib/libelf/libelf_fsize.m4 b/lib/libelf/libelf_fsize.m4 deleted file mode 100644 index 1cea997..0000000 --- a/lib/libelf/libelf_fsize.m4 +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <libelf.h> -#include <osreldate.h> - -#include "_libelf.h" - -/* - * Create an array of file sizes from the elf_type definitions - */ - -divert(-1) -include(SRCDIR`/elf_types.m4') - -/* - * Translations from structure definitions to the size of their file - * representations. - */ - -/* `Basic' types. */ -define(`BYTE_SIZE', 1) -define(`IDENT_SIZE', `EI_NIDENT') - -/* Types that have variable length. */ -define(`GNUHASH_SIZE', 1) -define(`NOTE_SIZE', 1) - -/* Currently unimplemented types. */ -define(`MOVEP_SIZE', 0) - -/* Overrides for 32 bit types that do not exist. */ -define(`XWORD_SIZE32', 0) -define(`SXWORD_SIZE32', 0) - -/* - * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. - */ - -define(`FSZ32',`_FSZ32($1_DEF)') -define(`_FSZ32', - `ifelse($#,1,0, - `_BSZ32($1)+_FSZ32(shift($@))')') -define(`_BSZ32',`$2_SIZE32') - -define(`FSZ64',`_FSZ64($1_DEF)') -define(`_FSZ64', - `ifelse($#,1,0, - `_BSZ64($1)+_FSZ64(shift($@))')') -define(`_BSZ64',`$2_SIZE64') - -/* - * DEFINE_ELF_FSIZES(TYPE,NAME) - * - * Shorthand for defining for 32 and 64 versions - * of elf type TYPE. - * - * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit - * sizes. - * - * Otherwise, look for a explicit 32/64 bit size definition for TYPE, - * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there - * is nothing further to do. - * - * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, - * compute an expression that adds up the sizes of the structure's - * constituents. - * - * If such a structure definition is not known, treat TYPE as a primitive - * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its - * file representation size. - */ - -define(`DEFINE_ELF_FSIZE', - `ifdef($1`_SIZE', - `define($1_SIZE32,$1_SIZE) - define($1_SIZE64,$1_SIZE)', - `ifdef($1`_SIZE32',`', - `ifdef(`Elf32_'$2`_DEF', - `define($1_SIZE32,FSZ32(Elf32_$2))', - `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') - ifdef($1`_SIZE64',`', - `ifdef(`Elf64_'$2`_DEF', - `define($1_SIZE64,FSZ64(Elf64_$2))', - `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') - -define(`DEFINE_ELF_FSIZES', - `ifelse($#,1,`', - `DEFINE_ELF_FSIZE($1) - DEFINE_ELF_FSIZES(shift($@))')') - -DEFINE_ELF_FSIZES(ELF_TYPE_LIST) -DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type - -define(`FSIZE', - `#if __FreeBSD_version >= $3 - [ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, -#endif') -define(`FSIZES', - `ifelse($#,1,`', - `FSIZE($1) -FSIZES(shift($@))')') - -divert(0) - -struct fsize { - size_t fsz32; - size_t fsz64; -}; - -static struct fsize fsize[ELF_T_NUM] = { -FSIZES(ELF_TYPE_LIST) -}; - -size_t -_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) -{ - size_t sz; - - sz = 0; - if (v != EV_CURRENT) - LIBELF_SET_ERROR(VERSION, 0); - else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) - LIBELF_SET_ERROR(ARGUMENT, 0); - else { - sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; - if (sz == 0) - LIBELF_SET_ERROR(UNIMPL, 0); - } - - return (sz*c); -} - diff --git a/lib/libelf/libelf_msize.m4 b/lib/libelf/libelf_msize.m4 deleted file mode 100644 index 6ae6a485..0000000 --- a/lib/libelf/libelf_msize.m4 +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/elf32.h> -#include <sys/elf64.h> - -#include <assert.h> -#include <libelf.h> -#include <osreldate.h> -#include <string.h> - -#include "_libelf.h" - -/* WARNING: GENERATED FROM __file__. */ - -struct msize { - size_t msz32; - size_t msz64; -}; - -divert(-1) -include(SRCDIR`/elf_types.m4') - -define(BYTE_SIZE, 1) -define(GNUHASH_SIZE, 1) -define(NOTE_SIZE, 1) - -/* - * Unimplemented types. - */ -define(MOVEP_SIZE, 0) -define(SXWORD_SIZE32, 0) -define(XWORD_SIZE32, 0) - -define(`DEFINE_ELF_MSIZE', - `ifdef($1`_SIZE', - `define($1_SIZE32,$1_SIZE) - define($1_SIZE64,$1_SIZE)', - `ifdef($1`_SIZE32',`', - `define($1_SIZE32,sizeof(Elf32_$2))') - ifdef($1`_SIZE64',`', - `define($1_SIZE64,sizeof(Elf64_$2))')')') -define(`DEFINE_ELF_MSIZES', - `ifelse($#,1,`', - `DEFINE_ELF_MSIZE($1) - DEFINE_ELF_MSIZES(shift($@))')') - -DEFINE_ELF_MSIZES(ELF_TYPE_LIST) - -define(`MSIZE', - `#if __FreeBSD_version >= $3 - [ELF_T_$1] = { .msz32 = $1_SIZE32, .msz64 = $1_SIZE64 }, -#endif') -define(`MSIZES', - `ifelse($#,1,`', - `MSIZE($1) -MSIZES(shift($@))')') - -divert(0) - -static struct msize msize[ELF_T_NUM] = { -MSIZES(ELF_TYPE_LIST) -}; - -size_t -_libelf_msize(Elf_Type t, int elfclass, unsigned int version) -{ - size_t sz; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); - - if (version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - - sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; - - return (sz); -} diff --git a/lib/libelf/libelf_phdr.c b/lib/libelf/libelf_phdr.c deleted file mode 100644 index ed3f650..0000000 --- a/lib/libelf/libelf_phdr.c +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <gelf.h> -#include <libelf.h> -#include <stdlib.h> - -#include "_libelf.h" - -void * -_libelf_getphdr(Elf *e, int ec) -{ - size_t phnum, phentsize; - size_t fsz, msz; - uint64_t phoff; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - void *ehdr, *phdr; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((phdr = (ec == ELFCLASS32 ? - (void *) e->e_u.e_elf.e_phdr.e_phdr32 : - (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) - return (phdr); - - /* - * Check the PHDR related fields in the EHDR for sanity. - */ - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - phnum = e->e_u.e_elf.e_nphdr; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - phentsize = eh32->e_phentsize; - phoff = (uint64_t) eh32->e_phoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - phentsize = eh64->e_phentsize; - phoff = (uint64_t) eh64->e_phoff; - } - - fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); - - assert(fsz > 0); - - if ((uint64_t) e->e_rawsize < (phoff + fsz)) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((phdr = calloc(phnum, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) - e->e_u.e_elf.e_phdr.e_phdr32 = phdr; - else - e->e_u.e_elf.e_phdr.e_phdr64 = phdr; - - - xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec); - (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - return (phdr); -} - -void * -_libelf_newphdr(Elf *e, int ec, size_t count) -{ - void *ehdr, *newphdr, *oldphdr; - size_t msz; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - assert(e->e_class == ec); - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - assert(e->e_version == EV_CURRENT); - - msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version); - - assert(msz > 0); - - newphdr = NULL; - if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; - } else { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; - } - - e->e_u.e_elf.e_nphdr = count; - - elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - return (newphdr); -} diff --git a/lib/libelf/libelf_shdr.c b/lib/libelf/libelf_shdr.c deleted file mode 100644 index 853cc90..0000000 --- a/lib/libelf/libelf_shdr.c +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <gelf.h> -#include <libelf.h> - -#include "_libelf.h" - -void * -_libelf_getshdr(Elf_Scn *s, int ec) -{ - Elf *e; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASSNONE) - ec = e->e_class; - - if (ec != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - return ((void *) &s->s_shdr); -} diff --git a/lib/libelf/libelf_xlate.c b/lib/libelf/libelf_xlate.c deleted file mode 100644 index 5137b2c..0000000 --- a/lib/libelf/libelf_xlate.c +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * Copyright (c) 2006 Joseph Koshy - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <assert.h> -#include <libelf.h> - -#include "_libelf.h" - -/* - * Translate to/from the file representation of ELF objects. - * - * Translation could potentially involve the following - * transformations: - * - * - an endianness conversion, - * - a change of layout, as the file representation of ELF objects - * can differ from their in-memory representation. - * - a change in representation due to a layout version change. - */ - -Elf_Data * -_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, - int elfclass, int direction) -{ - int byteswap; - size_t cnt, dsz, fsz, msz; - uintptr_t sb, se, db, de; - - if (encoding == ELFDATANONE) - encoding = LIBELF_PRIVATE(byteorder); - - if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || - dst == NULL || src == NULL || dst == src) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (dst->d_version != src->d_version) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (src->d_buf == NULL || dst->d_buf == NULL) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (src->d_type, (size_t) 1, src->d_version)) == 0) - return (NULL); - - msz = _libelf_msize(src->d_type, elfclass, src->d_version); - - assert(msz > 0); - - if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - /* - * Determine the number of objects that need to be converted, and - * the space required for the converted objects in the destination - * buffer. - */ - if (direction == ELF_TOMEMORY) { - cnt = src->d_size / fsz; - dsz = cnt * msz; - } else { - cnt = src->d_size / msz; - dsz = cnt * fsz; - } - - if (dst->d_size < dsz) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - sb = (uintptr_t) src->d_buf; - se = sb + src->d_size; - db = (uintptr_t) dst->d_buf; - de = db + dst->d_size; - - /* - * Check for overlapping buffers. Note that db == sb is - * allowed. - */ - if (db != sb && de > sb && se > db) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((direction == ELF_TOMEMORY ? db : sb) % - _libelf_malign(src->d_type, elfclass)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - dst->d_type = src->d_type; - dst->d_size = dsz; - - byteswap = encoding != LIBELF_PRIVATE(byteorder); - - if (src->d_size == 0 || - (db == sb && !byteswap && fsz == msz)) - return (dst); /* nothing more to do */ - - if (!(_libelf_get_translator(src->d_type, direction, elfclass)) - (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - return (dst); -} diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 15d5a25..5cc7e26 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998-2011 Dag-Erling Smørgrav + * Copyright (c) 1998-2014 Dag-Erling Smørgrav * Copyright (c) 2013 Michael Gmelin <freebsd@grem.de> * All rights reserved. * @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <netdb.h> +#include <poll.h> #include <pwd.h> #include <stdarg.h> #include <stdlib.h> @@ -641,7 +642,7 @@ fetch_ssl_verify_hname(X509 *cert, const char *host) struct addrinfo *ip; STACK_OF(GENERAL_NAME) *altnames; X509_NAME *subject; - int ret; + int ret; ret = 0; ip = fetch_ssl_get_numeric_addrinfo(host, strlen(host)); @@ -679,7 +680,7 @@ fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose) if (getenv("SSL_NO_TLS1") != NULL) ssl_ctx_options |= SSL_OP_NO_TLSv1; if (verbose) - fetch_info("SSL options: %x", ssl_ctx_options); + fetch_info("SSL options: %lx", ssl_ctx_options); SSL_CTX_set_options(ctx, ssl_ctx_options); } @@ -829,6 +830,16 @@ fetch_ssl(conn_t *conn, const struct url *URL, int verbose) return (-1); } SSL_set_fd(conn->ssl, conn->sd); + +#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) + if (!SSL_set_tlsext_host_name(conn->ssl, + __DECONST(struct url *, URL)->host)) { + fprintf(stderr, + "TLS server name indication extension failed for host %s\n", + URL->host); + return (-1); + } +#endif while ((ret = SSL_connect(conn->ssl)) == -1) { ssl_err = SSL_get_error(conn->ssl, ret); if (ssl_err != SSL_ERROR_WANT_READ && @@ -903,33 +914,6 @@ fetch_ssl_read(SSL *ssl, char *buf, size_t len) } #endif -/* - * Cache some data that was read from a socket but cannot be immediately - * returned because of an interrupted system call. - */ -static int -fetch_cache_data(conn_t *conn, char *src, size_t nbytes) -{ - char *tmp; - - if (conn->cache.size < nbytes) { - tmp = realloc(conn->cache.buf, nbytes); - if (tmp == NULL) { - fetch_syserr(); - return (-1); - } - conn->cache.buf = tmp; - conn->cache.size = nbytes; - } - - memcpy(conn->cache.buf, src, nbytes); - conn->cache.len = nbytes; - conn->cache.pos = 0; - - return (0); -} - - static ssize_t fetch_socket_read(int sd, char *buf, size_t len) { @@ -952,46 +936,31 @@ ssize_t fetch_read(conn_t *conn, char *buf, size_t len) { struct timeval now, timeout, delta; - fd_set readfds; - ssize_t rlen, total; - char *start; + struct pollfd pfd; + ssize_t rlen; + int deltams; if (fetchTimeout > 0) { gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } - total = 0; - start = buf; + deltams = INFTIM; + memset(&pfd, 0, sizeof pfd); + pfd.fd = conn->sd; + pfd.events = POLLIN | POLLERR; - if (conn->cache.len > 0) { - /* - * The last invocation of fetch_read was interrupted by a - * signal after some data had been read from the socket. Copy - * the cached data into the supplied buffer before trying to - * read from the socket again. - */ - total = (conn->cache.len < len) ? conn->cache.len : len; - memcpy(buf, conn->cache.buf, total); - - conn->cache.len -= total; - conn->cache.pos += total; - len -= total; - buf += total; - } - - while (len > 0) { + for (;;) { /* * The socket is non-blocking. Instead of the canonical - * select() -> read(), we do the following: + * poll() -> read(), we do the following: * * 1) call read() or SSL_read(). - * 2) if an error occurred, return -1. - * 3) if we received data but we still expect more, - * update our counters and loop. + * 2) if we received some data, return it. + * 3) if an error occurred, return -1. * 4) if read() or SSL_read() signaled EOF, return. * 5) if we did not receive any data but we're not at EOF, - * call select(). + * call poll(). * * In the SSL case, this is necessary because if we * receive a close notification, we have to call @@ -1007,46 +976,34 @@ fetch_read(conn_t *conn, char *buf, size_t len) else #endif rlen = fetch_socket_read(conn->sd, buf, len); - if (rlen == 0) { + if (rlen >= 0) { break; - } else if (rlen > 0) { - len -= rlen; - buf += rlen; - total += rlen; - continue; } else if (rlen == FETCH_READ_ERROR) { - if (errno == EINTR) - fetch_cache_data(conn, start, total); + fetch_syserr(); return (-1); } // assert(rlen == FETCH_READ_WAIT); - FD_ZERO(&readfds); - while (!FD_ISSET(conn->sd, &readfds)) { - FD_SET(conn->sd, &readfds); - if (fetchTimeout > 0) { - gettimeofday(&now, NULL); - if (!timercmp(&timeout, &now, >)) { - errno = ETIMEDOUT; - fetch_syserr(); - return (-1); - } - timersub(&timeout, &now, &delta); - } - errno = 0; - if (select(conn->sd + 1, &readfds, NULL, NULL, - fetchTimeout > 0 ? &delta : NULL) < 0) { - if (errno == EINTR) { - if (fetchRestartCalls) - continue; - /* Save anything that was read. */ - fetch_cache_data(conn, start, total); - } + if (fetchTimeout > 0) { + gettimeofday(&now, NULL); + if (!timercmp(&timeout, &now, >)) { + errno = ETIMEDOUT; fetch_syserr(); return (-1); } + timersub(&timeout, &now, &delta); + deltams = delta.tv_sec * 1000 + + delta.tv_usec / 1000;; + } + errno = 0; + pfd.revents = 0; + if (poll(&pfd, 1, deltams) < 0) { + if (errno == EINTR && fetchRestartCalls) + continue; + fetch_syserr(); + return (-1); } } - return (total); + return (rlen); } @@ -1120,35 +1077,33 @@ ssize_t fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt) { struct timeval now, timeout, delta; - fd_set writefds; + struct pollfd pfd; ssize_t wlen, total; - int r; + int deltams; + memset(&pfd, 0, sizeof pfd); if (fetchTimeout) { - FD_ZERO(&writefds); + pfd.fd = conn->sd; + pfd.events = POLLOUT | POLLERR; gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } total = 0; while (iovcnt > 0) { - while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) { - FD_SET(conn->sd, &writefds); + while (fetchTimeout && pfd.revents == 0) { gettimeofday(&now, NULL); - delta.tv_sec = timeout.tv_sec - now.tv_sec; - delta.tv_usec = timeout.tv_usec - now.tv_usec; - if (delta.tv_usec < 0) { - delta.tv_usec += 1000000; - delta.tv_sec--; - } - if (delta.tv_sec < 0) { + if (!timercmp(&timeout, &now, >)) { errno = ETIMEDOUT; fetch_syserr(); return (-1); } + timersub(&timeout, &now, &delta); + deltams = delta.tv_sec * 1000 + + delta.tv_usec / 1000; errno = 0; - r = select(conn->sd + 1, NULL, &writefds, NULL, &delta); - if (r == -1) { + pfd.revents = 0; + if (poll(&pfd, 1, deltams) < 0) { if (errno == EINTR && fetchRestartCalls) continue; return (-1); @@ -1240,7 +1195,6 @@ fetch_close(conn_t *conn) } #endif ret = close(conn->sd); - free(conn->cache.buf); free(conn->buf); free(conn); return (ret); diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index 1d543a6..875eef1 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998-2011 Dag-Erling Smørgrav + * Copyright (c) 1998-2014 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,13 +52,6 @@ struct fetchconn { size_t bufsize; /* buffer size */ size_t buflen; /* length of buffer contents */ int err; /* last protocol reply code */ - struct { /* data cached after an interrupted - read */ - char *buf; - size_t size; - size_t pos; - size_t len; - } cache; #ifdef WITH_SSL SSL *ssl; /* SSL handle */ SSL_CTX *ssl_ctx; /* SSL context */ diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 87535f0..cbbb8a8 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2013 Dag-Erling Smørgrav + * Copyright (c) 2000-2014 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -204,10 +204,11 @@ http_growbuf(struct httpio *io, size_t len) /* * Fill the input buffer, do chunk decoding on the fly */ -static int +static ssize_t http_fillbuf(struct httpio *io, size_t len) { ssize_t nbytes; + char ch; if (io->error) return (-1); @@ -229,7 +230,7 @@ http_fillbuf(struct httpio *io, size_t len) if (io->chunksize == 0) { switch (http_new_chunk(io)) { case -1: - io->error = 1; + io->error = EPROTO; return (-1); case 0: io->eof = 1; @@ -249,10 +250,8 @@ http_fillbuf(struct httpio *io, size_t len) io->chunksize -= io->buflen; if (io->chunksize == 0) { - char endl[2]; - - if (fetch_read(io->conn, endl, 2) != 2 || - endl[0] != '\r' || endl[1] != '\n') + if (fetch_read(io->conn, &ch, 1) != 1 || ch != '\r' || + fetch_read(io->conn, &ch, 1) != 1 || ch != '\n') return (-1); } @@ -268,31 +267,30 @@ static int http_readfn(void *v, char *buf, int len) { struct httpio *io = (struct httpio *)v; - int l, pos; + int rlen; if (io->error) return (-1); if (io->eof) return (0); - for (pos = 0; len > 0; pos += l, len -= l) { - /* empty buffer */ - if (!io->buf || io->bufpos == io->buflen) - if (http_fillbuf(io, len) < 1) - break; - l = io->buflen - io->bufpos; - if (len < l) - l = len; - memcpy(buf + pos, io->buf + io->bufpos, l); - io->bufpos += l; + /* empty buffer */ + if (!io->buf || io->bufpos == io->buflen) { + if ((rlen = http_fillbuf(io, len)) < 0) { + if ((errno = io->error) == EINTR) + io->error = 0; + return (-1); + } else if (rlen == 0) { + return (0); + } } - if (!pos && io->error) { - if (io->error == EINTR) - io->error = 0; - return (-1); - } - return (pos); + rlen = io->buflen - io->bufpos; + if (len < rlen) + rlen = len; + memcpy(buf, io->buf + io->bufpos, rlen); + io->bufpos += rlen; + return (rlen); } /* @@ -878,6 +876,12 @@ http_parse_mtime(const char *p, time_t *mtime) strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); setlocale(LC_TIME, "C"); r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); + /* + * Some proxies use UTC in response, but it should still be + * parsed. RFC2616 states GMT and UTC are exactly equal for HTTP. + */ + if (r == NULL) + r = strptime(p, "%a, %d %b %Y %H:%M:%S UTC", &tm); /* XXX should add support for date-2 and date-3 */ setlocale(LC_TIME, locale); if (r == NULL) diff --git a/lib/libiconv_compat/Makefile b/lib/libiconv_compat/Makefile deleted file mode 100644 index 3d4483a..0000000 --- a/lib/libiconv_compat/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -LIB= iconv -SHLIB_MAJOR= 3 -SRCS= stub.c - -WARNS?= 0 - -.include <bsd.lib.mk> diff --git a/lib/libiconv_compat/Makefile.depend b/lib/libiconv_compat/Makefile.depend deleted file mode 100644 index 9547aa7..0000000 --- a/lib/libiconv_compat/Makefile.depend +++ /dev/null @@ -1,16 +0,0 @@ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/lib/libgcc \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/lib/libiconv_compat/stub.c b/lib/libiconv_compat/stub.c deleted file mode 100644 index b4e56a2..0000000 --- a/lib/libiconv_compat/stub.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Hacks to support things like the dlopen() in libkiconv.so or - * ports that want to hard-code -liconv. - * - * $FreeBSD$ - */ - -int __libiconv_stub__; diff --git a/lib/libiconv_modules/BIG5/Makefile b/lib/libiconv_modules/BIG5/Makefile index 0f755fc..cdaf9dd 100644 --- a/lib/libiconv_modules/BIG5/Makefile +++ b/lib/libiconv_modules/BIG5/Makefile @@ -2,6 +2,6 @@ SHLIB= BIG5 SRCS+= citrus_big5.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/BIG5/citrus_big5.c b/lib/libiconv_modules/BIG5/citrus_big5.c index 1d7d8f8..a8376eb 100644 --- a/lib/libiconv_modules/BIG5/citrus_big5.c +++ b/lib/libiconv_modules/BIG5/citrus_big5.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_big5.c,v 1.12 2008/06/14 16:01:07 tnozaki Exp $ */ +/* $NetBSD: citrus_big5.c,v 1.13 2011/05/23 14:53:46 joerg Exp $ */ /*- * Copyright (c)2002, 2006 Citrus Project, @@ -92,8 +92,8 @@ typedef struct { typedef struct _BIG5Exclude { TAILQ_ENTRY(_BIG5Exclude) entry; - wint_t end; wint_t start; + wint_t end; } _BIG5Exclude; typedef TAILQ_HEAD(_BIG5ExcludeList, _BIG5Exclude) _BIG5ExcludeList; @@ -123,6 +123,7 @@ _citrus_BIG5_init_state(_BIG5EncodingInfo * __restrict ei __unused, memset(s, 0, sizeof(*s)); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_BIG5_pack_state(_BIG5EncodingInfo * __restrict ei __unused, @@ -142,6 +143,7 @@ _citrus_BIG5_unpack_state(_BIG5EncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static __inline int _citrus_BIG5_check(_BIG5EncodingInfo *ei, unsigned int c) @@ -170,7 +172,7 @@ _citrus_BIG5_check_excludes(_BIG5EncodingInfo *ei, wint_t c) } static int -_citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s, +_citrus_BIG5_fill_rowcol(void * __restrict ctx, const char * __restrict s, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -189,7 +191,7 @@ _citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s, static int /*ARGSUSED*/ -_citrus_BIG5_fill_excludes(void ** __restrict ctx, +_citrus_BIG5_fill_excludes(void * __restrict ctx, const char * __restrict s __unused, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -235,7 +237,6 @@ static int _citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei, const void * __restrict var, size_t lenvar) { - void *ctx = (void *)ei; const char *s; int err; @@ -257,9 +258,9 @@ _citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei, } /* fallback Big5-1984, for backward compatibility. */ - _citrus_BIG5_fill_rowcol((void **)&ctx, "row", 0xA1, 0xFE); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0x40, 0x7E); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "row", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "col", 0x40, 0x7E); + _citrus_BIG5_fill_rowcol(ei, "col", 0xA1, 0xFE); return (0); } @@ -357,7 +358,7 @@ _citrus_BIG5_wcrtomb_priv(_BIG5EncodingInfo * __restrict ei, size_t n, wchar_t wc, _BIG5State * __restrict psenc __unused, size_t * __restrict nresult) { - unsigned char l; + size_t l; int ret; /* check invalid sequence */ diff --git a/lib/libiconv_modules/DECHanyu/citrus_dechanyu.c b/lib/libiconv_modules/DECHanyu/citrus_dechanyu.c index 9d1d394..fc32018 100644 --- a/lib/libiconv_modules/DECHanyu/citrus_dechanyu.c +++ b/lib/libiconv_modules/DECHanyu/citrus_dechanyu.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_dechanyu.c,v 1.3 2008/06/14 16:01:07 tnozaki Exp $ */ +/* $NetBSD: citrus_dechanyu.c,v 1.4 2011/11/19 18:20:13 tnozaki Exp $ */ /*- * Copyright (c)2007 Citrus Project, @@ -78,6 +78,7 @@ _citrus_DECHanyu_init_state(_DECHanyuEncodingInfo * __restrict ei __unused, psenc->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_DECHanyu_pack_state(_DECHanyuEncodingInfo * __restrict ei __unused, @@ -96,6 +97,7 @@ _citrus_DECHanyu_unpack_state(_DECHanyuEncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static void /*ARGSUSED*/ diff --git a/lib/libiconv_modules/EUC/Makefile b/lib/libiconv_modules/EUC/Makefile index 422aab3..aeceff4 100644 --- a/lib/libiconv_modules/EUC/Makefile +++ b/lib/libiconv_modules/EUC/Makefile @@ -2,6 +2,6 @@ SHLIB= EUC SRCS+= citrus_euc.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/EUC/citrus_euc.c b/lib/libiconv_modules/EUC/citrus_euc.c index c153bef..6483eb5 100644 --- a/lib/libiconv_modules/EUC/citrus_euc.c +++ b/lib/libiconv_modules/EUC/citrus_euc.c @@ -169,6 +169,7 @@ _citrus_EUC_init_state(_EUCEncodingInfo *ei __unused, _EUCState *s) memset(s, 0, sizeof(*s)); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_EUC_pack_state(_EUCEncodingInfo *ei __unused, void *pspriv, @@ -186,6 +187,7 @@ _citrus_EUC_unpack_state(_EUCEncodingInfo *ei __unused, _EUCState *s, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static int _citrus_EUC_mbrtowc_priv(_EUCEncodingInfo *ei, wchar_t *pwc, const char **s, diff --git a/lib/libiconv_modules/EUCTW/Makefile b/lib/libiconv_modules/EUCTW/Makefile index b85c035..4808ca3 100644 --- a/lib/libiconv_modules/EUCTW/Makefile +++ b/lib/libiconv_modules/EUCTW/Makefile @@ -2,6 +2,6 @@ SHLIB= EUCTW SRCS+= citrus_euctw.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/EUCTW/citrus_euctw.c b/lib/libiconv_modules/EUCTW/citrus_euctw.c index f1f8a49..c35423e 100644 --- a/lib/libiconv_modules/EUCTW/citrus_euctw.c +++ b/lib/libiconv_modules/EUCTW/citrus_euctw.c @@ -119,7 +119,7 @@ _citrus_EUCTW_count(int cs) case 1: /*FALLTHROUGH*/ case 2: - return (2^cs); + return (1 << cs); case 3: abort(); /*NOTREACHED*/ @@ -136,6 +136,7 @@ _citrus_EUCTW_init_state(_EUCTWEncodingInfo * __restrict ei __unused, memset(s, 0, sizeof(*s)); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_EUCTW_pack_state(_EUCTWEncodingInfo * __restrict ei __unused, @@ -153,6 +154,7 @@ _citrus_EUCTW_unpack_state(_EUCTWEncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static int /*ARGSUSED*/ diff --git a/lib/libiconv_modules/GBK2K/Makefile b/lib/libiconv_modules/GBK2K/Makefile index 28dc796..39b3947 100644 --- a/lib/libiconv_modules/GBK2K/Makefile +++ b/lib/libiconv_modules/GBK2K/Makefile @@ -2,6 +2,6 @@ SHLIB= GBK2K SRCS+= citrus_gbk2k.c -CFLAGS+= --param max-inline-insns-single=16 +CFLAGS.gcc+= --param max-inline-insns-single=16 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/GBK2K/citrus_gbk2k.c b/lib/libiconv_modules/GBK2K/citrus_gbk2k.c index 8da5c7c..50ea2da 100644 --- a/lib/libiconv_modules/GBK2K/citrus_gbk2k.c +++ b/lib/libiconv_modules/GBK2K/citrus_gbk2k.c @@ -80,6 +80,7 @@ _citrus_GBK2K_init_state(_GBK2KEncodingInfo * __restrict ei __unused, memset(s, 0, sizeof(*s)); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_GBK2K_pack_state(_GBK2KEncodingInfo * __restrict ei __unused, @@ -97,6 +98,7 @@ _citrus_GBK2K_unpack_state(_GBK2KEncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static __inline bool _mb_singlebyte(int c) diff --git a/lib/libiconv_modules/HZ/citrus_hz.c b/lib/libiconv_modules/HZ/citrus_hz.c index 9bc7a5b..f9eb006 100644 --- a/lib/libiconv_modules/HZ/citrus_hz.c +++ b/lib/libiconv_modules/HZ/citrus_hz.c @@ -65,8 +65,8 @@ typedef enum { } charset_t; typedef struct { - int end; int start; + int end; int width; } range_t; @@ -153,6 +153,7 @@ _citrus_HZ_init_state(_HZEncodingInfo * __restrict ei, psenc->inuse = INIT0(ei); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_HZ_pack_state(_HZEncodingInfo * __restrict ei __unused, @@ -170,6 +171,7 @@ _citrus_HZ_unpack_state(_HZEncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static int _citrus_HZ_mbrtowc_priv(_HZEncodingInfo * __restrict ei, @@ -503,12 +505,12 @@ _citrus_HZ_encoding_module_uninit(_HZEncodingInfo *ei) } static int -_citrus_HZ_parse_char(void **context, const char *name __unused, const char *s) +_citrus_HZ_parse_char(void *context, const char *name __unused, const char *s) { escape_t *escape; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; if (escape->ch != '\0') return (EINVAL); @@ -520,14 +522,14 @@ _citrus_HZ_parse_char(void **context, const char *name __unused, const char *s) } static int -_citrus_HZ_parse_graphic(void **context, const char *name, const char *s) +_citrus_HZ_parse_graphic(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; graphic_t *graphic; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; ei = (_HZEncodingInfo *)p[1]; graphic = malloc(sizeof(*graphic)); @@ -589,13 +591,13 @@ _CITRUS_PROP_HINT_END }; static int -_citrus_HZ_parse_escape(void **context, const char *name, const char *s) +_citrus_HZ_parse_escape(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; void *p[2]; - ei = (_HZEncodingInfo *)*context; + ei = (_HZEncodingInfo *)context; escape = malloc(sizeof(*escape)); if (escape == NULL) return (EINVAL); diff --git a/lib/libiconv_modules/ISO2022/Makefile b/lib/libiconv_modules/ISO2022/Makefile index 1e865ac..8eba7d3 100644 --- a/lib/libiconv_modules/ISO2022/Makefile +++ b/lib/libiconv_modules/ISO2022/Makefile @@ -2,6 +2,6 @@ SHLIB= ISO2022 SRCS+= citrus_iso2022.c -CFLAGS+= --param max-inline-insns-single=128 +CFLAGS.gcc+= --param max-inline-insns-single=128 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/ISO2022/citrus_iso2022.c b/lib/libiconv_modules/ISO2022/citrus_iso2022.c index 2ae8df6..3402ba8 100644 --- a/lib/libiconv_modules/ISO2022/citrus_iso2022.c +++ b/lib/libiconv_modules/ISO2022/citrus_iso2022.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_iso2022.c,v 1.19 2008/06/14 16:01:07 tnozaki Exp $ */ +/* $NetBSD: citrus_iso2022.c,v 1.20 2010/12/07 22:01:45 joerg Exp $ */ /*- * Copyright (c)1999, 2002 Citrus Project, @@ -78,9 +78,9 @@ #define CS96MULTI (3U) typedef struct { - unsigned char interm; - unsigned char final; unsigned char type; + unsigned char final; + unsigned char interm; unsigned char vers; } _ISO2022Charset; @@ -444,6 +444,7 @@ _citrus_ISO2022_init_state(_ISO2022EncodingInfo * __restrict ei, s->flags |= _ISO2022STATE_FLAG_INITIALIZED; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_ISO2022_pack_state(_ISO2022EncodingInfo * __restrict ei __unused, @@ -461,6 +462,7 @@ _citrus_ISO2022_unpack_state(_ISO2022EncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static int /*ARGSUSED*/ diff --git a/lib/libiconv_modules/JOHAB/Makefile b/lib/libiconv_modules/JOHAB/Makefile index b945445..6a11f73 100644 --- a/lib/libiconv_modules/JOHAB/Makefile +++ b/lib/libiconv_modules/JOHAB/Makefile @@ -2,6 +2,6 @@ SHLIB= JOHAB SRCS+= citrus_johab.c -CFLAGS+= --param max-inline-insns-single=16 +CFLAGS.gcc+= --param max-inline-insns-single=16 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/JOHAB/citrus_johab.c b/lib/libiconv_modules/JOHAB/citrus_johab.c index 0365379..a533a85 100644 --- a/lib/libiconv_modules/JOHAB/citrus_johab.c +++ b/lib/libiconv_modules/JOHAB/citrus_johab.c @@ -80,6 +80,7 @@ _citrus_JOHAB_init_state(_JOHABEncodingInfo * __restrict ei __unused, psenc->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_JOHAB_pack_state(_JOHABEncodingInfo * __restrict ei __unused, @@ -97,6 +98,7 @@ _citrus_JOHAB_unpack_state(_JOHABEncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static void /*ARGSUSED*/ diff --git a/lib/libiconv_modules/MSKanji/citrus_mskanji.c b/lib/libiconv_modules/MSKanji/citrus_mskanji.c index fc0f13f..8549699 100644 --- a/lib/libiconv_modules/MSKanji/citrus_mskanji.c +++ b/lib/libiconv_modules/MSKanji/citrus_mskanji.c @@ -130,6 +130,7 @@ _citrus_MSKanji_init_state(_MSKanjiEncodingInfo * __restrict ei __unused, s->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_MSKanji_pack_state(_MSKanjiEncodingInfo * __restrict ei __unused, @@ -147,6 +148,7 @@ _citrus_MSKanji_unpack_state(_MSKanjiEncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static int /*ARGSUSED*/ diff --git a/lib/libiconv_modules/Makefile.inc b/lib/libiconv_modules/Makefile.inc index 3b25374..51ae718 100644 --- a/lib/libiconv_modules/Makefile.inc +++ b/lib/libiconv_modules/Makefile.inc @@ -14,4 +14,4 @@ SHLIBDIR= /usr/lib/i18n SHLIBDIR= /usr/lib32/i18n .endif LIBDIR= ${SHLIBDIR} -NO_PROFILE= +MK_PROFILE= no diff --git a/lib/libiconv_modules/UES/Makefile b/lib/libiconv_modules/UES/Makefile index 972e496..dc8f2d9 100644 --- a/lib/libiconv_modules/UES/Makefile +++ b/lib/libiconv_modules/UES/Makefile @@ -2,6 +2,6 @@ SHLIB= UES SRCS+= citrus_ues.c -CFLAGS+= --param max-inline-insns-single=64 +CFLAGS.gcc+= --param max-inline-insns-single=64 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/UES/citrus_ues.c b/lib/libiconv_modules/UES/citrus_ues.c index 872cc1f..45f5416 100644 --- a/lib/libiconv_modules/UES/citrus_ues.c +++ b/lib/libiconv_modules/UES/citrus_ues.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_ues.c,v 1.1 2006/11/13 15:16:31 tnozaki Exp $ */ +/* $NetBSD: citrus_ues.c,v 1.3 2012/02/12 13:51:29 wiz Exp $ */ /*- * Copyright (c)2006 Citrus Project, @@ -75,6 +75,7 @@ _citrus_UES_init_state(_UESEncodingInfo * __restrict ei __unused, psenc->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_UES_pack_state(_UESEncodingInfo * __restrict ei __unused, @@ -92,6 +93,7 @@ _citrus_UES_unpack_state(_UESEncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static __inline int to_int(int ch) diff --git a/lib/libiconv_modules/UTF1632/Makefile b/lib/libiconv_modules/UTF1632/Makefile index 71e9f88..485d070 100644 --- a/lib/libiconv_modules/UTF1632/Makefile +++ b/lib/libiconv_modules/UTF1632/Makefile @@ -2,6 +2,6 @@ SHLIB= UTF1632 SRCS+= citrus_utf1632.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/UTF7/Makefile b/lib/libiconv_modules/UTF7/Makefile index 8bedb73..733cb26 100644 --- a/lib/libiconv_modules/UTF7/Makefile +++ b/lib/libiconv_modules/UTF7/Makefile @@ -2,6 +2,6 @@ SHLIB= UTF7 SRCS+= citrus_utf7.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/UTF7/citrus_utf7.c b/lib/libiconv_modules/UTF7/citrus_utf7.c index 925be6d..53f4f77 100644 --- a/lib/libiconv_modules/UTF7/citrus_utf7.c +++ b/lib/libiconv_modules/UTF7/citrus_utf7.c @@ -87,6 +87,7 @@ _citrus_UTF7_init_state(_UTF7EncodingInfo * __restrict ei __unused, memset((void *)s, 0, sizeof(*s)); } +#if 0 static __inline void /*ARGSUSED*/ _citrus_UTF7_pack_state(_UTF7EncodingInfo * __restrict ei __unused, @@ -104,6 +105,7 @@ _citrus_UTF7_unpack_state(_UTF7EncodingInfo * __restrict ei __unused, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -113,9 +115,9 @@ static const char base64[] = static const char direct[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" - "0123456789(),-./:?"; + "0123456789'(),-./:?"; -static const char option[] = "!\"#$%&';<=>@[]^_`{|}"; +static const char option[] = "!\"#$%&*;<=>@[]^_`{|}"; static const char spaces[] = " \t\r\n"; #define BASE64_BIT 6 @@ -165,6 +167,7 @@ _citrus_UTF7_mbtoutf16(_UTF7EncodingInfo * __restrict ei, *nresult = (size_t)-2; *s = s0; sv.chlen = psenc->chlen; + memcpy(sv.ch, psenc->ch, sizeof(sv.ch)); *psenc = sv; return (0); } @@ -202,6 +205,9 @@ _citrus_UTF7_mbtoutf16(_UTF7EncodingInfo * __restrict ei, goto ilseq; *u16 = (uint16_t)psenc->ch[i]; done = 1; + } else { + psenc->chlen--; + i--; } } else { psenc->cache = @@ -241,7 +247,6 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei, wchar_t * __restrict pwc, const char ** __restrict s, size_t n, _UTF7State * __restrict psenc, size_t * __restrict nresult) { - const char *s0; uint32_t u32; uint16_t hi, lo; size_t nr, siz; @@ -252,14 +257,13 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei, *nresult = (size_t)_ENCODING_IS_STATE_DEPENDENT; return (0); } - s0 = *s; if (psenc->surrogate) { - hi = (psenc->cache >> 2) & UTF16_MAX; + hi = (psenc->cache >> psenc->bits) & UTF16_MAX; if (hi < HISRG_MIN || hi > HISRG_MAX) return (EINVAL); siz = 0; } else { - err = _citrus_UTF7_mbtoutf16(ei, &hi, &s0, n, psenc, &nr); + err = _citrus_UTF7_mbtoutf16(ei, &hi, s, n, psenc, &nr); if (nr == (size_t)-1 || nr == (size_t)-2) { *nresult = nr; return (err); @@ -274,7 +278,7 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei, } psenc->surrogate = 1; } - err = _citrus_UTF7_mbtoutf16(ei, &lo, &s0, n, psenc, &nr); + err = _citrus_UTF7_mbtoutf16(ei, &lo, s, n, psenc, &nr); if (nr == (size_t)-1 || nr == (size_t)-2) { *nresult = nr; return (err); @@ -286,7 +290,6 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei, u32 = (hi << 10 | lo) + SRG_BASE; siz += nr; done: - *s = s0; if (pwc != NULL) *pwc = (wchar_t)u32; if (u32 == (uint32_t)0) { diff --git a/lib/libiconv_modules/UTF8/citrus_utf8.c b/lib/libiconv_modules/UTF8/citrus_utf8.c index cdbc53c..d7c78d3 100644 --- a/lib/libiconv_modules/UTF8/citrus_utf8.c +++ b/lib/libiconv_modules/UTF8/citrus_utf8.c @@ -156,6 +156,7 @@ _citrus_UTF8_init_state(_UTF8EncodingInfo *ei __unused, _UTF8State *s) s->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_UTF8_pack_state(_UTF8EncodingInfo *ei __unused, void *pspriv, @@ -173,6 +174,7 @@ _citrus_UTF8_unpack_state(_UTF8EncodingInfo *ei __unused, _UTF8State *s, memcpy((void *)s, pspriv, sizeof(*s)); } +#endif static int _citrus_UTF8_mbrtowc_priv(_UTF8EncodingInfo *ei, wchar_t *pwc, const char **s, diff --git a/lib/libiconv_modules/VIQR/citrus_viqr.c b/lib/libiconv_modules/VIQR/citrus_viqr.c index 20175a3..dddb0b0 100644 --- a/lib/libiconv_modules/VIQR/citrus_viqr.c +++ b/lib/libiconv_modules/VIQR/citrus_viqr.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_viqr.c,v 1.4 2008/06/14 16:01:08 tnozaki Exp $ */ +/* $NetBSD: citrus_viqr.c,v 1.5 2011/11/19 18:20:13 tnozaki Exp $ */ /*- * Copyright (c)2006 Citrus Project, @@ -230,6 +230,7 @@ _citrus_VIQR_init_state(_VIQREncodingInfo * __restrict ei __unused, psenc->chlen = 0; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_VIQR_pack_state(_VIQREncodingInfo * __restrict ei __unused, @@ -247,6 +248,7 @@ _citrus_VIQR_unpack_state(_VIQREncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static int _citrus_VIQR_mbrtowc_priv(_VIQREncodingInfo * __restrict ei, @@ -431,7 +433,6 @@ static int _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei, const void * __restrict var __unused, size_t lenvar __unused) { - const mnemonic_def_t *p; const char *s; size_t i, n; int errnum; @@ -455,7 +456,10 @@ _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei, return (errnum); } } - for (i = 0;; ++i) { + /* a + 1 < b + 1 here to silence gcc warning about unsigned < 0. */ + for (i = 0; i + 1 < mnemonic_ext_size + 1; ++i) { + const mnemonic_def_t *p; + p = &mnemonic_ext[i]; n = strlen(p->name); if (ei->mb_cur_max < n) diff --git a/lib/libiconv_modules/ZW/citrus_zw.c b/lib/libiconv_modules/ZW/citrus_zw.c index b9dc10b..097fcfe 100644 --- a/lib/libiconv_modules/ZW/citrus_zw.c +++ b/lib/libiconv_modules/ZW/citrus_zw.c @@ -85,6 +85,7 @@ _citrus_ZW_init_state(_ZWEncodingInfo * __restrict ei __unused, psenc->charset = NONE; } +#if 0 static __inline void /*ARGSUSED*/ _citrus_ZW_pack_state(_ZWEncodingInfo * __restrict ei __unused, @@ -102,6 +103,7 @@ _citrus_ZW_unpack_state(_ZWEncodingInfo * __restrict ei __unused, memcpy((void *)psenc, pspriv, sizeof(*psenc)); } +#endif static int _citrus_ZW_mbrtowc_priv(_ZWEncodingInfo * __restrict ei, diff --git a/lib/libiconv_modules/iconv_none/citrus_iconv_none.c b/lib/libiconv_modules/iconv_none/citrus_iconv_none.c index 76bb06f..967ee13 100644 --- a/lib/libiconv_modules/iconv_none/citrus_iconv_none.c +++ b/lib/libiconv_modules/iconv_none/citrus_iconv_none.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_iconv_none.c,v 1.2 2003/07/01 09:42:16 tshiozak Exp $ */ +/* $NetBSD: citrus_iconv_none.c,v 1.3 2011/05/23 14:45:44 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, diff --git a/lib/libiconv_modules/iconv_std/Makefile b/lib/libiconv_modules/iconv_std/Makefile index a873cfa..88d68aa 100644 --- a/lib/libiconv_modules/iconv_std/Makefile +++ b/lib/libiconv_modules/iconv_std/Makefile @@ -2,6 +2,6 @@ SHLIB= iconv_std SRCS+= citrus_iconv_std.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c index b30f099..7c9b064 100644 --- a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c +++ b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_iconv_std.c,v 1.15 2006/11/13 19:08:19 tnozaki Exp $ */ +/* $NetBSD: citrus_iconv_std.c,v 1.16 2012/02/12 13:51:29 wiz Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -543,6 +543,16 @@ _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, ret = do_conv(is, &csid, &idx); if (ret) { if (ret == E_NO_CORRESPONDING_CHAR) { + /* + * GNU iconv returns EILSEQ when no + * corresponding character in the output. + * Some software depends on this behavior + * though this is against POSIX specification. + */ + if (cv->cv_shared->ci_ilseq_invalid != 0) { + ret = EILSEQ; + goto err; + } inval++; szrout = 0; if ((((flags & _CITRUS_ICONV_F_HIDE_INVALID) == 0) && diff --git a/lib/libiconv_modules/mapper_parallel/Makefile b/lib/libiconv_modules/mapper_parallel/Makefile index 000c1cd..b79c3ad 100644 --- a/lib/libiconv_modules/mapper_parallel/Makefile +++ b/lib/libiconv_modules/mapper_parallel/Makefile @@ -4,6 +4,6 @@ SHLIB= mapper_parallel SRCS+= citrus_mapper_serial.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/mapper_serial/Makefile b/lib/libiconv_modules/mapper_serial/Makefile index 67d4bb0..0b5907b 100644 --- a/lib/libiconv_modules/mapper_serial/Makefile +++ b/lib/libiconv_modules/mapper_serial/Makefile @@ -2,6 +2,6 @@ SHLIB= mapper_serial SRCS+= citrus_mapper_serial.c -CFLAGS+= --param max-inline-insns-single=32 +CFLAGS.gcc+= --param max-inline-insns-single=32 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/mapper_std/Makefile b/lib/libiconv_modules/mapper_std/Makefile index 0d35e90..aa46ad2 100644 --- a/lib/libiconv_modules/mapper_std/Makefile +++ b/lib/libiconv_modules/mapper_std/Makefile @@ -2,6 +2,6 @@ SHLIB= mapper_std SRCS+= citrus_mapper_std.c -CFLAGS+= --param max-inline-insns-single=8 +CFLAGS.gcc+= --param max-inline-insns-single=8 .include <bsd.lib.mk> diff --git a/lib/libiconv_modules/mapper_std/citrus_mapper_std.c b/lib/libiconv_modules/mapper_std/citrus_mapper_std.c index bc75643..712e9b2 100644 --- a/lib/libiconv_modules/mapper_std/citrus_mapper_std.c +++ b/lib/libiconv_modules/mapper_std/citrus_mapper_std.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $NetBSD: citrus_mapper_std.c,v 1.8 2006/09/11 13:06:33 tnozaki Exp $ */ +/* $NetBSD: citrus_mapper_std.c,v 1.10 2011/11/19 18:48:39 tnozaki Exp $ */ /*- * Copyright (c)2003, 2006 Citrus Project, @@ -174,8 +174,11 @@ rowcol_parse_variable_compat(struct _citrus_mapper_std_rowcol *rc, n = be32toh(rcx->rcx_src_row_end); if (m + n > 0) { ret = set_linear_zone(lz, m, n); - if (ret != 0) + if (ret != 0) { + free(rc->rc_src_rowcol); + rc->rc_src_rowcol = NULL; return (ret); + } ++rc->rc_src_rowcol_len, ++lz; } m = be32toh(rcx->rcx_src_col_begin); diff --git a/lib/libiconv_modules/mapper_zone/Makefile b/lib/libiconv_modules/mapper_zone/Makefile index 287bc24..4bdeef6 100644 --- a/lib/libiconv_modules/mapper_zone/Makefile +++ b/lib/libiconv_modules/mapper_zone/Makefile @@ -2,6 +2,6 @@ SHLIB= mapper_zone SRCS+= citrus_mapper_zone.c -CFLAGS+= --param max-inline-insns-single=8 +CFLAGS.gcc+= --param max-inline-insns-single=8 .include <bsd.lib.mk> diff --git a/lib/libipsec/ipsec_dump_policy.c b/lib/libipsec/ipsec_dump_policy.c index 5ddad43..257bb09 100644 --- a/lib/libipsec/ipsec_dump_policy.c +++ b/lib/libipsec/ipsec_dump_policy.c @@ -199,6 +199,7 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound) break; case IPPROTO_TCP: proto = "tcp"; + break; default: __ipsec_errcode = EIPSEC_INVAL_PROTO; return NULL; diff --git a/lib/libipx/Makefile b/lib/libipx/Makefile deleted file mode 100644 index b816ba3..0000000 --- a/lib/libipx/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -LIB= ipx -SHLIBDIR?= /lib -SRCS= ipx_addr.c ipx_ntoa.c -MAN= ipx.3 -MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3 - -WARNS?= 2 - -.include <bsd.lib.mk> diff --git a/lib/libipx/Makefile.depend b/lib/libipx/Makefile.depend deleted file mode 100644 index 26cf195..0000000 --- a/lib/libipx/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/lib/libgcc \ - include \ - include/arpa \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/lib/libipx/ipx.3 b/lib/libipx/ipx.3 deleted file mode 100644 index ab6de2d..0000000 --- a/lib/libipx/ipx.3 +++ /dev/null @@ -1,125 +0,0 @@ -.\" Copyright (c) 1986, 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd June 4, 1993 -.Dt IPX 3 -.Os -.Sh NAME -.Nm ipx_addr , -.Nm ipx_ntoa -.Nd IPX address conversion routines -.Sh LIBRARY -.Lb libipx -.Sh SYNOPSIS -.In sys/types.h -.In netipx/ipx.h -.Ft struct ipx_addr -.Fn ipx_addr "const char *cp" -.Ft char * -.Fn ipx_ntoa "struct ipx_addr ipx" -.Sh DESCRIPTION -The routine -.Fn ipx_addr -interprets character strings representing -.Tn IPX -addresses, returning binary information suitable -for use in system calls. -The routine -.Fn ipx_ntoa -takes -.Tn IPX -addresses and returns -.Tn ASCII -strings representing the address in a -notation in common use: -.Bd -ragged -offset indent -<network number>.<host number>.<port number> -.Ed -.Pp -Trailing zero fields are suppressed, and each number is printed in hexadecimal, -in a format suitable for input to -.Fn ipx_addr . -Any fields lacking super-decimal digits will have a -trailing -.Ql H -appended. -.Pp -An effort has been made to ensure that -.Fn ipx_addr -be compatible with most formats in common use. -It will first separate an address into 1 to 3 fields using a single delimiter -chosen from -period -.Ql \&. , -colon -.Ql \&: -or pound-sign -.Ql \&# . -Each field is then examined for byte separators (colon or period). -If there are byte separators, each subfield separated is taken to be -a small hexadecimal number, and the entirety is taken as a network-byte-ordered -quantity to be zero extended in the high-network-order bytes. -Next, the field is inspected for hyphens, in which case -the field is assumed to be a number in decimal notation -with hyphens separating the millennia. -Next, the field is assumed to be a number: -It is interpreted -as hexadecimal if there is a leading -.Ql 0x -(as in C), -a trailing -.Ql H -(as in Mesa), or there are any super-decimal digits present. -It is interpreted as octal if there is a leading -.Ql 0 -and there are no super-octal digits. -Otherwise, it is converted as a decimal number. -.Sh RETURN VALUES -None. -(See -.Sx BUGS . ) -.Sh SEE ALSO -.\" .Xr ns 4 , -.Xr hosts 5 , -.Xr networks 5 -.Sh HISTORY -The precursor -.Fn ns_addr -and -.Fn ns_toa -functions appeared in -.Bx 4.3 . -.Sh BUGS -The string returned by -.Fn ipx_ntoa -resides in a static memory area. -The function -.Fn ipx_addr -should diagnose improperly formed input, and there should be an unambiguous -way to recognize this. diff --git a/lib/libipx/ipx_addr.c b/lib/libipx/ipx_addr.c deleted file mode 100644 index 6d48b59..0000000 --- a/lib/libipx/ipx_addr.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * J.Q. Johnson. - * - * 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ipx_addr.c"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <arpa/inet.h> -#include <netipx/ipx.h> -#include <stdio.h> -#include <string.h> - -static struct ipx_addr addr, zero_addr; - -static void Field(), cvtbase(); - -struct ipx_addr -ipx_addr(name) - const char *name; -{ - char separator; - char *hostname, *socketname, *cp; - char buf[50]; - - (void)strncpy(buf, name, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - /* - * First, figure out what he intends as a field separator. - * Despite the way this routine is written, the preferred - * form 2-272.AA001234H.01777, i.e. XDE standard. - * Great efforts are made to ensure backwards compatibility. - */ - if ( (hostname = strchr(buf, '#')) ) - separator = '#'; - else { - hostname = strchr(buf, '.'); - if ((cp = strchr(buf, ':')) && - ((hostname && cp < hostname) || (hostname == 0))) { - hostname = cp; - separator = ':'; - } else - separator = '.'; - } - if (hostname) - *hostname++ = 0; - - addr = zero_addr; - Field(buf, addr.x_net.c_net, 4); - if (hostname == 0) - return (addr); /* No separator means net only */ - - socketname = strchr(hostname, separator); - if (socketname) { - *socketname++ = 0; - Field(socketname, (u_char *)&addr.x_port, 2); - } - - Field(hostname, addr.x_host.c_host, 6); - - return (addr); -} - -static void -Field(buf, out, len) - char *buf; - u_char *out; - int len; -{ - char *bp = buf; - int i, ibase, base16 = 0, base10 = 0, clen = 0; - int hb[6], *hp; - char *fmt; - - /* - * first try 2-273#2-852-151-014#socket - */ - if ((*buf != '-') && - (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", - &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { - cvtbase(1000L, 256, hb, i, out, len); - return; - } - /* - * try form 8E1#0.0.AA.0.5E.E6#socket - */ - if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", - &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { - cvtbase(256L, 256, hb, i, out, len); - return; - } - /* - * try form 8E1#0:0:AA:0:5E:E6#socket - */ - if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", - &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { - cvtbase(256L, 256, hb, i, out, len); - return; - } - /* - * This is REALLY stretching it but there was a - * comma notation separating shorts -- definitely non-standard - */ - if (1 < (i = sscanf(buf,"%x,%x,%x", - &hb[0], &hb[1], &hb[2]))) { - hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); - hb[2] = htons(hb[2]); - cvtbase(65536L, 256, hb, i, out, len); - return; - } - - /* Need to decide if base 10, 16 or 8 */ - while (*bp) switch (*bp++) { - - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '-': - break; - - case '8': case '9': - base10 = 1; - break; - - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - base16 = 1; - break; - - case 'x': case 'X': - *--bp = '0'; - base16 = 1; - break; - - case 'h': case 'H': - base16 = 1; - /* FALLTHROUGH */ - - default: - *--bp = 0; /* Ends Loop */ - } - if (base16) { - fmt = "%3x"; - ibase = 4096; - } else if (base10 == 0 && *buf == '0') { - fmt = "%3o"; - ibase = 512; - } else { - fmt = "%3d"; - ibase = 1000; - } - - for (bp = buf; *bp++; ) clen++; - if (clen == 0) clen++; - if (clen > 18) clen = 18; - i = ((clen - 1) / 3) + 1; - bp = clen + buf - 3; - hp = hb + i - 1; - - while (hp > hb) { - (void)sscanf(bp, fmt, hp); - bp[0] = 0; - hp--; - bp -= 3; - } - (void)sscanf(buf, fmt, hp); - cvtbase((long)ibase, 256, hb, i, out, len); -} - -static void -cvtbase(oldbase,newbase,input,inlen,result,reslen) - long oldbase; - int newbase; - int input[]; - int inlen; - unsigned char result[]; - int reslen; -{ - int d, e; - long sum; - - e = 1; - while (e > 0 && reslen > 0) { - d = 0; e = 0; sum = 0; - /* long division: input=input/newbase */ - while (d < inlen) { - sum = sum*oldbase + (long) input[d]; - e += (sum > 0); - input[d++] = sum / newbase; - sum %= newbase; - } - result[--reslen] = sum; /* accumulate remainder */ - } - for (d=0; d < reslen; d++) - result[d] = 0; -} diff --git a/lib/libipx/ipx_ntoa.c b/lib/libipx/ipx_ntoa.c deleted file mode 100644 index a33b807..0000000 --- a/lib/libipx/ipx_ntoa.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 1986, 1993 - * The Regents of the University of California. 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ipx_ntoa.c"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <arpa/inet.h> -#include <netipx/ipx.h> -#include <stdio.h> - -static char *spectHex(char *); - -char * -ipx_ntoa(addr) - struct ipx_addr addr; -{ - static char obuf[40]; - union { union ipx_net net_e; u_long long_e; } net; - u_short port = htons(addr.x_port); - char *cp; - char *cp2; - u_char *up = addr.x_host.c_host; - u_char *uplim = up + 6; - - net.net_e = addr.x_net; - sprintf(obuf, "%lx", (u_long)ntohl(net.long_e)); - cp = spectHex(obuf); - cp2 = cp + 1; - while (*up==0 && up < uplim) up++; - if (up == uplim) { - if (port) { - sprintf(cp, ".0"); - cp += 2; - } - } else { - sprintf(cp, ".%x", *up++); - while (up < uplim) { - while (*cp) cp++; - sprintf(cp, "%02x", *up++); - } - cp = spectHex(cp2); - } - if (port) { - sprintf(cp, ".%x", port); - spectHex(cp + 1); - } - return (obuf); -} - -static char * -spectHex(p0) - char *p0; -{ - int ok = 0; - int nonzero = 0; - char *p = p0; - for (; *p; p++) switch (*p) { - - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - ok = 1; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - nonzero = 1; - } - if (nonzero && !ok) { *p++ = 'H'; *p = 0; } - return (p); -} diff --git a/lib/libkse/Makefile b/lib/libkse/Makefile deleted file mode 100644 index 7d8c5c1..0000000 --- a/lib/libkse/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# $FreeBSD$ -# -# All library objects contain FreeBSD revision strings by default; they may be -# excluded as a space-saving measure. To produce a library that does -# not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS -# below. Note, there are no IDs for syscall stubs whose sources are generated. -# To included legacy CSRG sccsid strings, add -DLIBC_SCCS and -DSYSLIBC_SCCS -# (for system call stubs) to CFLAGS below. -DSYSLIBC_SCCS affects just the -# system call stubs. - -.include <bsd.own.mk> - -SHLIB=kse -SHLIB_MAJOR= 4 -CFLAGS+=-DPTHREAD_KERNEL -CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \ - -I${.CURDIR}/../../include -CFLAGS+=-I${.CURDIR}/arch/${MACHINE_CPUARCH}/include -CFLAGS+=-I${.CURDIR}/sys -CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf -CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_CPUARCH} -CFLAGS+=-fno-builtin - -# Uncomment this if you want libkse to contain debug information for -# thread locking. -CFLAGS+=-D_LOCK_DEBUG -WARNS?=3 - -# Uncomment this if you want to build a 1:1 threading mode library -# however it is no longer strictly conformed to POSIX -# CFLAGS+=-DSYSTEM_SCOPE_ONLY - -# Enable extra internal consistancy checks. -CFLAGS+=-D_PTHREADS_INVARIANTS -Wall - -VERSION_DEF=${.CURDIR}/../libc/Versions.def -SYMBOL_MAPS=${.CURDIR}/kse.map - -PRECIOUSLIB= - -.PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH}/${MACHINE_CPUARCH} - -.include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc" -.include "${.CURDIR}/support/Makefile.inc" -.include "${.CURDIR}/sys/Makefile.inc" -.include "${.CURDIR}/thread/Makefile.inc" - -.include <bsd.lib.mk> diff --git a/lib/libkse/arch/amd64/Makefile.inc b/lib/libkse/arch/amd64/Makefile.inc deleted file mode 100644 index 0166d3d..0000000 --- a/lib/libkse/arch/amd64/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= context.S enter_uts.S pthread_md.c diff --git a/lib/libkse/arch/amd64/amd64/context.S b/lib/libkse/arch/amd64/amd64/context.S deleted file mode 100644 index 6a6b558..0000000 --- a/lib/libkse/arch/amd64/amd64/context.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -/* - * The following notes ("cheat sheet") was provided by Peter Wemm. - * - * scratch: - * rax (1st return) - * rcx (4th arg) - * rdx (3rd arg, 2nd return) - * rsi (2nd arg) - * rdi (1st arg) - * r8 (5th arg) - * r9 (6th arg) - * r10 (temp, static chain?) - * r11 (temp) - * - * preserved: - * rbx (base pointer) - * rsp (stack) - * rbp (frame) - * r12-r15 (general) - * - * calls: - * rdi 1 - * rsi 2 - * rdx 3 - * rcx 4 - * r8 5 - * r9 6 - * - * return: - * rax 1 - * rdx 2 - * - * This means: - * arg1 goes in %rdi, arg2 in %rsi, etc. return value is %rax (and - * secondary return, eg: pipe(2), in %rdx) %rcx,%rsi,%rdi etc are - * trashed by making a call to something. %rbx,%rbp,%r12-15 are the - * only registers preserved across a call. Note that unlike i386, - * %rsi and %rdi are scratch rather than preserved. FPU is - * different, args are in SSE registers rather than the x87 stack. - * - * Aside from the register calling conventions, amd64 can be treated - * very much like i386. Things like setjmp/longjmp etc were literal - * translations from i386 but with the register names updated, etc. - * The main gotcha is that FPU save/restore is in SSE format, which - * means a sparse 512 byte FPU context. - */ - - -/* - * Where do we define these? - */ -#define MC_SIZE 800 /* sizeof mcontext_t */ -#define MC_LEN_OFFSET (25*8) /* offset to mc_len from mcontext */ -#define MC_FPFMT_OFFSET (26*8) /* offset to mc_fpformat from mcontext */ -#define MC_FPFMT_NODEV 0x10000 -#define MC_OWNEDFP_OFFSET (27*8) /* offset to mc_ownedfp from mcontext */ -#define MC_OWNEDFP_NONE 0x20000 -#define MC_OWNEDFP_FPU 0x20001 -#define MC_OWNEDFP_PCB 0x20002 -#define MC_FPREGS_OFFSET (28*8) /* offset to FP registers */ -#define MC_FP_CW_OFFSET (28*8) /* offset to FP control word */ - -#define MC_RDI (1 * 8) -#define MC_RSI (2 * 8) -#define MC_RDX (3 * 8) -#define MC_RCX (4 * 8) -#define MC_R8 (5 * 8) -#define MC_R9 (6 * 8) -#define MC_RAX (7 * 8) -#define MC_RBX (8 * 8) -#define MC_RBP (9 * 8) -#define MC_R10 (10 * 8) -#define MC_R11 (11 * 8) -#define MC_R12 (12 * 8) -#define MC_R13 (13 * 8) -#define MC_R14 (14 * 8) -#define MC_R15 (15 * 8) -#define MC_FLAGS (18 * 8) -#define MC_RIP (20 * 8) -#define MC_CS (21 * 8) -#define MC_RFLAGS (22 * 8) -#define MC_RSP (23 * 8) -#define MC_SS (24 * 8) - -#define REDZONE 128 /* size of the red zone */ - -/* - * _amd64_ctx_save(mcontext_t *mcp) - * - * No values are saved to mc_trapno, mc_addr, mc_err and mc_cs. - * For the FPU state, only the floating point control word is stored. - */ -ENTRY(_amd64_save_context) - cmpq $0, %rdi /* check for null pointer */ - jne 1f - movq $-1, %rax - jmp 2f -1: movq %rdi, MC_RDI(%rdi) - movq %rsi, MC_RSI(%rdi) - movq %rdx, MC_RDX(%rdi) - movq %rcx, MC_RCX(%rdi) - movq %r8, MC_R8(%rdi) - movq %r9, MC_R9(%rdi) - movq $1, MC_RAX(%rdi) /* return 1 when restored */ - movq %rbx, MC_RBX(%rdi) - movq %rbp, MC_RBP(%rdi) - movq %r10, MC_R10(%rdi) - movq %r11, MC_R11(%rdi) - movq %r12, MC_R12(%rdi) - movq %r13, MC_R13(%rdi) - movq %r14, MC_R14(%rdi) - movq %r15, MC_R15(%rdi) - movq (%rsp), %rax /* get return address */ - movq %rax, MC_RIP(%rdi) /* save return address (%rip) */ - pushfq /* get flags */ - popq %rax - movq %rax, MC_RFLAGS(%rdi) /* save flags */ - movq %rsp, %rax /* setcontext pushes the return */ - addq $8, %rax /* address onto the stack; */ - movq %rax, MC_RSP(%rdi) /* account for this -- ???. */ - movw %ss, MC_SS(%rdi) - fnstcw MC_FP_CW_OFFSET(%rdi) /* save FPU control word */ - movq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi) /* no FP */ - movq $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%rdi) - movq $MC_SIZE, MC_LEN_OFFSET(%rdi) - xorq %rax, %rax /* return 0 */ -2: ret - -/* - * _amd64_ctx_restore(mcontext_t *mcp, intptr_t val, intptr_t *loc); - */ -ENTRY(_amd64_restore_context) - cmpq $0, %rdi /* check for null pointer */ - jne 1f - movq $-1, %rax - jmp 2f -1: cmpq $MC_SIZE, MC_LEN_OFFSET(%rdi) /* is context valid? */ - je 2f - movq $-1, %rax /* bzzzt, invalid context */ - ret -2: movq MC_RCX(%rdi), %rcx - movq MC_R8(%rdi), %r8 - movq MC_R9(%rdi), %r9 - movq MC_RBX(%rdi), %rbx - movq MC_RBP(%rdi), %rbp - movq MC_R10(%rdi), %r10 - movq MC_R11(%rdi), %r11 - movq MC_R12(%rdi), %r12 - movq MC_R13(%rdi), %r13 - movq MC_R14(%rdi), %r14 - movq MC_R15(%rdi), %r15 - /* - * if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB) - * restore XMM/SSE FP register format - */ - cmpq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi) - je 4f - cmpq $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%rdi) - je 3f - cmpq $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%rdi) - jne 4f -3: fxrstor MC_FPREGS_OFFSET(%rdi) /* restore XMM FP regs */ - jmp 5f -4: fninit - fldcw MC_FP_CW_OFFSET(%rdi) -5: movq MC_RSP(%rdi), %rsp /* switch to context stack */ - subq $REDZONE, %rsp - movq MC_RIP(%rdi), %rax /* return address on stack */ - pushq %rax - movq MC_RDI(%rdi), %rax /* rdi on stack */ - pushq %rax - movq MC_RDX(%rdi), %rax /* rdx on stack */ - pushq %rax - movq MC_RSI(%rdi), %rax /* rsi on stack */ - pushq %rax - movq MC_RFLAGS(%rdi), %rax /* flags on stack*/ - pushq %rax - movq MC_RAX(%rdi), %rax /* restore rax */ - /* At this point we're done with the context. */ - cmpq $0, %rdx /* set *loc to val */ - je 6f - movq %rsi, (%rdx) -6: popfq /* restore flags */ - popq %rsi /* restore rsi, rdx, and rdi */ - popq %rdx - popq %rdi - ret $REDZONE - diff --git a/lib/libkse/arch/amd64/amd64/enter_uts.S b/lib/libkse/arch/amd64/amd64/enter_uts.S deleted file mode 100644 index fb0df87..0000000 --- a/lib/libkse/arch/amd64/amd64/enter_uts.S +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - - -/* - * _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - * size_t stacksz); - */ -ENTRY(_amd64_enter_uts) - addq %rcx, %rdx /* get stack base */ - andq $~0xf, %rdx /* align to 16 bytes */ - movq %rdx, %rsp /* switch to UTS stack */ - movq %rdx, %rbp /* set frame */ - callq *%rsi - ret diff --git a/lib/libkse/arch/amd64/amd64/pthread_md.c b/lib/libkse/arch/amd64/amd64/pthread_md.c deleted file mode 100644 index 3aceec7..0000000 --- a/lib/libkse/arch/amd64/amd64/pthread_md.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <stdlib.h> -#include <strings.h> -#include "rtld_tls.h" -#include "pthread_md.h" - -/* - * The constructors. - */ -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - struct tcb *tcb; - void *oldtls; - - if (initial) { - __asm __volatile("movq %%fs:0, %0" : "=r" (oldtls)); - } else { - oldtls = NULL; - } - - tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); - if (tcb) { - tcb->tcb_thread = thread; - bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); - } - - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - _rtld_free_tls(tcb, sizeof(struct tcb), 16); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb != NULL) { - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_self = kcb; - kcb->kcb_kse = kse; - } - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} diff --git a/lib/libkse/arch/amd64/include/atomic_ops.h b/lib/libkse/arch/amd64/include/atomic_ops.h deleted file mode 100644 index 0ac3b1c..0000000 --- a/lib/libkse/arch/amd64/include/atomic_ops.h +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -/* - * Atomic swap: - * Atomic (tmp = *dst, *dst = val), then *res = tmp - * - * void atomic_swap64(intptr_t *dst, intptr_t val, intptr_t *res); - */ -static inline void -atomic_swap64(volatile intptr_t *dst, intptr_t val, intptr_t *res) -{ - __asm __volatile( - "xchgq %2, %1; movq %2, %0" - : "=m" (*res) : "m" (*dst), "r" (val) : "memory"); -} - -static inline void -atomic_swap_int(volatile int *dst, int val, int *res) -{ - __asm __volatile( - "xchgl %2, %1; movl %2, %0" - : "=m" (*res) : "m" (*dst), "r" (val) : "memory"); -} - -#define atomic_swap_ptr(d, v, r) \ - atomic_swap64((volatile intptr_t *)(d), (intptr_t)(v), (intptr_t *)(r)) - -#endif diff --git a/lib/libkse/arch/amd64/include/pthread_md.h b/lib/libkse/arch/amd64/include/pthread_md.h deleted file mode 100644 index 3e451fd..0000000 --- a/lib/libkse/arch/amd64/include/pthread_md.h +++ /dev/null @@ -1,268 +0,0 @@ -/*- - * Copyright (C) 2003 David Xu <davidxu@freebsd.org> - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - * Machine-dependent thread prototypes/definitions for the thread kernel. - */ -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <stddef.h> -#include <sys/types.h> -#include <sys/kse.h> -#include <machine/sysarch.h> -#include <ucontext.h> - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_dtv) - -#define THR_GETCONTEXT(ucp) \ - (void)_amd64_save_context(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) \ - (void)_amd64_restore_context(&(ucp)->uc_mcontext, 0, NULL) - -#define PER_KSE -#undef PER_THREAD - -struct kse; -struct pthread; -struct tdv; - -/* - * %fs points to a struct kcb. - */ -struct kcb { - struct tcb *kcb_curtcb; - struct kcb *kcb_self; /* self reference */ - struct kse *kcb_kse; - struct kse_mailbox kcb_kmbx; -}; - -struct tcb { - struct tcb *tcb_self; /* required by rtld */ - void *tcb_dtv; /* required by rtld */ - struct pthread *tcb_thread; - void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */ - struct kse_thr_mailbox tcb_tmbx; -}; - -/* - * Evaluates to the byte offset of the per-kse variable name. - */ -#define __kcb_offset(name) __offsetof(struct kcb, name) - -/* - * Evaluates to the type of the per-kse variable name. - */ -#define __kcb_type(name) __typeof(((struct kcb *)0)->name) - -/* - * Evaluates to the value of the per-kse variable name. - */ -#define KCB_GET64(name) ({ \ - __kcb_type(name) __result; \ - \ - u_long __i; \ - __asm __volatile("movq %%fs:%1, %0" \ - : "=r" (__i) \ - : "m" (*(u_long *)(__kcb_offset(name)))); \ - __result = (__kcb_type(name))__i; \ - \ - __result; \ -}) - -/* - * Sets the value of the per-kse variable name to value val. - */ -#define KCB_SET64(name, val) ({ \ - __kcb_type(name) __val = (val); \ - \ - u_long __i; \ - __i = (u_long)__val; \ - __asm __volatile("movq %1,%%fs:%0" \ - : "=m" (*(u_long *)(__kcb_offset(name))) \ - : "r" (__i)); \ -}) - -static __inline u_long -__kcb_readandclear64(volatile u_long *addr) -{ - u_long result; - - __asm __volatile ( - " xorq %0, %0;" - " xchgq %%fs:%1, %0;" - "# __kcb_readandclear64" - : "=&r" (result) - : "m" (*addr)); - return (result); -} - -#define KCB_READANDCLEAR64(name) ({ \ - __kcb_type(name) __result; \ - \ - __result = (__kcb_type(name)) \ - __kcb_readandclear64((u_long *)__kcb_offset(name)); \ - __result; \ -}) - - -#define _kcb_curkcb() KCB_GET64(kcb_self) -#define _kcb_curtcb() KCB_GET64(kcb_curtcb) -#define _kcb_curkse() ((struct kse *)KCB_GET64(kcb_kmbx.km_udata)) -#define _kcb_get_tmbx() KCB_GET64(kcb_kmbx.km_curthread) -#define _kcb_set_tmbx(value) KCB_SET64(kcb_kmbx.km_curthread, (void *)value) -#define _kcb_readandclear_tmbx() KCB_READANDCLEAR64(kcb_kmbx.km_curthread) - -/* - * The constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *tcb); -struct kcb *_kcb_ctor(struct kse *); -void _kcb_dtor(struct kcb *); - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - amd64_set_fsbase(kcb); -} - -/* Get the current kcb. */ -static __inline struct kcb * -_kcb_get(void) -{ - return (_kcb_curkcb()); -} - -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - - crit = _kcb_readandclear_tmbx(); - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - _kcb_set_tmbx(crit); -} - -static __inline int -_kcb_in_critical(void) -{ - return (_kcb_get_tmbx() == NULL); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - kcb->kcb_curtcb = tcb; -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (_kcb_curtcb()); -} - -static __inline struct pthread * -_get_curthread(void) -{ - struct tcb *tcb; - - tcb = _kcb_curtcb(); - if (tcb != NULL) - return (tcb->tcb_thread); - else - return (NULL); -} - -static __inline struct kse * -_get_curkse(void) -{ - return ((struct kse *)_kcb_curkse()); -} - -void _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - size_t stacksz); -int _amd64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc); -int _amd64_save_context(mcontext_t *mc); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - int ret; - - ret = _amd64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext); - if (ret == 0) { - _amd64_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } - else if (ret < 0) - return (-1); - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - extern int _libkse_debug; - - if ((kcb == NULL) || (tcb == NULL)) - return (-1); - kcb->kcb_curtcb = tcb; - - if (_libkse_debug == 0) { - tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp; - if (setmbox != 0) - _amd64_restore_context( - &tcb->tcb_tmbx.tm_context.uc_mcontext, - (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread); - else - _amd64_restore_context( - &tcb->tcb_tmbx.tm_context.uc_mcontext, - 0, NULL); - /* We should not reach here. */ - } else { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } - - return (-1); -} -#endif diff --git a/lib/libkse/arch/arm/Makefile.inc b/lib/libkse/arch/arm/Makefile.inc deleted file mode 100644 index 1705e71..0000000 --- a/lib/libkse/arch/arm/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -CFLAGS+=-DSYSTEM_SCOPE_ONLY - -SRCS+= pthread_md.c context.S diff --git a/lib/libkse/arch/arm/arm/context.S b/lib/libkse/arch/arm/arm/context.S deleted file mode 100644 index c638804..0000000 --- a/lib/libkse/arch/arm/arm/context.S +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) Olivier Houchard - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -/* - * int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc) - * - * Restores the context in mcp. - * - * Returns 0 if there are no errors; -1 otherwise - */ - -.weak _C_LABEL(_thr_setcontext) -.set _C_LABEL(_thr_setcontext), _C_LABEL(__thr_setcontext) - -ENTRY(__thr_setcontext) -/* Check for NULL pointer. */ - cmp r0, #0 - moveq r0, #-1 - moveq pc, lr - cmp r2, #0 - strne r1, [r2] - ldr r1, [r0, #(16 * 4)] /* CPSR */ - msr cpsr, r1 - ldmia r0, {r0-r15} - mov pc, lr - /* XXX: FP bits ? */ - -/* - * int thr_getcontext(mcontext_t *mcp); - * - * Returns -1 if there is an error, 0 no errors; 1 upon return - * from a setcontext(). - */ -.weak _C_LABEL(_thr_getcontext) -.set _C_LABEL(_thr_getcontext), _C_LABEL(__thr_getcontext) - -ENTRY(__thr_getcontext) -/* Check for NULL pointer. */ - cmp r0, #0 - moveq r0, #-1 - moveq pc, lr - stmia r0, {r1-r14} - mov r1, #1 - str r1, [r0] /* Return 1 from setcontext */ - str lr, [r0, #(15 * 4)] /* PC */ - mrs r1, cpsr - str r1, [r0, #(16 * 4)] /* CPSR */ - mov r0, #0 /* Return 0. */ - mov pc, lr - -ENTRY(_arm_enter_uts) - add sp, r2, r3 /* Stack addr + size. */ - mov pc, r1 diff --git a/lib/libkse/arch/arm/arm/pthread_md.c b/lib/libkse/arch/arm/arm/pthread_md.c deleted file mode 100644 index 72426d4..0000000 --- a/lib/libkse/arch/arm/arm/pthread_md.c +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright (C) 2003 Jake Burkholder <jake@freebsd.org> - * Copyright (C) 2003 David Xu <davidxu@freebsd.org> - * Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> - -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <ucontext.h> - -#include <machine/sysarch.h> - -#include "pthread_md.h" - -struct arm_tp **arm_tp = (struct arm_tp **)ARM_TP_ADDRESS; - -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - struct tcb *tcb; - - if ((tcb = malloc(sizeof(struct tcb)))) { - bzero(tcb, sizeof(struct tcb)); - tcb->tcb_thread = thread; - /* XXX - Allocate tdv/tls */ - } - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - - free(tcb); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb != NULL) { - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_faketcb.tcb_isfake = 1; - kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_curtcb = &kcb->kcb_faketcb; - kcb->kcb_kse = kse; - } - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} diff --git a/lib/libkse/arch/arm/include/atomic_ops.h b/lib/libkse/arch/arm/include/atomic_ops.h deleted file mode 100644 index 4d8b55e..0000000 --- a/lib/libkse/arch/arm/include/atomic_ops.h +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -#include <machine/atomic.h> -#include "thr_private.h" - -/* - * Atomic swap: - * Atomic (tmp = *dst, *dst = val), then *res = tmp - * - * void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res); - */ -static inline void -atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res) -{ - *res = __swp(val, dst); -} - -#define atomic_swap_ptr(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif - diff --git a/lib/libkse/arch/arm/include/pthread_md.h b/lib/libkse/arch/arm/include/pthread_md.h deleted file mode 100644 index 857fa1b..0000000 --- a/lib/libkse/arch/arm/include/pthread_md.h +++ /dev/null @@ -1,257 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>. - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent thread prototypes/definitions for the thread kernel. - */ -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <sys/kse.h> -#include <stddef.h> -#include <ucontext.h> - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv) - -int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *); -int _thr_getcontext(mcontext_t *); - -#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL) - -#define PER_THREAD - -struct kcb; -struct kse; -struct pthread; -struct tcb; -struct tdv; /* We don't know what this is yet? */ - - -/* - * %r6 points to one of these. We define the static TLS as an array - * of long double to enforce 16-byte alignment of the TLS memory. - * - * XXX - Both static and dynamic allocation of any of these structures - * will result in a valid, well-aligned thread pointer??? - */ -struct arm_tp { - struct tdv *tp_tdv; /* dynamic TLS */ -}; - -struct tcb { - struct pthread *tcb_thread; - struct kcb *tcb_curkcb; - uint32_t tcb_isfake; - struct kse_thr_mailbox tcb_tmbx; /* needs 32-byte alignment */ - struct arm_tp tcb_tp; -}; - -struct kcb { - struct kse_mailbox kcb_kmbx; - struct tcb kcb_faketcb; - struct tcb *kcb_curtcb; - struct kse *kcb_kse; -}; - -extern struct arm_tp **arm_tp; -#define _tp (*arm_tp) - -#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) - -/* - * The kcb and tcb constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *); -struct kcb *_kcb_ctor(struct kse *kse); -void _kcb_dtor(struct kcb *); - -static __inline uint32_t -__kcb_swp(uint32_t val, void *ptr) -{ - - __asm __volatile("swp %0, %1, [%2]" - : "=r" (val) : "r" (val) , "r" (ptr) : "memory"); - return (val); -} - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - /* There is no thread yet; use the fake tcb. */ - __kcb_swp((uint32_t)&kcb->kcb_faketcb.tcb_tp, &_tp); -} - -/* - * Get the current kcb. - * - * This can only be called while in a critical region; don't - * worry about having the kcb changed out from under us. - */ -static __inline struct kcb * -_kcb_get(void) -{ - return (_tcb->tcb_curkcb); -} - -/* - * Enter a critical region. - * - * Read and clear km_curthread in the kse mailbox. - */ -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - - if (_tcb->tcb_isfake) - return (NULL); - crit = (struct kse_thr_mailbox *)__kcb_swp((uint32_t)NULL, - &_tcb->tcb_curkcb->kcb_kmbx.km_curthread); - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - - if (_tcb->tcb_isfake == 0) - __kcb_swp((uint32_t)crit, - &_tcb->tcb_curkcb->kcb_kmbx.km_curthread); -} - -static __inline int -_kcb_in_critical(void) -{ - uint32_t flags; - int ret; - - return (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - if (_tcb->tcb_isfake != 0) { - /* - * We are in a critical region since there is no - * current thread. - */ - ret = 1; - } else { - flags = _tcb->tcb_tmbx.tm_flags; - _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - _tcb->tcb_tmbx.tm_flags = flags; - } - return (ret); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - if (tcb == NULL) - tcb = &kcb->kcb_faketcb; - __kcb_swp((uint32_t)&tcb->tcb_tp, &_tp); - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (_tcb); -} - -static __inline struct pthread * -_get_curthread(void) -{ - return (_tcb->tcb_thread); -} - -/* - * Get the current kse. - * - * Like _kcb_get(), this can only be called while in a critical region. - */ -static __inline struct kse * -_get_curkse(void) -{ - return (_tcb->tcb_curkcb->kcb_kse); -} - -void _arm_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - size_t stacksz); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - int ret; - - if ((ret = _thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext)) - == 0) { - kcb->kcb_curtcb = &kcb->kcb_faketcb; - __kcb_swp((int)&kcb->kcb_faketcb.tcb_tp, &_tp); - _arm_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } else if (ret < 0) - return (-1); - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - extern int _libkse_debug; - mcontext_t *mc; - - if (!tcb || !kcb) - return (-1); - _tcb_set(kcb, tcb); - mc = &tcb->tcb_tmbx.tm_context.uc_mcontext; - if (_libkse_debug == 0) { - tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp; - if (setmbox) - _thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)&kcb->kcb_kmbx.km_curthread); - else - _thr_setcontext(mc, 0, NULL); - } else { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } - - /* We should not reach here. */ - return (-1); -} - -#endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libkse/arch/i386/Makefile.inc b/lib/libkse/arch/i386/Makefile.inc deleted file mode 100644 index b83ca28..0000000 --- a/lib/libkse/arch/i386/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= thr_enter_uts.S thr_getcontext.S pthread_md.c diff --git a/lib/libkse/arch/i386/i386/pthread_md.c b/lib/libkse/arch/i386/i386/pthread_md.c deleted file mode 100644 index cbea6d4..0000000 --- a/lib/libkse/arch/i386/i386/pthread_md.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright (C) 2003 David Xu <davidxu@freebsd.org> - * Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <machine/cpufunc.h> -#include <machine/sysarch.h> - -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <ucontext.h> - -#include "rtld_tls.h" -#include "pthread_md.h" - -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - struct tcb *tcb; - void *oldtls; - - if (initial) { - __asm __volatile("movl %%gs:0, %0" : "=r" (oldtls)); - } else { - oldtls = NULL; - } - - tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); - if (tcb) { - tcb->tcb_thread = thread; - tcb->tcb_spare = 0; - bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); - } - - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - _rtld_free_tls(tcb, sizeof(struct tcb), 16); -} - -/* - * Initialize KSD. This also includes setting up the LDT. - */ -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb != NULL) { - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_self = kcb; - kcb->kcb_kse = kse; - } - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} - -int -i386_set_gsbase(void *addr) -{ - - return (sysarch(I386_SET_GSBASE, &addr)); -} diff --git a/lib/libkse/arch/i386/i386/thr_enter_uts.S b/lib/libkse/arch/i386/i386/thr_enter_uts.S deleted file mode 100644 index bf6df8f..0000000 --- a/lib/libkse/arch/i386/i386/thr_enter_uts.S +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>. - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - - -/* - * _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - * long stacksz); - * +4 = km, +8 = uts, +12 = stack, +16 = size - */ -ENTRY(_i386_enter_uts) - movl %esp, %edx /* save stack */ - movl 12(%edx), %eax /* get bottom of stack */ - addl 16(%edx), %eax /* add length */ - movl %eax, %esp /* switch to uts stack */ - pushl 4(%edx) /* push the address of the mailbox */ - call *8(%edx) - ret diff --git a/lib/libkse/arch/i386/i386/thr_getcontext.S b/lib/libkse/arch/i386/i386/thr_getcontext.S deleted file mode 100644 index d9d300f..0000000 --- a/lib/libkse/arch/i386/i386/thr_getcontext.S +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -/* - * Where do we define these? - */ -#define MC_LEN_OFFSET 80 /* offset to mc_len from mcontext */ -#define MC_LEN 640 /* mc_len <machine/ucontext.h> */ -#define MC_FPFMT_OFFSET 84 -#define MC_FPFMT_NODEV 0x10000 -#define MC_FPFMT_387 0x10001 -#define MC_FPFMT_XMM 0x10002 -#define MC_OWNEDFP_OFFSET 88 -#define MC_OWNEDFP_NONE 0x20000 -#define MC_OWNEDFP_FPU 0x20001 -#define MC_OWNEDFP_PCB 0x20002 -#define MC_FPREGS_OFFSET 96 /* offset to FP regs from mcontext */ -#define MC_FP_CW_OFFSET 96 /* offset to FP control word */ - -/* - * int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc) - * - * Restores the context in mcp. - * - * Returns 0 if there are no errors; -1 otherwise - */ - .weak CNAME(_thr_setcontext) - .set CNAME(_thr_setcontext),CNAME(__thr_setcontext) -ENTRY(__thr_setcontext) - movl 4(%esp), %edx /* get address of mcontext */ - cmpl $0, %edx /* check for null pointer */ - jne 1f - movl $-1, %eax - jmp 8f -1: cmpl $MC_LEN, MC_LEN_OFFSET(%edx) /* is context valid? */ - je 2f - movl $-1, %eax /* bzzzt, invalid context */ - jmp 8f -2: /*movl 4(%edx), %gs*/ /* we don't touch %gs */ - movw 8(%edx), %fs - movw 12(%edx), %es - movw 16(%edx), %ds - movw 76(%edx), %ss - movl 20(%edx), %edi - movl 24(%edx), %esi - movl 28(%edx), %ebp - movl %esp, %ecx /* save current stack in ecx */ - movl 72(%edx), %esp /* switch to context defined stack */ - pushl 60(%edx) /* push return address on stack */ - pushl 44(%edx) /* push ecx on stack */ - pushl 48(%edx) /* push eax on stack */ - /* - * if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB) { - * if (mc_fpformat == MC_FPFMT_387) - * restore 387 FP register format - * else if (mc_fpformat == MC_FPFMT_XMM) - * restore XMM/SSE FP register format - * } - */ - cmpl $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%edx) - je 3f - cmpl $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%edx) - jne 5f -3: cmpl $MC_FPFMT_387, MC_FPFMT_OFFSET(%edx) - jne 4f - frstor MC_FPREGS_OFFSET(%edx) /* restore 387 FP regs */ - jmp 6f -4: cmpl $MC_FPFMT_XMM, MC_FPFMT_OFFSET(%edx) - jne 5f - fxrstor MC_FPREGS_OFFSET(%edx) /* restore XMM FP regs */ - jmp 6f -5: fninit - fldcw MC_FP_CW_OFFSET(%edx) -6: pushl 68(%edx) /* push flags register on stack*/ - movl 36(%edx), %ebx /* restore ebx and edx */ - movl 40(%edx), %edx - movl 12(%ecx), %eax /* get 3rd arg (loc) */ - cmpl $0, %eax /* do nothing if loc == null */ - je 7f - movl 8(%ecx), %ecx /* get 2nd arg (val) */ - movl %ecx, (%eax) /* set loc = val */ -7: popfl /* restore flags after test */ - popl %eax /* restore eax and ecx last */ - popl %ecx -8: ret - -/* - * int thr_getcontext(mcontext_t *mcp); - * - * Returns -1 if there is an error, 0 no errors; 1 upon return - * from a setcontext(). - */ - .weak CNAME(_thr_getcontext) - .set CNAME(_thr_getcontext),CNAME(__thr_getcontext) -ENTRY(__thr_getcontext) - pushl %edx /* save edx */ - movl 8(%esp), %edx /* get address of mcontext */ - cmpl $0, %edx /* check for null pointer */ - jne 1f - popl %edx /* restore edx and stack */ - movl $-1, %eax - jmp 2f -1: /*movw %gs, 4(%edx)*/ /* we don't touch %gs */ - movw %fs, 8(%edx) - movw %es, 12(%edx) - movw %ds, 16(%edx) - movw %ss, 76(%edx) - movl %edi, 20(%edx) - movl %esi, 24(%edx) - movl %ebp, 28(%edx) - movl %ebx, 36(%edx) - movl $1, 48(%edx) /* store successful return in eax */ - popl %eax /* get saved value of edx */ - movl %eax, 40(%edx) /* save edx */ - movl %ecx, 44(%edx) - movl (%esp), %eax /* get return address */ - movl %eax, 60(%edx) /* save return address */ - fnstcw MC_FP_CW_OFFSET(%edx) - movl $MC_LEN, MC_LEN_OFFSET(%edx) - movl $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%edx) /* no FP */ - movl $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%edx) /* no FP */ - pushfl - popl %eax /* get eflags */ - movl %eax, 68(%edx) /* store eflags */ - movl %esp, %eax /* setcontext pushes the return */ - addl $4, %eax /* address onto the top of the */ - movl %eax, 72(%edx) /* stack; account for this */ - movl 40(%edx), %edx /* restore edx -- is this needed? */ - xorl %eax, %eax /* return 0 */ -2: ret diff --git a/lib/libkse/arch/i386/include/atomic_ops.h b/lib/libkse/arch/i386/include/atomic_ops.h deleted file mode 100644 index 0cd47f8..0000000 --- a/lib/libkse/arch/i386/include/atomic_ops.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -/* - * Atomic swap: - * Atomic (tmp = *dst, *dst = val), then *res = tmp - * - * void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res); - */ -static inline void -atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res) -{ - __asm __volatile( - "xchgl %2, %1; movl %2, %0" - : "=m" (*res) : "m" (*dst), "r" (val) : "memory"); -} - -#define atomic_swap_ptr(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif diff --git a/lib/libkse/arch/i386/include/pthread_md.h b/lib/libkse/arch/i386/include/pthread_md.h deleted file mode 100644 index 151d882..0000000 --- a/lib/libkse/arch/i386/include/pthread_md.h +++ /dev/null @@ -1,264 +0,0 @@ -/*- - * Copyright (c) 2002 Daniel Eischen <deischen@freebsd.org>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - * Machine-dependent thread prototypes/definitions for the thread kernel. - */ -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <stddef.h> -#include <sys/types.h> -#include <sys/kse.h> -#include <machine/sysarch.h> -#include <ucontext.h> - -extern int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *); -extern int _thr_getcontext(mcontext_t *); - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_dtv) - -#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL) - -#define PER_KSE -#undef PER_THREAD - -struct kse; -struct pthread; - -/* - * %gs points to a struct kcb. - */ -struct kcb { - struct tcb *kcb_curtcb; - struct kcb *kcb_self; /* self reference */ - struct kse *kcb_kse; - struct kse_mailbox kcb_kmbx; -}; - -struct tcb { - struct tcb *tcb_self; /* required by rtld */ - void *tcb_dtv; /* required by rtld */ - struct pthread *tcb_thread; - void *tcb_spare; /* align tcb_tmbx to 16 bytes */ - struct kse_thr_mailbox tcb_tmbx; -}; - -/* - * Evaluates to the byte offset of the per-kse variable name. - */ -#define __kcb_offset(name) __offsetof(struct kcb, name) - -/* - * Evaluates to the type of the per-kse variable name. - */ -#define __kcb_type(name) __typeof(((struct kcb *)0)->name) - -/* - * Evaluates to the value of the per-kse variable name. - */ -#define KCB_GET32(name) ({ \ - __kcb_type(name) __result; \ - \ - u_int __i; \ - __asm __volatile("movl %%gs:%1, %0" \ - : "=r" (__i) \ - : "m" (*(u_int *)(__kcb_offset(name)))); \ - __result = (__kcb_type(name))__i; \ - \ - __result; \ -}) - -/* - * Sets the value of the per-kse variable name to value val. - */ -#define KCB_SET32(name, val) ({ \ - __kcb_type(name) __val = (val); \ - \ - u_int __i; \ - __i = (u_int)__val; \ - __asm __volatile("movl %1,%%gs:%0" \ - : "=m" (*(u_int *)(__kcb_offset(name))) \ - : "r" (__i)); \ -}) - -static __inline u_long -__kcb_readandclear32(volatile u_long *addr) -{ - u_long result; - - __asm __volatile ( - " xorl %0, %0;" - " xchgl %%gs:%1, %0;" - "# __kcb_readandclear32" - : "=&r" (result) - : "m" (*addr)); - return (result); -} - -#define KCB_READANDCLEAR32(name) ({ \ - __kcb_type(name) __result; \ - \ - __result = (__kcb_type(name)) \ - __kcb_readandclear32((u_long *)__kcb_offset(name)); \ - __result; \ -}) - - -#define _kcb_curkcb() KCB_GET32(kcb_self) -#define _kcb_curtcb() KCB_GET32(kcb_curtcb) -#define _kcb_curkse() ((struct kse *)KCB_GET32(kcb_kmbx.km_udata)) -#define _kcb_get_tmbx() KCB_GET32(kcb_kmbx.km_curthread) -#define _kcb_set_tmbx(value) KCB_SET32(kcb_kmbx.km_curthread, (void *)value) -#define _kcb_readandclear_tmbx() KCB_READANDCLEAR32(kcb_kmbx.km_curthread) - - -/* - * The constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *tcb); -struct kcb *_kcb_ctor(struct kse *); -void _kcb_dtor(struct kcb *); - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - i386_set_gsbase(kcb); -} - -/* Get the current kcb. */ -static __inline struct kcb * -_kcb_get(void) -{ - return (_kcb_curkcb()); -} - -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - - crit = _kcb_readandclear_tmbx(); - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - _kcb_set_tmbx(crit); -} - -static __inline int -_kcb_in_critical(void) -{ - return (_kcb_get_tmbx() == NULL); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - kcb->kcb_curtcb = tcb; -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (_kcb_curtcb()); -} - -static __inline struct pthread * -_get_curthread(void) -{ - struct tcb *tcb; - - tcb = _kcb_curtcb(); - if (tcb != NULL) - return (tcb->tcb_thread); - else - return (NULL); -} - -static __inline struct kse * -_get_curkse(void) -{ - return ((struct kse *)_kcb_curkse()); -} - -void _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack, - size_t stacksz); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - int ret; - - ret = _thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext); - if (ret == 0) { - _i386_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } - else if (ret < 0) - return (-1); - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - extern int _libkse_debug; - - if ((kcb == NULL) || (tcb == NULL)) - return (-1); - kcb->kcb_curtcb = tcb; - if (_libkse_debug == 0) { - tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp; - if (setmbox != 0) - _thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext, - (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread); - else - _thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext, - 0, NULL); - } else { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } - - /* We should not reach here. */ - return (-1); -} - -#endif diff --git a/lib/libkse/arch/ia64/Makefile.inc b/lib/libkse/arch/ia64/Makefile.inc deleted file mode 100644 index 0166d3d..0000000 --- a/lib/libkse/arch/ia64/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= context.S enter_uts.S pthread_md.c diff --git a/lib/libkse/arch/ia64/ia64/context.S b/lib/libkse/arch/ia64/ia64/context.S deleted file mode 100644 index 9411293..0000000 --- a/lib/libkse/arch/ia64/ia64/context.S +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -#include <sys/syscall.h> - -#define SIZEOF_SPECIAL (18*8) - -/* - * int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc); - */ -ENTRY(_ia64_restore_context, 3) -{ .mmi - invala - mov ar.rsc=0xc - add r32=16,r32 - ;; -} -{ .mmi - loadrs - ld8 r12=[r32] // sp - add r31=8,r32 - ;; -} -{ .mii - ld8 r16=[r31],16 // unat (before) - add r30=16,r32 - add r14=SIZEOF_SPECIAL,r32 - ;; -} -{ .mmi - ld8 r17=[r30],16 // rp - ld8 r18=[r31],16 // pr - mov r2=r33 - ;; -} -{ .mmi - ld8 r19=[r30],16 // pfs - ld8 r20=[r31],32 // bspstore - mov rp=r17 - ;; -} -{ .mmi - ld8 r21=[r30],32 // rnat - ld8 r22=[r31],16 // rsc - mov pr=r18,0x1fffe - ;; -} -{ .mmi - ld8 r23=[r30] // fpsr - ld8 r24=[r31] // psr -- not used - mov r3=r34 - ;; -} -{ .mmi - ld8 r17=[r14],8 // unat (after) - mov ar.bspstore=r20 - cmp.ne p15,p0=r0,r3 - ;; -} -{ .mmi - mov ar.rnat=r21 - mov ar.unat=r17 - add r15=8,r14 - ;; -} -{ .mmi - ld8.fill r4=[r14],16 // r4 - ld8.fill r5=[r15],16 // r5 - mov ar.pfs=r19 - ;; -} -{ .mmi - ld8.fill r6=[r14],16 // r6 - ld8.fill r7=[r15],16 // r7 - nop 0 - ;; -} -{ .mmi - mov ar.unat=r16 - mov ar.rsc=r22 - nop 0 -} -{ .mmi - ld8 r17=[r14],16 // b1 - ld8 r18=[r15],16 // b2 - nop 0 - ;; -} -{ .mmi - ld8 r19=[r14],16 // b3 - ld8 r20=[r15],16 // b4 - mov b1=r17 - ;; -} -{ .mmi - ld8 r16=[r14],24 // b5 - ld8 r17=[r15],32 // lc - mov b2=r18 - ;; -} -{ .mmi - ldf.fill f2=[r14],32 - ldf.fill f3=[r15],32 - mov b3=r19 - ;; -} -{ .mmi - ldf.fill f4=[r14],32 - ldf.fill f5=[r15],32 - mov b4=r20 - ;; -} -{ .mmi - ldf.fill f16=[r14],32 - ldf.fill f17=[r15],32 - mov b5=r16 - ;; -} -{ .mmi - ldf.fill f18=[r14],32 - ldf.fill f19=[r15],32 - mov ar.lc=r17 - ;; -} - ldf.fill f20=[r14],32 - ldf.fill f21=[r15],32 - ;; - ldf.fill f22=[r14],32 - ldf.fill f23=[r15],32 - ;; - ldf.fill f24=[r14],32 - ldf.fill f25=[r15],32 - ;; - ldf.fill f26=[r14],32 - ldf.fill f27=[r15],32 - ;; - ldf.fill f28=[r14],32 - ldf.fill f29=[r15],32 - ;; - ldf.fill f30=[r14],32+24 - ldf.fill f31=[r15],24+24 - ;; - ld8 r8=[r14],16 - ld8 r9=[r15],16 - ;; - ld8 r10=[r14] - ld8 r11=[r15] - ;; -{ .mmb -(p15) st8 [r3]=r2 - mov ar.fpsr=r23 - br.ret.sptk rp - ;; -} -END(_ia64_restore_context) - -/* - * int _ia64_save_context(mcontext_t *mc); - */ -ENTRY(_ia64_save_context, 1) -{ .mmi - mov r14=ar.rsc - mov r15=ar.fpsr - add r31=8,r32 - ;; -} -{ .mmi - st8 [r32]=r0,16 - st8 [r31]=r0,16 - nop 0 - ;; -} -{ .mmi - mov ar.rsc=0xc - mov r16=ar.unat - nop 0 - ;; -} -{ .mmi - flushrs - st8 [r32]=sp,16 // sp - mov r17=rp - ;; -} -{ .mmi - st8 [r31]=r16,16 // unat (before) - st8 [r32]=r17,16 // rp - mov r16=pr - ;; -} -{ .mmi - st8 [r31]=r16,16 // pr - mov r17=ar.bsp - mov r16=ar.pfs - ;; -} -{ .mmi - st8 [r32]=r16,16 // pfs - st8 [r31]=r17,16 // bspstore - nop 0 - ;; -} -{ .mmi - mov r16=ar.rnat - mov ar.rsc=r14 - add r30=SIZEOF_SPECIAL-(6*8),r32 - ;; -} -{ .mmi - st8 [r32]=r16,16 // rnat - st8 [r31]=r0,16 // __spare - nop 0 - ;; -} -{ .mmi - st8 [r32]=r13,16 // tp -- not used - st8 [r31]=r14,16 // rsc - mov r16=b1 - ;; -} -{ .mmi - st8 [r32]=r15,10*8 // fpr - st8 [r31]=r0,8*8 // psr - nop 0 - ;; -} - /* callee_saved */ -{ .mmi - .mem.offset 8,0 - st8.spill [r31]=r4,16 // r4 - .mem.offset 16,0 - st8.spill [r32]=r5,16 // r5 - mov r17=b2 - ;; -} -{ .mmi - .mem.offset 24,0 - st8.spill [r31]=r6,16 // r6 - .mem.offset 32,0 - st8.spill [r32]=r7,16 // r7 - mov r18=b3 - ;; -} -{ .mmi - st8 [r31]=r16,16 // b1 - mov r16=ar.unat - mov r19=b4 - ;; -} -{ .mmi - st8 [r30]=r16 // unat (after) - st8 [r32]=r17,16 // b2 - mov r16=b5 - ;; -} -{ .mmi - st8 [r31]=r18,16 // b3 - st8 [r32]=r19,16 // b4 - mov r17=ar.lc - ;; -} - st8 [r31]=r16,16 // b5 - st8 [r32]=r17,16 // lc - ;; - st8 [r31]=r0,24 // __spare - stf.spill [r32]=f2,32 - ;; - stf.spill [r31]=f3,32 - stf.spill [r32]=f4,32 - ;; - stf.spill [r31]=f5,32 - stf.spill [r32]=f16,32 - ;; - stf.spill [r31]=f17,32 - stf.spill [r32]=f18,32 - ;; - stf.spill [r31]=f19,32 - stf.spill [r32]=f20,32 - ;; - stf.spill [r31]=f21,32 - stf.spill [r32]=f22,32 - ;; - stf.spill [r31]=f23,32 - stf.spill [r32]=f24,32 - ;; - stf.spill [r31]=f25,32 - stf.spill [r32]=f26,32 - ;; - stf.spill [r31]=f27,32 - stf.spill [r32]=f28,32 - ;; -{ .mmi - stf.spill [r31]=f29,32 - stf.spill [r32]=f30,32+24 - add r14=1,r0 - ;; -} -{ .mmi - stf.spill [r31]=f31,24+24 - st8 [r32]=r14,16 // r8 - add r8=0,r0 - ;; -} - st8 [r31]=r0,16 // r9 - st8 [r32]=r0 // r10 - ;; -{ .mmb - st8 [r31]=r0 // r11 - mf - br.ret.sptk rp - ;; -} -END(_ia64_save_context) - -/* - * void _ia64_break_setcontext(mcontext_t *mc); - */ -ENTRY(_ia64_break_setcontext, 1) -{ .mmi - mov r8=r32 - break 0x180000 - nop 0 - ;; -} -END(_ia64_break_setcontext) diff --git a/lib/libkse/arch/ia64/ia64/enter_uts.S b/lib/libkse/arch/ia64/ia64/enter_uts.S deleted file mode 100644 index 5df4d93..0000000 --- a/lib/libkse/arch/ia64/ia64/enter_uts.S +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -/* - * void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack, - * size_t stacksz); - */ -ENTRY(_ia64_enter_uts, 4) -{ .mmi - ld8 r14=[in0],8 - mov ar.rsc=0xc - add r15=in2,in3 - ;; -} -{ .mmi - flushrs - ld8 r1=[in0] - mov b7=r14 - ;; -} -{ .mii - mov ar.bspstore=in2 - add sp=-16,r15 - mov rp=r14 - ;; -} -{ .mib - mov ar.rsc=0xf - mov in0=in1 - br.cond.sptk b7 - ;; -} -1: br.cond.sptk 1b -END(_ia64_enter_uts) diff --git a/lib/libkse/arch/ia64/ia64/pthread_md.c b/lib/libkse/arch/ia64/ia64/pthread_md.c deleted file mode 100644 index dc59b0e..0000000 --- a/lib/libkse/arch/ia64/ia64/pthread_md.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 2006 Marcel Moolenaar - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <stdlib.h> -#include <strings.h> - -#include "rtld_tls.h" -#include "pthread_md.h" - -/* - * The constructors. - */ -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - register char *tp __asm("%r13"); - struct tcb *tcb; - - tcb = _rtld_allocate_tls((initial) ? tp : NULL, - sizeof(struct tcb), 16); - if (tcb == NULL) - return (NULL); - tcb->tcb_thread = thread; - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - - _rtld_free_tls(tcb, sizeof(struct tcb), 16); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb == NULL) - return (NULL); - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_kse = kse; - kcb->kcb_faketcb.tcb_isfake = 1; - kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_curtcb = &kcb->kcb_faketcb; - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} diff --git a/lib/libkse/arch/ia64/include/atomic_ops.h b/lib/libkse/arch/ia64/include/atomic_ops.h deleted file mode 100644 index a8965d1..0000000 --- a/lib/libkse/arch/ia64/include/atomic_ops.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -static inline void -atomic_swap_int(volatile int *dst, int val, int *res) -{ - __asm("xchg4 %0=[%2],%1" : "=r"(*res) : "r"(val), "r"(dst)); -} - -static inline void -atomic_swap_long(volatile long *dst, long val, long *res) -{ - __asm("xchg8 %0=[%2],%1" : "=r"(*res) : "r"(val), "r"(dst)); -} - -#define atomic_swap_ptr(d,v,r) \ - atomic_swap_long((volatile long *)d, (long)v, (long *)r) - -#endif /* _ATOMIC_OPS_H_ */ diff --git a/lib/libkse/arch/ia64/include/pthread_md.h b/lib/libkse/arch/ia64/include/pthread_md.h deleted file mode 100644 index ed77157..0000000 --- a/lib/libkse/arch/ia64/include/pthread_md.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2003-2006 Marcel Moolenaar - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <sys/kse.h> -#include <stddef.h> -#include <ucontext.h> - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv) - -#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n") - -#define PER_THREAD - -struct kcb; -struct kse; -struct pthread; -struct tcb; - -/* - * tp points to one of these. We define the TLS structure as a union - * containing a long double to enforce 16-byte alignment. This makes - * sure that there will not be any padding in struct tcb after the - * TLS structure. - */ -union ia64_tp { - void *tp_dtv; - long double _align_; -}; - -struct tcb { - struct kse_thr_mailbox tcb_tmbx; - struct pthread *tcb_thread; - struct kcb *tcb_curkcb; - long tcb_isfake; - union ia64_tp tcb_tp; -}; - -struct kcb { - struct kse_mailbox kcb_kmbx; - struct kse *kcb_kse; - struct tcb *kcb_curtcb; - struct tcb kcb_faketcb; -}; - -static __inline struct tcb * -ia64_get_tcb(void) -{ - register char *tp __asm("%r13"); - - return ((struct tcb *)(tp - offsetof(struct tcb, tcb_tp))); -} - -static __inline void -ia64_set_tcb(struct tcb *tcb) -{ - register char *tp __asm("%r13"); - - __asm __volatile("mov %0 = %1;;" : "=r"(tp) : "r"(&tcb->tcb_tp)); -} - -/* - * The kcb and tcb constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *); -struct kcb *_kcb_ctor(struct kse *kse); -void _kcb_dtor(struct kcb *); - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - /* There is no thread yet; use the fake tcb. */ - ia64_set_tcb(&kcb->kcb_faketcb); -} - -/* - * Get the current kcb. - * - * This can only be called while in a critical region; don't - * worry about having the kcb changed out from under us. - */ -static __inline struct kcb * -_kcb_get(void) -{ - return (ia64_get_tcb()->tcb_curkcb); -} - -/* - * Enter a critical region. - * - * Read and clear km_curthread in the kse mailbox. - */ -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct tcb *tcb; - struct kse_thr_mailbox *crit; - uint32_t flags; - - tcb = ia64_get_tcb(); - if (tcb->tcb_isfake != 0) { - /* - * We already are in a critical region since - * there is no current thread. - */ - crit = NULL; - } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread; - tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; - tcb->tcb_tmbx.tm_flags = flags; - } - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - struct tcb *tcb; - - tcb = ia64_get_tcb(); - /* No need to do anything if this is a fake tcb. */ - if (tcb->tcb_isfake == 0) - tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; -} - -static __inline int -_kcb_in_critical(void) -{ - struct tcb *tcb; - uint32_t flags; - int ret; - - tcb = ia64_get_tcb(); - if (tcb->tcb_isfake != 0) { - /* - * We are in a critical region since there is no - * current thread. - */ - ret = 1; - } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - tcb->tcb_tmbx.tm_flags = flags; - } - return (ret); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - if (tcb == NULL) - tcb = &kcb->kcb_faketcb; - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; - ia64_set_tcb(tcb); -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (ia64_get_tcb()); -} - -static __inline struct pthread * -_get_curthread(void) -{ - return (ia64_get_tcb()->tcb_thread); -} - -/* - * Get the current kse. - * - * Like _kcb_get(), this can only be called while in a critical region. - */ -static __inline struct kse * -_get_curkse(void) -{ - return (ia64_get_tcb()->tcb_curkcb->kcb_kse); -} - -void _ia64_break_setcontext(mcontext_t *mc); -void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack, - size_t stacksz); -int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc); -int _ia64_save_context(mcontext_t *mc); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) { - /* Make the fake tcb the current thread. */ - kcb->kcb_curtcb = &kcb->kcb_faketcb; - ia64_set_tcb(&kcb->kcb_faketcb); - _ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - mcontext_t *mc; - - _tcb_set(kcb, tcb); - mc = &tcb->tcb_tmbx.tm_context.uc_mcontext; - if (mc->mc_flags & _MC_FLAGS_ASYNC_CONTEXT) { - if (setmbox) { - mc->mc_flags |= _MC_FLAGS_KSE_SET_MBOX; - mc->mc_special.ifa = - (intptr_t)&kcb->kcb_kmbx.km_curthread; - mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx; - } - _ia64_break_setcontext(mc); - } else if (mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } else { - if (setmbox) - _ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)&kcb->kcb_kmbx.km_curthread); - else - _ia64_restore_context(mc, 0, NULL); - } - /* We should not reach here. */ - return (-1); -} - -#endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libkse/arch/powerpc/Makefile.inc b/lib/libkse/arch/powerpc/Makefile.inc deleted file mode 100644 index f49e97f..0000000 --- a/lib/libkse/arch/powerpc/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -# XXX temporary -CFLAGS+=-DSYSTEM_SCOPE_ONLY - -SRCS+= enter_uts.S context.S pthread_md.c diff --git a/lib/libkse/arch/powerpc/include/atomic_ops.h b/lib/libkse/arch/powerpc/include/atomic_ops.h deleted file mode 100644 index 866bed5..0000000 --- a/lib/libkse/arch/powerpc/include/atomic_ops.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004 by Peter Grehan. 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -/* - * Atomic swap: - * Atomic (tmp = *dst, *dst = val), then *res = tmp - * - * void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res); - */ -static inline void -atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res) -{ - int tmp; - - tmp = 0; /* should be a better way to quieten cc1... */ -#ifdef __GNUC__ - __asm __volatile( - "1: lwarx %0, 0, %4\n" /* load with reservation */ - " stwcx. %3, 0, %4\n" /* attempt to store val */ - " bne- 1b\n" /* interrupted? retry */ - " stw %0, %1\n" /* else, *dst -> *res */ - : "=&r" (tmp), "=m" (*res), "+m" (*dst) - : "r" (val), "r" (dst) - : "cc", "memory"); -#endif -} - -#define atomic_swap_ptr(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif diff --git a/lib/libkse/arch/powerpc/include/pthread_md.h b/lib/libkse/arch/powerpc/include/pthread_md.h deleted file mode 100644 index 5af255e..0000000 --- a/lib/libkse/arch/powerpc/include/pthread_md.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2004 by Peter Grehan. - * Copyright 2006 Marcel Moolenaar - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent thread prototypes/definitions for the thread kernel. - */ -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <sys/kse.h> -#include <stddef.h> -#include <ucontext.h> - -extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t); -extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *); -extern int _ppc32_getcontext(mcontext_t *); - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv) - -#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL) - -#define PER_THREAD - -struct kcb; -struct kse; -struct pthread; -struct tcb; - -/* - * %r2 points to the following. - */ -struct ppc32_tp { - void *tp_dtv; /* dynamic thread vector */ - uint32_t _reserved_; - double tp_tls[0]; /* static TLS */ -}; - -struct tcb { - struct kse_thr_mailbox tcb_tmbx; - struct pthread *tcb_thread; - struct kcb *tcb_curkcb; - long tcb_isfake; - long tcb_spare[3]; - struct ppc32_tp tcb_tp; -}; - -struct kcb { - struct kse_mailbox kcb_kmbx; - struct kse *kcb_kse; - struct tcb *kcb_curtcb; - struct tcb kcb_faketcb; -}; - -/* - * From the PowerPC32 TLS spec: - * - * "r2 is the thread pointer, and points 0x7000 past the end of the - * thread control block." Or, 0x7008 past the start of the 8-byte tcb - */ -#define TP_OFFSET 0x7008 - -static __inline char * -ppc_get_tp(void) -{ - register char *r2 __asm__("%r2"); - - return (r2 - TP_OFFSET); -} - -static __inline void -ppc_set_tp(char *tp) -{ - register char *r2 __asm__("%r2"); - __asm __volatile("mr %0,%1" : "=r"(r2) : "r"(tp + TP_OFFSET)); -} - -static __inline struct tcb * -ppc_get_tcb(void) -{ - return ((struct tcb *)(ppc_get_tp() - offsetof(struct tcb, tcb_tp))); -} - -static __inline void -ppc_set_tcb(struct tcb *tcb) -{ - ppc_set_tp((char*)&tcb->tcb_tp); -} - -/* - * The kcb and tcb constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *); -struct kcb *_kcb_ctor(struct kse *kse); -void _kcb_dtor(struct kcb *); - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - /* There is no thread yet; use the fake tcb. */ - ppc_set_tcb(&kcb->kcb_faketcb); -} - -/* - * Get the current kcb. - * - * This can only be called while in a critical region; don't - * worry about having the kcb changed out from under us. - */ -static __inline struct kcb * -_kcb_get(void) -{ - return (ppc_get_tcb()->tcb_curkcb); -} - -/* - * Enter a critical region. - * - * Read and clear km_curthread in the kse mailbox. - */ -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - struct tcb *tcb; - uint32_t flags; - - tcb = ppc_get_tcb(); - if (tcb->tcb_isfake != 0) { - /* - * We already are in a critical region since - * there is no current thread. - */ - crit = NULL; - } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread; - tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; - tcb->tcb_tmbx.tm_flags = flags; - } - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - struct tcb *tcb; - - tcb = ppc_get_tcb(); - - /* No need to do anything if this is a fake tcb. */ - if (tcb->tcb_isfake == 0) - tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; -} - -static __inline int -_kcb_in_critical(void) -{ - struct tcb *tcb; - uint32_t flags; - int ret; - - tcb = ppc_get_tcb(); - if (tcb->tcb_isfake != 0) { - /* - * We are in a critical region since there is no - * current thread. - */ - ret = 1; - } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - tcb->tcb_tmbx.tm_flags = flags; - } - return (ret); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - if (tcb == NULL) - tcb = &kcb->kcb_faketcb; - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; - ppc_set_tcb(tcb); -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (ppc_get_tcb()); -} - -static __inline struct pthread * -_get_curthread(void) -{ - return (ppc_get_tcb()->tcb_thread); -} - -/* - * Get the current kse. - * - * Like _kcb_get(), this can only be called while in a critical region. - */ -static __inline struct kse * -_get_curkse(void) -{ - return (ppc_get_tcb()->tcb_curkcb->kcb_kse); -} - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) { - /* Make the fake tcb the current thread. */ - kcb->kcb_curtcb = &kcb->kcb_faketcb; - ppc_set_tcb(&kcb->kcb_faketcb); - _ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size - 32); - /* We should not reach here. */ - return (-1); - } - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - mcontext_t *mc; - extern int _libkse_debug; - - _tcb_set(kcb, tcb); - mc = &tcb->tcb_tmbx.tm_context.uc_mcontext; - - /* - * A full context needs a system call to restore, so use - * kse_switchin. Otherwise, the partial context can be - * restored with _ppc32_setcontext - */ - if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } else { - tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp; - if (setmbox) - _ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread); - else - _ppc32_setcontext(mc, 0, NULL); - } - - /* We should not reach here. */ - return (-1); -} - -#endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libkse/arch/powerpc/powerpc/assym.c b/lib/libkse/arch/powerpc/powerpc/assym.c deleted file mode 100644 index a8479e7..0000000 --- a/lib/libkse/arch/powerpc/powerpc/assym.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2004 Peter Grehan. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* Used to generate mcontext_t offsets */ - -#include <sys/types.h> -#include <sys/assym.h> -#include <sys/ucontext.h> - -#include <stddef.h> - -ASSYM(_MC_VERSION, _MC_VERSION); -ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE); -ASSYM(_MC_FP_VALID, _MC_FP_VALID); - -ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers)); -ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags)); - -ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0])); -ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1])); -ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2])); -ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3])); -ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4])); -ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5])); -ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6])); -ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7])); -ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8])); -ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9])); -ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10])); -ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11])); -ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12])); -ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13])); -ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14])); -ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15])); -ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16])); -ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17])); -ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18])); -ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19])); -ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20])); -ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21])); -ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22])); -ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23])); -ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24])); -ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25])); -ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26])); -ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27])); -ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28])); -ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29])); -ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30])); -ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31])); -ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32])); -ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33])); -ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34])); -ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35])); - -ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32])); -ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0])); -ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1])); -ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2])); -ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3])); -ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4])); -ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5])); -ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6])); -ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7])); -ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8])); -ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9])); -ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10])); -ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11])); -ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12])); -ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13])); -ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14])); -ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15])); -ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16])); -ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17])); -ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18])); -ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19])); -ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20])); -ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21])); -ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22])); -ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23])); -ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24])); -ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25])); -ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26])); -ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27])); -ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28])); -ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29])); -ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30])); -ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31])); diff --git a/lib/libkse/arch/powerpc/powerpc/assym.s b/lib/libkse/arch/powerpc/powerpc/assym.s deleted file mode 100644 index 7017c15..0000000 --- a/lib/libkse/arch/powerpc/powerpc/assym.s +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2004 Peter Grehan. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Struct offsets for version 0x1 of the mcontext struct. - * Generated with - * cc -c assym.c - * ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s - * hand-edit output - */ -#define _MC_VERSION 0x1 -#define _MC_VERSION_KSE 0xee -#define _MC_FP_VALID 0x1 - -#define _MC_VERS 0x0 -#define _MC_FLAGS 0x4 - -#define _MC_R0 0x298 -#define _MC_R1 0x21c -#define _MC_R2 0x220 -#define _MC_R3 0x224 -#define _MC_R4 0x228 -#define _MC_R5 0x22c -#define _MC_R6 0x230 -#define _MC_R7 0x234 -#define _MC_R8 0x238 -#define _MC_R9 0x23c -#define _MC_R10 0x240 -#define _MC_R11 0x244 -#define _MC_R12 0x248 -#define _MC_R13 0x24c -#define _MC_R14 0x250 -#define _MC_R15 0x254 -#define _MC_R16 0x258 -#define _MC_R17 0x25c -#define _MC_R18 0x260 -#define _MC_R19 0x264 -#define _MC_R20 0x268 -#define _MC_R21 0x26c -#define _MC_R22 0x270 -#define _MC_R23 0x274 -#define _MC_R24 0x278 -#define _MC_R25 0x27c -#define _MC_R26 0x280 -#define _MC_R27 0x284 -#define _MC_R28 0x288 -#define _MC_R29 0x28c -#define _MC_R30 0x290 -#define _MC_R31 0x294 -#define _MC_LR 0x298 -#define _MC_CR 0x29c -#define _MC_XER 0x2a0 -#define _MC_CTR 0x2a4 - -#define _MC_FPSCR 0x3c0 -#define _MC_F0 0x2c0 -#define _MC_F1 0x2c8 -#define _MC_F2 0x2d0 -#define _MC_F3 0x2d8 -#define _MC_F4 0x2e0 -#define _MC_F5 0x2e8 -#define _MC_F6 0x2f0 -#define _MC_F7 0x2f8 -#define _MC_F8 0x300 -#define _MC_F9 0x308 -#define _MC_F10 0x310 -#define _MC_F11 0x318 -#define _MC_F12 0x320 -#define _MC_F13 0x328 -#define _MC_F14 0x330 -#define _MC_F15 0x338 -#define _MC_F16 0x340 -#define _MC_F17 0x348 -#define _MC_F18 0x350 -#define _MC_F19 0x358 -#define _MC_F20 0x360 -#define _MC_F21 0x368 -#define _MC_F22 0x370 -#define _MC_F23 0x378 -#define _MC_F24 0x380 -#define _MC_F25 0x388 -#define _MC_F26 0x390 -#define _MC_F27 0x398 -#define _MC_F28 0x3a0 -#define _MC_F29 0x3a8 -#define _MC_F30 0x3b0 -#define _MC_F31 0x3b8 - diff --git a/lib/libkse/arch/powerpc/powerpc/context.S b/lib/libkse/arch/powerpc/powerpc/context.S deleted file mode 100644 index 34d175a..0000000 --- a/lib/libkse/arch/powerpc/powerpc/context.S +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2004 Peter Grehan. - * 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -#include "assym.s" - -/* - * int _ppc32_getcontext(mcontext_t *mcp) - * - * Save register state from a voluntary context switch. - * Only volatile registers, and those needed to complete - * a setcontext call, need to be saved. - * - * r1 - * r14-31 - * f14-31 XXX - * lr - * - * Return 0 for this call, and set up the context so it will return - * 1 when restored with _ppc32_setcontext(). - * - * XXX XXX - * Floating-point is a big issue. Since there's no way to determine - * if the caller has used FP, all volatile register need to be saved. - * If FP hasn't been used, this results in a lazy FP exception in - * the kernel and from that point on FP is always switched in/out - * for the thread, which may be a big performance drag for the system. - * An alternative is to use a system call to get the context, which - * will do the right thing for floating point, but will save all - * registers rather than the caller-saved subset, and has the overhead - * of a syscall. - * Maybe another option would be to give a light-weight way for a - * thread to determine if FP is in used: perhaps a syscall that - * returns in the asm traphandler, or an OSX-style read-only page - * with a flag to indicate FP state. - * - * For now, punt the issue ala Alpha 1:1 model and fix in the future. - */ -ENTRY(_ppc32_getcontext) - stw %r1, _MC_R1(%r3) - stw %r13, _MC_R13(%r3) - stw %r14, _MC_R14(%r3) - stw %r15, _MC_R15(%r3) - stw %r16, _MC_R16(%r3) - stw %r17, _MC_R17(%r3) - stw %r18, _MC_R18(%r3) - stw %r19, _MC_R19(%r3) - stw %r20, _MC_R20(%r3) - stw %r21, _MC_R21(%r3) - stw %r22, _MC_R22(%r3) - stw %r23, _MC_R23(%r3) - stw %r24, _MC_R24(%r3) - stw %r25, _MC_R25(%r3) - stw %r26, _MC_R26(%r3) - stw %r27, _MC_R27(%r3) - stw %r28, _MC_R28(%r3) - stw %r29, _MC_R28(%r3) - stw %r30, _MC_R30(%r3) - stw %r31, _MC_R31(%r3) - mflr %r4 - stw %r4, _MC_LR(%r3) - mfcr %r4 - stw %r4, _MC_CR(%r3) - - /* XXX f14-31 ? */ - - li %r4, _MC_VERSION_KSE /* partial ucontext version */ - stw %r4, _MC_VERS(%r3) - - /* Return 0 */ - li %r3, 0 - blr - -/* - * int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val, - * intptr_t *loc); - * - * Should only be called for partial KSE contexts. The full context - * case is handled by kse_switchin() in _thread_switch() - * - * Returns -1 on error and 1 for return from a saved context - */ - -ENTRY(_ppc32_setcontext) - lwz %r6, _MC_VERS(%r3) - cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */ - beq 1f - li %r3, -1 /* invalid context type, return -1 */ - blr - -1: /* partial format, callee-saved regs assumed */ - lwz %r1, _MC_R1(%r3) - lwz %r13, _MC_R13(%r3) - lwz %r14, _MC_R14(%r3) - lwz %r15, _MC_R15(%r3) - lwz %r16, _MC_R16(%r3) - lwz %r17, _MC_R17(%r3) - lwz %r18, _MC_R18(%r3) - lwz %r19, _MC_R19(%r3) - lwz %r20, _MC_R20(%r3) - lwz %r21, _MC_R21(%r3) - lwz %r22, _MC_R22(%r3) - lwz %r23, _MC_R23(%r3) - lwz %r24, _MC_R24(%r3) - lwz %r25, _MC_R25(%r3) - lwz %r26, _MC_R26(%r3) - lwz %r27, _MC_R27(%r3) - lwz %r28, _MC_R28(%r3) - lwz %r29, _MC_R28(%r3) - lwz %r30, _MC_R30(%r3) - lwz %r31, _MC_R31(%r3) - lwz %r6, _MC_LR(%r3) - mtlr %r6 - lwz %r6, _MC_CR(%r3) - mtcr %r6 - - /* XXX f14-31 ? */ - - /* if (loc != NULL) *loc = val */ - cmpwi %r5, 0 - beq 2f - stw %r4, 0(%r5) - - /* Return 1 */ -2: li %r3, 1 - blr diff --git a/lib/libkse/arch/powerpc/powerpc/pthread_md.c b/lib/libkse/arch/powerpc/powerpc/pthread_md.c deleted file mode 100644 index 7aa5ee9..0000000 --- a/lib/libkse/arch/powerpc/powerpc/pthread_md.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 2006 Marcel Moolenaar - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdlib.h> -#include <strings.h> - -#include "rtld_tls.h" -#include "pthread_md.h" - -/* - * The constructors. - */ -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - struct tcb *tcb; - - tcb = _rtld_allocate_tls((initial) ? ppc_get_tp() : NULL, - sizeof(struct tcb), 8); - if (tcb == NULL) - return (NULL); - tcb->tcb_thread = thread; - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - _rtld_free_tls(tcb, sizeof(struct tcb), 8); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb == NULL) - return (NULL); - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_kse = kse; - kcb->kcb_faketcb.tcb_isfake = 1; - kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_curtcb = &kcb->kcb_faketcb; - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} diff --git a/lib/libkse/arch/sparc64/Makefile.inc b/lib/libkse/arch/sparc64/Makefile.inc deleted file mode 100644 index 988ff06..0000000 --- a/lib/libkse/arch/sparc64/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= pthread_md.c thr_getcontext.S diff --git a/lib/libkse/arch/sparc64/include/atomic_ops.h b/lib/libkse/arch/sparc64/include/atomic_ops.h deleted file mode 100644 index 2264ec2..0000000 --- a/lib/libkse/arch/sparc64/include/atomic_ops.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder <jake@FreeBSD.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _ATOMIC_OPS_H_ -#define _ATOMIC_OPS_H_ - -#include <machine/atomic.h> - -/* - * Atomic swap: - * Atomic (tmp = *dst, *dst = val), then *res = tmp - * - * void atomic_swap_long(long *dst, long val, long *res); - */ -static __inline void -atomic_swap_long(volatile long *dst, long val, long *res) -{ - long tmp; - long r; - - tmp = *dst; - for (;;) { - r = atomic_cas_64(dst, tmp, val); - if (r == tmp) - break; - tmp = r; - } - *res = tmp; -} - -static __inline void -atomic_swap_int(volatile int *dst, int val, int *res) -{ - int tmp; - int r; - - tmp = *dst; - for (;;) { - r = atomic_cas_32(dst, tmp, val); - if (r == tmp) - break; - tmp = r; - } - *res = tmp; -} - -#define atomic_swap_ptr(dst, val, res) \ - atomic_swap_long((volatile long *)dst, (long)val, (long *)res) - -#endif diff --git a/lib/libkse/arch/sparc64/include/pthread_md.h b/lib/libkse/arch/sparc64/include/pthread_md.h deleted file mode 100644 index 47cf001..0000000 --- a/lib/libkse/arch/sparc64/include/pthread_md.h +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>. - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent thread prototypes/definitions for the thread kernel. - */ -#ifndef _PTHREAD_MD_H_ -#define _PTHREAD_MD_H_ - -#include <sys/kse.h> -#include <stddef.h> -#include <ucontext.h> - -#define KSE_STACKSIZE 16384 -#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv) - -int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *); -int _thr_getcontext(mcontext_t *); - -#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL) - -#define PER_THREAD - -struct kcb; -struct kse; -struct pthread; -struct tcb; -struct tdv; /* We don't know what this is yet? */ - - -/* - * %g6 points to one of these. We define the static TLS as an array - * of long double to enforce 16-byte alignment of the TLS memory. - * - * XXX - Both static and dynamic allocation of any of these structures - * will result in a valid, well-aligned thread pointer??? - */ -struct sparc64_tp { - struct tdv *tp_tdv; /* dynamic TLS */ - uint64_t _reserved_; - long double tp_tls[0]; /* static TLS */ -}; - -struct tcb { - struct pthread *tcb_thread; - void *tcb_addr; /* allocated tcb address */ - struct kcb *tcb_curkcb; - uint64_t tcb_isfake; - uint64_t tcb_spare[4]; - struct kse_thr_mailbox tcb_tmbx; /* needs 64-byte alignment */ - struct sparc64_tp tcb_tp; -} __aligned(64); - -struct kcb { - struct kse_mailbox kcb_kmbx; - struct tcb kcb_faketcb; - struct tcb *kcb_curtcb; - struct kse *kcb_kse; -}; - -register struct sparc64_tp *_tp __asm("%g6"); - -#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) - -/* - * The kcb and tcb constructors. - */ -struct tcb *_tcb_ctor(struct pthread *, int); -void _tcb_dtor(struct tcb *); -struct kcb *_kcb_ctor(struct kse *kse); -void _kcb_dtor(struct kcb *); - -/* Called from the KSE to set its private data. */ -static __inline void -_kcb_set(struct kcb *kcb) -{ - /* There is no thread yet; use the fake tcb. */ - _tp = &kcb->kcb_faketcb.tcb_tp; -} - -/* - * Get the current kcb. - * - * This can only be called while in a critical region; don't - * worry about having the kcb changed out from under us. - */ -static __inline struct kcb * -_kcb_get(void) -{ - return (_tcb->tcb_curkcb); -} - -/* - * Enter a critical region. - * - * Read and clear km_curthread in the kse mailbox. - */ -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - uint32_t flags; - - if (_tcb->tcb_isfake != 0) { - /* - * We already are in a critical region since - * there is no current thread. - */ - crit = NULL; - } else { - flags = _tcb->tcb_tmbx.tm_flags; - _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread; - _tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; - _tcb->tcb_tmbx.tm_flags = flags; - } - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - /* No need to do anything if this is a fake tcb. */ - if (_tcb->tcb_isfake == 0) - _tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; -} - -static __inline int -_kcb_in_critical(void) -{ - uint32_t flags; - int ret; - - if (_tcb->tcb_isfake != 0) { - /* - * We are in a critical region since there is no - * current thread. - */ - ret = 1; - } else { - flags = _tcb->tcb_tmbx.tm_flags; - _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - _tcb->tcb_tmbx.tm_flags = flags; - } - return (ret); -} - -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - if (tcb == NULL) - tcb = &kcb->kcb_faketcb; - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; - _tp = &tcb->tcb_tp; -} - -static __inline struct tcb * -_tcb_get(void) -{ - return (_tcb); -} - -static __inline struct pthread * -_get_curthread(void) -{ - return (_tcb->tcb_thread); -} - -/* - * Get the current kse. - * - * Like _kcb_get(), this can only be called while in a critical region. - */ -static __inline struct kse * -_get_curkse(void) -{ - return (_tcb->tcb_curkcb->kcb_kse); -} - -void _sparc64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack, - size_t stacksz); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - if (_thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) { - /* Make the fake tcb the current thread. */ - kcb->kcb_curtcb = &kcb->kcb_faketcb; - _tp = &kcb->kcb_faketcb.tcb_tp; - _sparc64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - extern int _libkse_debug; - mcontext_t *mc; - - _tcb_set(kcb, tcb); - mc = &tcb->tcb_tmbx.tm_context.uc_mcontext; - if (_libkse_debug == 0) { - tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp; - if (setmbox) - _thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread); - else - _thr_setcontext(mc, 0, NULL); - } else { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } - - /* We should not reach here. */ - return (-1); -} - -#endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libkse/arch/sparc64/sparc64/assym.s b/lib/libkse/arch/sparc64/sparc64/assym.s deleted file mode 100644 index 3e22c9f..0000000 --- a/lib/libkse/arch/sparc64/sparc64/assym.s +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Offsets into structures used from asm. Must be kept in sync with - * appropriate headers. - * - * $FreeBSD$ - */ - -#define UC_MCONTEXT 0x40 - -#define MC_FLAGS 0x0 -#define MC_VALID_FLAGS 0x1 -#define MC_GLOBAL 0x0 -#define MC_OUT 0x40 -#define MC_TPC 0xc8 -#define MC_TNPC 0xc0 diff --git a/lib/libkse/arch/sparc64/sparc64/pthread_md.c b/lib/libkse/arch/sparc64/sparc64/pthread_md.c deleted file mode 100644 index d6bf95d..0000000 --- a/lib/libkse/arch/sparc64/sparc64/pthread_md.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (C) 2003 Jake Burkholder <jake@freebsd.org> - * Copyright (C) 2003 David Xu <davidxu@freebsd.org> - * Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> - -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <ucontext.h> - -#include "pthread_md.h" - -struct tcb * -_tcb_ctor(struct pthread *thread, int initial) -{ - struct tcb *tcb; - void *addr; - - addr = malloc(sizeof(struct tcb) + 63); - if (addr == NULL) - tcb = NULL; - else { - tcb = (struct tcb *)(((uintptr_t)(addr) + 63) & ~63); - bzero(tcb, sizeof(struct tcb)); - tcb->tcb_addr = addr; - tcb->tcb_thread = thread; - /* XXX - Allocate tdv/tls */ - } - return (tcb); -} - -void -_tcb_dtor(struct tcb *tcb) -{ - void *addr; - - addr = tcb->tcb_addr; - tcb->tcb_addr = NULL; - free(addr); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - kcb = malloc(sizeof(struct kcb)); - if (kcb != NULL) { - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_faketcb.tcb_isfake = 1; - kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_curtcb = &kcb->kcb_faketcb; - kcb->kcb_kse = kse; - } - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); -} diff --git a/lib/libkse/arch/sparc64/sparc64/thr_getcontext.S b/lib/libkse/arch/sparc64/sparc64/thr_getcontext.S deleted file mode 100644 index ca6473a..0000000 --- a/lib/libkse/arch/sparc64/sparc64/thr_getcontext.S +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (C) 2003 Jake Burkholder <jake@freebsd.org> - * 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. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <machine/asm.h> -__FBSDID("$FreeBSD$"); - -#include "assym.s" - - .weak CNAME(_thr_getcontext) - .set CNAME(_thr_getcontext),CNAME(__thr_getcontext) -ENTRY(__thr_getcontext) - add %o7, 8, %o1 - add %o1, 4, %o2 - stx %sp, [%o0 + MC_OUT + (6 * 8)] - stx %o1, [%o0 + MC_TPC] - stx %o2, [%o0 + MC_TNPC] - mov MC_VALID_FLAGS, %l0 /* Validate the context. */ - stx %l0, [%o0 + MC_FLAGS] - mov 1, %l0 - stx %l0, [%o0 + MC_OUT + (0 * 8)] /* return 1 when resumed */ - retl - mov 0, %o0 /* return 0 */ -END(__thr_getcontext) - - .weak CNAME(_thr_setcontext) - .set CNAME(_thr_setcontext),CNAME(__thr_setcontext) -ENTRY(__thr_setcontext) - save %sp, -CCFSZ, %sp - flushw - mov %i0, %l0 - mov %i1, %l1 - mov %i2, %l2 - ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1 - ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2 - ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3 - ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4 - ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5 - ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6 - ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7 - ldx [%l0 + MC_OUT + (0 * 8)], %i0 - ldx [%l0 + MC_OUT + (1 * 8)], %i1 - ldx [%l0 + MC_OUT + (2 * 8)], %i2 - ldx [%l0 + MC_OUT + (3 * 8)], %i3 - ldx [%l0 + MC_OUT + (4 * 8)], %i4 - ldx [%l0 + MC_OUT + (5 * 8)], %i5 - ldx [%l0 + MC_OUT + (6 * 8)], %i6 - ldx [%l0 + MC_OUT + (7 * 8)], %i7 - ldx [%l0 + MC_TPC], %l4 - ldx [%l0 + MC_TNPC], %l3 - brz %l2, 1f - nop - stx %l1, [%l2] -1: jmpl %l3, %g0 - return %l4 -END(__thr_setcontext) - -ENTRY(_sparc64_enter_uts) - save %sp, -CCFSZ, %sp - flushw - add %i2, %i3, %i2 - sub %i2, SPOFF + CCFSZ, %sp - jmpl %i0, %g0 - mov %i1, %o0 -END(_sparc64_enter_uts) diff --git a/lib/libkse/kse.map b/lib/libkse/kse.map deleted file mode 100644 index a6eed69..0000000 --- a/lib/libkse/kse.map +++ /dev/null @@ -1,367 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Use the same naming scheme as libc. - */ -FBSD_1.0 { - __error; - accept; - aio_suspend; - close; - connect; - creat; - execve; - fcntl; - fork; - fsync; - msync; - nanosleep; - open; - pause; - poll; - pselect; - pthread_atfork; - pthread_barrier_destroy; - pthread_barrier_init; - pthread_barrier_wait; - pthread_barrierattr_destroy; - pthread_barrierattr_getpshared; - pthread_barrierattr_init; - pthread_barrierattr_setpshared; - pthread_attr_destroy; - pthread_attr_get_np; - pthread_attr_getdetachstate; - pthread_attr_getguardsize; - pthread_attr_getinheritsched; - pthread_attr_getschedparam; - pthread_attr_getschedpolicy; - pthread_attr_getscope; - pthread_attr_getstack; - pthread_attr_getstackaddr; - pthread_attr_getstacksize; - pthread_attr_init; - pthread_attr_setcreatesuspend_np; - pthread_attr_setdetachstate; - pthread_attr_setguardsize; - pthread_attr_setinheritsched; - pthread_attr_setschedparam; - pthread_attr_setschedpolicy; - pthread_attr_setscope; - pthread_attr_setstack; - pthread_attr_setstackaddr; - pthread_attr_setstacksize; - pthread_cancel; - pthread_cleanup_pop; - pthread_cleanup_push; - pthread_cond_broadcast; - pthread_cond_destroy; - pthread_cond_init; - pthread_cond_signal; - pthread_cond_timedwait; - pthread_cond_wait; - pthread_condattr_destroy; - pthread_condattr_init; - pthread_create; - pthread_detach; - pthread_equal; - pthread_exit; - pthread_getconcurrency; - pthread_getprio; - pthread_getschedparam; - pthread_getspecific; - pthread_join; - pthread_key_create; - pthread_key_delete; - pthread_kill; - pthread_main_np; - pthread_multi_np; - pthread_mutex_destroy; - pthread_mutex_getprioceiling; - pthread_mutex_init; - pthread_mutex_lock; - pthread_mutex_setprioceiling; - pthread_mutex_timedlock; - pthread_mutex_trylock; - pthread_mutex_unlock; - pthread_mutexattr_destroy; - pthread_mutexattr_getkind_np; - pthread_mutexattr_getprioceiling; - pthread_mutexattr_getprotocol; - pthread_mutexattr_gettype; - pthread_mutexattr_init; - pthread_mutexattr_setkind_np; - pthread_mutexattr_setprioceiling; - pthread_mutexattr_setprotocol; - pthread_mutexattr_settype; - pthread_once; - pthread_resume_all_np; - pthread_resume_np; - pthread_rwlock_destroy; - pthread_rwlock_init; - pthread_rwlock_rdlock; - pthread_rwlock_timedrdlock; - pthread_rwlock_timedwrlock; - pthread_rwlock_tryrdlock; - pthread_rwlock_trywrlock; - pthread_rwlock_unlock; - pthread_rwlock_wrlock; - pthread_rwlockattr_destroy; - pthread_rwlockattr_getpshared; - pthread_rwlockattr_init; - pthread_rwlockattr_setpshared; - pthread_self; - pthread_set_name_np; - pthread_setcancelstate; - pthread_setcanceltype; - pthread_setconcurrency; - pthread_setprio; - pthread_setschedparam; - pthread_setspecific; - pthread_sigmask; - pthread_single_np; - pthread_spin_destroy; - pthread_spin_init; - pthread_spin_lock; - pthread_spin_trylock; - pthread_spin_unlock; - pthread_suspend_all_np; - pthread_suspend_np; - pthread_switch_add_np; - pthread_switch_delete_np; - pthread_testcancel; - pthread_yield; - raise; - read; - readv; - sched_yield; - select; - sem_init; - sem_post; - sem_timedwait; - sem_wait; - sigaction; - sigaltstack; - sigpending; - sigprocmask; - sigsuspend; - sigwait; - sigwaitinfo; - sigtimedwait; - sleep; - system; - tcdrain; - usleep; - vfork; - wait4; - wait; - waitpid; - write; - writev; -}; - -/* - * List the private interfaces reserved for use in FreeBSD libraries. - * These are not part of our application ABI. - */ -FBSDprivate_1.0 { - ___creat; - __accept; - __close; - __connect; - __fcntl; - __fsync; - __msync; - __nanosleep; - __open; - __poll; - __pthread_cond_timedwait; - __pthread_cond_wait; - __pthread_mutex_init; - __pthread_mutex_lock; - __pthread_mutex_trylock; - __pthread_mutex_timedlock; - __read; - __readv; - __select; - __sigsuspend; - __sigtimedwait; - __sigwait; - __sigwaitinfo; - __wait4; - __write; - __writev; - _aio_suspend; - _execve; - _fork; - _nanosleep; - _pause; - _pselect; - _pthread_atfork; - _pthread_barrier_destroy; - _pthread_barrier_init; - _pthread_barrier_wait; - _pthread_barrierattr_destroy; - _pthread_barrierattr_getpshared; - _pthread_barrierattr_init; - _pthread_barrierattr_setpshared; - _pthread_attr_destroy; - _pthread_attr_get_np; - _pthread_attr_getdetachstate; - _pthread_attr_getguardsize; - _pthread_attr_getinheritsched; - _pthread_attr_getschedparam; - _pthread_attr_getschedpolicy; - _pthread_attr_getscope; - _pthread_attr_getstack; - _pthread_attr_getstackaddr; - _pthread_attr_getstacksize; - _pthread_attr_init; - _pthread_attr_setcreatesuspend_np; - _pthread_attr_setdetachstate; - _pthread_attr_setguardsize; - _pthread_attr_setinheritsched; - _pthread_attr_setschedparam; - _pthread_attr_setschedpolicy; - _pthread_attr_setscope; - _pthread_attr_setstack; - _pthread_attr_setstackaddr; - _pthread_attr_setstacksize; - _pthread_cancel; - _pthread_cleanup_pop; - _pthread_cleanup_push; - _pthread_cond_broadcast; - _pthread_cond_destroy; - _pthread_cond_init; - _pthread_cond_signal; - _pthread_cond_timedwait; - _pthread_cond_wait; - _pthread_condattr_default; - _pthread_condattr_destroy; - _pthread_condattr_init; - _pthread_create; - _pthread_detach; - _pthread_equal; - _pthread_exit; - _pthread_getconcurrency; - _pthread_getprio; - _pthread_getschedparam; - _pthread_getspecific; - _pthread_join; - _pthread_key_create; - _pthread_key_delete; - _pthread_kill; - _pthread_main_np; - _pthread_multi_np; - _pthread_mutex_destroy; - _pthread_mutex_getprioceiling; - _pthread_mutex_init; - _pthread_mutex_init_calloc_cb; - _pthread_mutex_isowned_np; - _pthread_mutex_lock; - _pthread_mutex_setprioceiling; - _pthread_mutex_timedlock; - _pthread_mutex_trylock; - _pthread_mutex_unlock; - _pthread_mutexattr_default; - _pthread_mutexattr_destroy; - _pthread_mutexattr_getkind_np; - _pthread_mutexattr_getprioceiling; - _pthread_mutexattr_getprotocol; - _pthread_mutexattr_gettype; - _pthread_mutexattr_init; - _pthread_mutexattr_setkind_np; - _pthread_mutexattr_setprioceiling; - _pthread_mutexattr_setprotocol; - _pthread_mutexattr_settype; - _pthread_once; - _pthread_resume_all_np; - _pthread_resume_np; - _pthread_rwlock_destroy; - _pthread_rwlock_init; - _pthread_rwlock_rdlock; - _pthread_rwlock_timedrdlock; - _pthread_rwlock_timedwrlock; - _pthread_rwlock_tryrdlock; - _pthread_rwlock_trywrlock; - _pthread_rwlock_unlock; - _pthread_rwlock_wrlock; - _pthread_rwlockattr_destroy; - _pthread_rwlockattr_getpshared; - _pthread_rwlockattr_init; - _pthread_rwlockattr_setpshared; - _pthread_self; - _pthread_set_name_np; - _pthread_setcancelstate; - _pthread_setcanceltype; - _pthread_setconcurrency; - _pthread_setprio; - _pthread_setschedparam; - _pthread_setspecific; - _pthread_sigmask; - _pthread_single_np; - _pthread_spin_destroy; - _pthread_spin_init; - _pthread_spin_lock; - _pthread_spin_trylock; - _pthread_spin_unlock; - _pthread_suspend_all_np; - _pthread_suspend_np; - _pthread_switch_add_np; - _pthread_switch_delete_np; - _pthread_testcancel; - _pthread_yield; - _raise; - _sched_yield; - _sem_init; - _sem_post; - _sem_timedwait; - _sem_wait; - _sigaction; - _sigaltstack; - _sigpending; - _sigprocmask; - _sigsuspend; - _sigtimedwait; - _sigwait; - _sigwaitinfo; - _sleep; - _spinlock; - _spinlock_debug; - _spinunlock; - _system; - _tcdrain; - _usleep; - _vfork; - _wait; - _waitpid; - - /* Debugger needs these. */ - _libkse_debug; - _thread_activated; - _thread_active_threads; - _thread_keytable; - _thread_list; - _thread_max_keys; - _thread_off_attr_flags; - _thread_off_dtv; - _thread_off_linkmap; - _thread_off_next; - _thread_off_tcb; - _thread_off_tmbx; - _thread_off_key_allocated; - _thread_off_key_destructor; - _thread_off_kse; - _thread_off_kse_locklevel; - _thread_off_sigmask; - _thread_off_sigpend; - _thread_off_state; - _thread_off_thr_locklevel; - _thread_off_tlsindex; - _thread_size_key; - _thread_state_running; - _thread_state_zoombie; -}; - -FBSD_1.1 { - pthread_mutex_isowned_np; -}; diff --git a/lib/libkse/support/Makefile.inc b/lib/libkse/support/Makefile.inc deleted file mode 100644 index 6542f7a..0000000 --- a/lib/libkse/support/Makefile.inc +++ /dev/null @@ -1,40 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/support ${.CURDIR}/../libc/gen ${.CURDIR}/../libc/string -.PATH: ${.CURDIR}/../libc/${MACHINE_CPUARCH}/sys - -CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_CPUARCH} - -SYSCALLS= clock_gettime \ - kse_create \ - kse_exit \ - kse_release \ - kse_switchin \ - kse_thr_interrupt \ - kse_wakeup \ - sigaction \ - sigprocmask \ - sigtimedwait \ - write - -SYSCALL_SRC= ${SYSCALLS:S/$/.S/} -SYSCALL_OBJ= ${SYSCALLS:S/$/.So/} - -${SYSCALL_SRC}: - printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET} - -LIBC_OBJS= sigsetops.So \ - bcopy.So \ - bzero.So \ - cerror.So \ - memcpy.So \ - memset.So \ - strcpy.So \ - strlen.So - -SOBJS+= thr_libc.So -CLEANFILES+= ${SYSCALL_SRC} ${SYSCALL_OBJ} ${LIBC_OBJS} - -thr_libc.So: ${SYSCALL_OBJ} ${LIBC_OBJS} - ${CC} -fPIC -nostdlib -o ${.TARGET} -r ${.ALLSRC} - diff --git a/lib/libkse/support/thr_support.c b/lib/libkse/support/thr_support.c deleted file mode 100644 index 2956e07..0000000 --- a/lib/libkse/support/thr_support.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright 2003 Alexander Kabaev. - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/cdefs.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/kse.h> -#include <signal.h> -#include <string.h> - -#include "thr_private.h" - -__strong_reference(clock_gettime, _thr_clock_gettime); -__strong_reference(kse_exit, _thr_kse_exit); -__strong_reference(kse_wakeup, _thr_kse_wakeup); -__strong_reference(kse_create, _thr_kse_create); -__strong_reference(kse_thr_interrupt, _thr_kse_thr_interrupt); -__strong_reference(kse_release, _thr_kse_release); -__strong_reference(kse_switchin, _thr_kse_switchin); - -__strong_reference(sigaction, _thr_sigaction); -__strong_reference(sigprocmask, _thr_sigprocmask); -__strong_reference(sigemptyset, _thr_sigemptyset); -__strong_reference(sigaddset, _thr_sigaddset); -__strong_reference(sigfillset, _thr_sigfillset); -__strong_reference(sigismember, _thr_sigismember); -__strong_reference(sigdelset, _thr_sigdelset); - -__strong_reference(memset, _thr_memset); -__strong_reference(memcpy, _thr_memcpy); -__strong_reference(strcpy, _thr_strcpy); -__strong_reference(strlen, _thr_strlen); -__strong_reference(bzero, _thr_bzero); -__strong_reference(bcopy, _thr_bcopy); - -__strong_reference(__sys_write, _thr__sys_write); -__strong_reference(__sys_sigtimedwait, _thr__sys_sigtimedwait); - diff --git a/lib/libkse/sys/Makefile.inc b/lib/libkse/sys/Makefile.inc deleted file mode 100644 index fb4a108..0000000 --- a/lib/libkse/sys/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/sys - -SRCS+= lock.c thr_error.c diff --git a/lib/libkse/sys/lock.c b/lib/libkse/sys/lock.c deleted file mode 100644 index 3620f31..0000000 --- a/lib/libkse/sys/lock.c +++ /dev/null @@ -1,362 +0,0 @@ -/*- - * Copyright (c) 2001, 2003 Daniel Eischen <deischen@freebsd.org>. - * 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/types.h> -#include <machine/atomic.h> -#include <assert.h> -#include <stdlib.h> - -#include "atomic_ops.h" -#include "lock.h" - -#ifdef _LOCK_DEBUG -#define LCK_ASSERT(e) assert(e) -#else -#define LCK_ASSERT(e) -#endif - -#define MAX_SPINS 500 - -void -_lock_destroy(struct lock *lck) -{ - if ((lck != NULL) && (lck->l_head != NULL)) { - free(lck->l_head); - lck->l_head = NULL; - lck->l_tail = NULL; - } -} - -int -_lock_init(struct lock *lck, enum lock_type ltype, - lock_handler_t *waitfunc, lock_handler_t *wakeupfunc, - void *(calloc_cb)(size_t, size_t)) -{ - if (lck == NULL) - return (-1); - else if ((lck->l_head = calloc_cb(1, sizeof(struct lockreq))) == NULL) - return (-1); - else { - lck->l_type = ltype; - lck->l_wait = waitfunc; - lck->l_wakeup = wakeupfunc; - lck->l_head->lr_locked = 0; - lck->l_head->lr_watcher = NULL; - lck->l_head->lr_owner = NULL; - lck->l_head->lr_active = 1; - lck->l_tail = lck->l_head; - } - return (0); -} - -int -_lock_reinit(struct lock *lck, enum lock_type ltype, - lock_handler_t *waitfunc, lock_handler_t *wakeupfunc) -{ - if (lck == NULL) - return (-1); - else if (lck->l_head == NULL) - return (_lock_init(lck, ltype, waitfunc, wakeupfunc, calloc)); - else { - lck->l_head->lr_locked = 0; - lck->l_head->lr_watcher = NULL; - lck->l_head->lr_owner = NULL; - lck->l_head->lr_active = 1; - lck->l_tail = lck->l_head; - } - return (0); -} - -int -_lockuser_init(struct lockuser *lu, void *priv) -{ - if (lu == NULL) - return (-1); - else if ((lu->lu_myreq == NULL) && - ((lu->lu_myreq = malloc(sizeof(struct lockreq))) == NULL)) - return (-1); - else { - lu->lu_myreq->lr_locked = 1; - lu->lu_myreq->lr_watcher = NULL; - lu->lu_myreq->lr_owner = lu; - lu->lu_myreq->lr_active = 0; - lu->lu_watchreq = NULL; - lu->lu_priority = 0; - lu->lu_private = priv; - lu->lu_private2 = NULL; - } - return (0); -} - -int -_lockuser_reinit(struct lockuser *lu, void *priv) -{ - if (lu == NULL) - return (-1); - if (lu->lu_watchreq != NULL) { - /* - * In this case the lock is active. All lockusers - * keep their watch request and drop their own - * (lu_myreq) request. Their own request is either - * some other lockuser's watch request or is the - * head of the lock. - */ - lu->lu_myreq = lu->lu_watchreq; - lu->lu_watchreq = NULL; - } - if (lu->lu_myreq == NULL) - /* - * Oops, something isn't quite right. Try to - * allocate one. - */ - return (_lockuser_init(lu, priv)); - else { - lu->lu_myreq->lr_locked = 1; - lu->lu_myreq->lr_watcher = NULL; - lu->lu_myreq->lr_owner = lu; - lu->lu_myreq->lr_active = 0; - lu->lu_watchreq = NULL; - lu->lu_priority = 0; - lu->lu_private = priv; - lu->lu_private2 = NULL; - } - return (0); -} - -void -_lockuser_destroy(struct lockuser *lu) -{ - if ((lu != NULL) && (lu->lu_myreq != NULL)) - free(lu->lu_myreq); -} - -/* - * Acquire a lock waiting (spin or sleep) for it to become available. - */ -void -_lock_acquire(struct lock *lck, struct lockuser *lu, int prio) -{ - int i; - int lval; - - /** - * XXX - We probably want to remove these checks to optimize - * performance. It is also a bug if any one of the - * checks fail, so it's probably better to just let it - * SEGV and fix it. - */ -#if 0 - if (lck == NULL || lu == NULL || lck->l_head == NULL) - return; -#endif - if ((lck->l_type & LCK_PRIORITY) != 0) { - LCK_ASSERT(lu->lu_myreq->lr_locked == 1); - LCK_ASSERT(lu->lu_myreq->lr_watcher == NULL); - LCK_ASSERT(lu->lu_myreq->lr_owner == lu); - LCK_ASSERT(lu->lu_watchreq == NULL); - - lu->lu_priority = prio; - } - /* - * Atomically swap the head of the lock request with - * this request. - */ - atomic_swap_ptr((void *)&lck->l_head, lu->lu_myreq, - (void *)&lu->lu_watchreq); - - if (lu->lu_watchreq->lr_locked != 0) { - atomic_store_rel_ptr - ((volatile uintptr_t *)(void *)&lu->lu_watchreq->lr_watcher, - (uintptr_t)lu); - if ((lck->l_wait == NULL) || - ((lck->l_type & LCK_ADAPTIVE) == 0)) { - while (lu->lu_watchreq->lr_locked != 0) - ; /* spin, then yield? */ - } else { - /* - * Spin for a bit before invoking the wait function. - * - * We should be a little smarter here. If we're - * running on a single processor, then the lock - * owner got preempted and spinning will accomplish - * nothing but waste time. If we're running on - * multiple processors, the owner could be running - * on another CPU and we might acquire the lock if - * we spin for a bit. - * - * The other thing to keep in mind is that threads - * acquiring these locks are considered to be in - * critical regions; they will not be preempted by - * the _UTS_ until they release the lock. It is - * therefore safe to assume that if a lock can't - * be acquired, it is currently held by a thread - * running in another KSE. - */ - for (i = 0; i < MAX_SPINS; i++) { - if (lu->lu_watchreq->lr_locked == 0) - return; - if (lu->lu_watchreq->lr_active == 0) - break; - } - atomic_swap_int(&lu->lu_watchreq->lr_locked, - 2, &lval); - if (lval == 0) - lu->lu_watchreq->lr_locked = 0; - else - lck->l_wait(lck, lu); - - } - } - lu->lu_myreq->lr_active = 1; -} - -/* - * Release a lock. - */ -void -_lock_release(struct lock *lck, struct lockuser *lu) -{ - struct lockuser *lu_tmp, *lu_h; - struct lockreq *myreq; - int prio_h; - int lval; - - /** - * XXX - We probably want to remove these checks to optimize - * performance. It is also a bug if any one of the - * checks fail, so it's probably better to just let it - * SEGV and fix it. - */ -#if 0 - if ((lck == NULL) || (lu == NULL)) - return; -#endif - if ((lck->l_type & LCK_PRIORITY) != 0) { - prio_h = 0; - lu_h = NULL; - - /* Update tail if our request is last. */ - if (lu->lu_watchreq->lr_owner == NULL) { - atomic_store_rel_ptr((volatile uintptr_t *) - (void *)&lck->l_tail, - (uintptr_t)lu->lu_myreq); - atomic_store_rel_ptr((volatile uintptr_t *) - (void *)&lu->lu_myreq->lr_owner, - (uintptr_t)NULL); - } else { - /* Remove ourselves from the list. */ - atomic_store_rel_ptr((volatile uintptr_t *) - (void *)&lu->lu_myreq->lr_owner, - (uintptr_t)lu->lu_watchreq->lr_owner); - atomic_store_rel_ptr((volatile uintptr_t *) - (void *)&lu->lu_watchreq->lr_owner->lu_myreq, - (uintptr_t)lu->lu_myreq); - } - /* - * The watch request now becomes our own because we've - * traded away our previous request. Save our previous - * request so that we can grant the lock. - */ - myreq = lu->lu_myreq; - lu->lu_myreq = lu->lu_watchreq; - lu->lu_watchreq = NULL; - lu->lu_myreq->lr_locked = 1; - lu->lu_myreq->lr_owner = lu; - lu->lu_myreq->lr_watcher = NULL; - /* - * Traverse the list of lock requests in reverse order - * looking for the user with the highest priority. - */ - for (lu_tmp = lck->l_tail->lr_watcher; lu_tmp != NULL; - lu_tmp = lu_tmp->lu_myreq->lr_watcher) { - if (lu_tmp->lu_priority > prio_h) { - lu_h = lu_tmp; - prio_h = lu_tmp->lu_priority; - } - } - if (lu_h != NULL) { - /* Give the lock to the highest priority user. */ - if (lck->l_wakeup != NULL) { - atomic_swap_int( - &lu_h->lu_watchreq->lr_locked, - 0, &lval); - if (lval == 2) - /* Notify the sleeper */ - lck->l_wakeup(lck, - lu_h->lu_myreq->lr_watcher); - } - else - atomic_store_rel_int( - &lu_h->lu_watchreq->lr_locked, 0); - } else { - if (lck->l_wakeup != NULL) { - atomic_swap_int(&myreq->lr_locked, - 0, &lval); - if (lval == 2) - /* Notify the sleeper */ - lck->l_wakeup(lck, myreq->lr_watcher); - } - else - /* Give the lock to the previous request. */ - atomic_store_rel_int(&myreq->lr_locked, 0); - } - } else { - /* - * The watch request now becomes our own because we've - * traded away our previous request. Save our previous - * request so that we can grant the lock. - */ - myreq = lu->lu_myreq; - lu->lu_myreq = lu->lu_watchreq; - lu->lu_watchreq = NULL; - lu->lu_myreq->lr_locked = 1; - if (lck->l_wakeup) { - atomic_swap_int(&myreq->lr_locked, 0, &lval); - if (lval == 2) - /* Notify the sleeper */ - lck->l_wakeup(lck, myreq->lr_watcher); - } - else - /* Give the lock to the previous request. */ - atomic_store_rel_int(&myreq->lr_locked, 0); - } - lu->lu_myreq->lr_active = 0; -} - -void -_lock_grant(struct lock *lck __unused /* unused */, struct lockuser *lu) -{ - atomic_store_rel_int(&lu->lu_watchreq->lr_locked, 3); -} - -void -_lockuser_setactive(struct lockuser *lu, int active) -{ - lu->lu_myreq->lr_active = active; -} - diff --git a/lib/libkse/sys/lock.h b/lib/libkse/sys/lock.h deleted file mode 100644 index 815e444..0000000 --- a/lib/libkse/sys/lock.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2001, 2003 Daniel Eischen <deischen@freebsd.org>. - * 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LOCK_H_ -#define _LOCK_H_ - -struct lockreq; -struct lockuser; -struct lock; - -enum lock_type { - LCK_DEFAULT = 0x0000, /* default is FIFO spin locks */ - LCK_PRIORITY = 0x0001, - LCK_ADAPTIVE = 0x0002 /* call user-supplied handlers */ -}; - -typedef void lock_handler_t(struct lock *, struct lockuser *); - -struct lock { - struct lockreq *l_head; - struct lockreq *l_tail; /* only used for priority locks */ - enum lock_type l_type; - lock_handler_t *l_wait; /* only used for adaptive locks */ - lock_handler_t *l_wakeup; /* only used for adaptive locks */ -}; - -/* Try to make this >= CACHELINESIZE */ -struct lockreq { - struct lockuser *lr_watcher; /* only used for priority locks */ - struct lockuser *lr_owner; /* only used for priority locks */ - volatile int lr_locked; /* lock granted = 0, busy otherwise */ - volatile int lr_active; /* non-zero if the lock is last lock for thread */ -}; - -struct lockuser { - struct lockreq *lu_myreq; /* request to give up/trade */ - struct lockreq *lu_watchreq; /* watch this request */ - int lu_priority; /* only used for priority locks */ - void *lu_private1; /* private{1,2} are initialized to */ - void *lu_private2; /* NULL and can be used by caller */ -#define lu_private lu_private1 -}; - -#define _LCK_INITIALIZER(lck_req) { &lck_req, NULL, LCK_DEFAULT, \ - NULL, NULL } -#define _LCK_REQUEST_INITIALIZER { 0, NULL, NULL, 0 } - -#define _LCK_BUSY(lu) ((lu)->lu_watchreq->lr_locked != 0) -#define _LCK_ACTIVE(lu) ((lu)->lu_watchreq->lr_active != 0) -#define _LCK_GRANTED(lu) ((lu)->lu_watchreq->lr_locked == 3) - -#define _LCK_SET_PRIVATE(lu, p) (lu)->lu_private = (void *)(p) -#define _LCK_GET_PRIVATE(lu) (lu)->lu_private -#define _LCK_SET_PRIVATE2(lu, p) (lu)->lu_private2 = (void *)(p) -#define _LCK_GET_PRIVATE2(lu) (lu)->lu_private2 - -void _lock_acquire(struct lock *, struct lockuser *, int); -void _lock_destroy(struct lock *); -void _lock_grant(struct lock *, struct lockuser *); -int _lock_init(struct lock *, enum lock_type, - lock_handler_t *, lock_handler_t *, void *(size_t, size_t)); -int _lock_reinit(struct lock *, enum lock_type, - lock_handler_t *, lock_handler_t *); -void _lock_release(struct lock *, struct lockuser *); -int _lockuser_init(struct lockuser *lu, void *priv); -void _lockuser_destroy(struct lockuser *lu); -int _lockuser_reinit(struct lockuser *lu, void *priv); -void _lockuser_setactive(struct lockuser *lu, int active); - -#endif diff --git a/lib/libkse/sys/thr_error.c b/lib/libkse/sys/thr_error.c deleted file mode 100644 index eaaf27b..0000000 --- a/lib/libkse/sys/thr_error.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell - * and Chris Provenzano. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <errno.h> -#include <pthread.h> -#include "libc_private.h" -#include "thr_private.h" - -#undef errno -extern int errno; - -int * -__error(void) -{ - struct pthread *curthread; - - if (__isthreaded == 0) - return (&errno); - else if (_kse_in_critical()) - return &(_get_curkse()->k_error); - else { - curthread = _get_curthread(); - if ((curthread == NULL) || (curthread == _thr_initial)) - return (&errno); - else - return (&curthread->error); - } -} diff --git a/lib/libkse/test/Makefile b/lib/libkse/test/Makefile deleted file mode 100644 index 5b5eb3c..0000000 --- a/lib/libkse/test/Makefile +++ /dev/null @@ -1,116 +0,0 @@ -# -# $FreeBSD$ -# -# Automated test suite for libpthread (pthreads). -# - -# File lists. - -# Tests written in C. -CTESTS := hello_d.c hello_s.c join_leak_d.c mutex_d.c sem_d.c sigsuspend_d.c \ - sigwait_d.c - -# C programs that are used internally by the tests. The build system merely -# compiles these. -BTESTS := guard_b.c hello_b.c - -# Tests written in perl. -PTESTS := guard_s.pl propagate_s.pl - -# Munge the file lists to their final executable names (strip the .c). -CTESTS := $(CTESTS:R) -BTESTS := $(BTESTS:R) - -CPPFLAGS := -D_LIBC_R_ -D_REENTRANT -CFLAGS := -Wall -pipe -g3 -LDFLAGS_A := -static -LDFLAGS_P := -pg -LDFLAGS_S := -LIBS := -lpthread - -# Flags passed to verify. "-v" or "-u" may be useful. -VERIFY = perl verify -VFLAGS := - -all : default - -# Only use the following suffixes, in order to avoid any strange built-in rules. -.SUFFIXES : -.SUFFIXES : .c .o .d .pl - -# Clear out all paths, then set just one (default path) for the main build -# directory. -.PATH : -.PATH : . - -# Build the C programs. -.for bin in $(CTESTS) $(BTESTS) -$(bin)_a : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_A) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_a.o \2/g\" > $(@:R:S/$/&.d/)" - -$(bin)_p : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_P) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_p.o \2/g\" > $(@:R:S/$/&.d/)" - -$(bin)_s : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_S) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_s.o \2/g\" > $(@:R:S/$/&.d/)" -.endfor - -# Dependency file inclusion. -.for depfile in $(CTESTS:R:S/$/&_a.d/) $(BTESTS:R:S/$/&_a.d/) \ - $(CTESTS:R:S/$/&_p.d/) $(BTESTS:R:S/$/&_p.d/) \ - $(CTESTS:R:S/$/&_s.d/) $(BTESTS:R:S/$/&_s.d/) -.if exists($(depfile)) -.include "$(depfile)" -.endif -.endfor - -default : check - -tests_a : $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/) -tests_p : $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/) -tests_s : $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/) - -tests : tests_a tests_p tests_s - -check_a : tests_a -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_a $(bin) -.endfor - @echo "Test static library:" - @$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS) - -check_p : tests_p -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_p $(bin) -.endfor - @echo "Test profile library:" - @$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS) - -check_s : tests_s -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_s $(bin) -.endfor - @echo "Test shared library:" - @$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS) - -check : check_a check_p check_s - -clean : - rm -f *~ - rm -f *.core - rm -f *.out - rm -f *.perf - rm -f *.diff - rm -f *.gmon - rm -f $(CTESTS) $(BTESTS) - rm -f $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/) - rm -f $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/) - rm -f $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/) - rm -f *.d - rm -f *.o diff --git a/lib/libkse/test/README b/lib/libkse/test/README deleted file mode 100644 index 8f625a1..0000000 --- a/lib/libkse/test/README +++ /dev/null @@ -1,28 +0,0 @@ -$FreeBSD$ - -This test suite is meant to test general functionality of pthreads, as well as -provide a simple framework for regression tests. In general, this test suite -can be used with any pthreads library, but in reality there are a number of -libpthread-specific aspects to this test suite which would require some -effort to get around if testing another pthreads library. - -This test suite assumes that libpthread is installed. - -There are two forms of test that the 'verify' script understands. The simpler -form is the diff format, where the output of the test program is diff'ed with -the correspondingly named .exp file. If there is diff output, the test fails. -The sequence test format is somewhat more complex, and is documented in the -command line usage output for verify. The advantage of this format is that it -allows multiple tests to pass/fail within one program. - -There is no driving need for test naming consistency, but the existing tests -generally follow these conventions: - -<name>_d.c <name>_d.exp : Diff mode C test and expected output file. -<name>_s.c : Sequence mode C test. -<name>_b*.c : Back end C program used by perl tests. -<name>_d.pl <name>_d.pl.exp : Diff mode perl test and expected output file. -<name>_s.pl : Sequence mode perl test. - -<name> is something descriptive, such as "pr14685" in the case of a PR-related -regression test, or "mutex" in the case of a test of mutexes. diff --git a/lib/libkse/test/guard_b.c b/lib/libkse/test/guard_b.c deleted file mode 100644 index 2e27031..0000000 --- a/lib/libkse/test/guard_b.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - * Test thread stack guard functionality. - */ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <pthread.h> - -#define FRAME_SIZE 1024 -#define FRAME_OVERHEAD 40 - -struct args -{ - void *top; /* Top of thread's initial stack frame. */ - int cur; /* Recursion depth. */ - int max; /* Maximum recursion depth. */ -}; - -void * -recurse(void *args) -{ - int top; - struct args *parms = (struct args *)args; - char filler[FRAME_SIZE - FRAME_OVERHEAD]; - - /* Touch the memory in this stack frame. */ - top = 0xa5; - memset(filler, 0xa5, sizeof(filler)); - - if (parms->top == NULL) { - /* Initial stack frame. */ - parms->top = (void*)⊤ - } - - /* - * Make sure frame size is what we expect. Getting this right involves - * hand tweaking, so just print a warning rather than aborting. - */ - if (parms->top - (void *)&top != FRAME_SIZE * parms->cur) { - fprintf(stderr, - "Stack size (%ld) != expected (%ld), frame %ld\n", - (long)parms->top - (long)&top, - (long)(FRAME_SIZE * parms->cur), (long)parms->cur); - } - - parms->cur++; - if (parms->cur < parms->max) - recurse(args); - - return NULL; -} - - -int -main(int argc, char **argv) -{ - size_t def_stacksize, def_guardsize; - size_t stacksize, guardsize; - pthread_t thread; - pthread_attr_t attr; - struct args args; - - if (argc != 3) { - fprintf(stderr, "usage: guard_b <stacksize> <guardsize>\n"); - exit(1); - } - fprintf(stderr, "Test begin\n"); - - stacksize = strtoul(argv[1], NULL, 10); - guardsize = strtoul(argv[2], NULL, 10); - - assert(pthread_attr_init(&attr) == 0); - /* - * Exercise the attribute APIs more thoroughly than is strictly - * necessary for the meat of this test program. - */ - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - if (def_stacksize != stacksize) { - assert(pthread_attr_setstacksize(&attr, stacksize) == 0); - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(def_stacksize == stacksize); - } - if (def_guardsize != guardsize) { - assert(pthread_attr_setguardsize(&attr, guardsize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - assert(def_guardsize >= guardsize); - } - - /* - * Create a thread that will come just short of overflowing the thread - * stack. We need to leave a bit of breathing room in case the thread - * is context switched, and we also have to take care not to call any - * functions in the deepest stack frame. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) - 1; - fprintf(stderr, "No overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* - * Create a thread that will barely of overflow the thread stack. This - * should cause a segfault. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) + 1; - fprintf(stderr, "Overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* Not reached. */ - fprintf(stderr, "Unexpected success\n"); - abort(); - - return 0; -} diff --git a/lib/libkse/test/guard_b.exp b/lib/libkse/test/guard_b.exp deleted file mode 100644 index cc67470..0000000 --- a/lib/libkse/test/guard_b.exp +++ /dev/null @@ -1,4 +0,0 @@ -# $FreeBSD$ -Test begin -No overflow: -Overflow: diff --git a/lib/libkse/test/guard_s.pl b/lib/libkse/test/guard_s.pl deleted file mode 100644 index 7802ff3..0000000 --- a/lib/libkse/test/guard_s.pl +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. -# 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(s), this list of conditions and the following disclaimer -# unmodified other than the allowable addition of one or more -# copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# $FreeBSD$ -# -# Test thread stack guard functionality. The C test program needs to be driven -# by this script because it segfaults when the stack guard is hit. -# - -print "1..30\n"; - -$i = 0; -# Iterates 10 times. -for ($stacksize = 65536; $stacksize < 131072; $stacksize += 7168) -{ - # Iterates 3 times (1024, 4096, 7168). - for ($guardsize = 1024; $guardsize < 8192; $guardsize += 3072) - { - $i++; - - print "stacksize: $stacksize, guardsize: $guardsize\n"; - - `./guard_b $stacksize $guardsize >guard_b.out 2>&1`; - - if (! -f "./guard_b.out") - { - print "not ok $i\n"; - } - else - { - `diff guard_b.exp guard_b.out >guard_b.diff 2>&1`; - if ($?) - { - # diff returns non-zero if there is a difference. - print "not ok $i\n"; - } - else - { - print "ok $i\n"; - } - } - } -} diff --git a/lib/libkse/test/hello_b.c b/lib/libkse/test/hello_b.c deleted file mode 100644 index 2eefa7f..0000000 --- a/lib/libkse/test/hello_b.c +++ /dev/null @@ -1,13 +0,0 @@ -/**************************************************************************** - * - * Back end C programs can be anything compilable. - * - * $FreeBSD$ - * - ****************************************************************************/ - -int -main() -{ - return 0; -} diff --git a/lib/libkse/test/hello_d.c b/lib/libkse/test/hello_d.c deleted file mode 100644 index 6d77526..0000000 --- a/lib/libkse/test/hello_d.c +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** - * - * Simple diff mode test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <pthread.h> - -void * -entry(void * a_arg) -{ - fprintf(stderr, "Hello world\n"); - - return NULL; -} - -int -main() -{ - pthread_t thread; - int error; - - error = pthread_create(&thread, NULL, entry, NULL); - if (error) - fprintf(stderr, "Error in pthread_create(): %s\n", - strerror(error)); - - error = pthread_join(thread, NULL); - if (error) - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - - return 0; -} diff --git a/lib/libkse/test/hello_d.exp b/lib/libkse/test/hello_d.exp deleted file mode 100644 index 47be080..0000000 --- a/lib/libkse/test/hello_d.exp +++ /dev/null @@ -1,2 +0,0 @@ -# $FreeBSD$ -Hello world diff --git a/lib/libkse/test/hello_s.c b/lib/libkse/test/hello_s.c deleted file mode 100644 index 942bf2d..0000000 --- a/lib/libkse/test/hello_s.c +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** - * - * Simple sequence mode test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <pthread.h> - -void * -entry(void * a_arg) -{ - fprintf(stderr, "ok 1\n"); - fprintf(stderr, "ok \n"); - fprintf(stderr, "ok 3\n"); - - return NULL; -} - -int -main() -{ - pthread_t thread; - int error; - - fprintf(stderr, "1..3\n"); - - fprintf(stderr, "Some random text\n"); - - error = pthread_create(&thread, NULL, entry, NULL); - fprintf(stderr, "More unimportant text\n"); - if (error) - fprintf(stderr,"Error in pthread_create(): %s\n", - strerror(error)); - - error = pthread_join(thread, NULL); - if (error) - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - - fprintf(stderr, "Hello world\n"); - - return 0; -} diff --git a/lib/libkse/test/join_leak_d.c b/lib/libkse/test/join_leak_d.c deleted file mode 100644 index 6532ca5..0000000 --- a/lib/libkse/test/join_leak_d.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - * Test for leaked joined threads. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <string.h> -#include <pthread.h> - -#define NITERATIONS 16384 -#define MAXGROWTH 16384 - -void * -thread_entry(void *a_arg) -{ - return NULL; -} - -int -main(void) -{ - pthread_t thread; - int i, error; - char *brk, *nbrk; - unsigned growth; - - fprintf(stderr, "Test begin\n"); - - /* Get an initial brk value. */ - brk = sbrk(0); - - /* Create threads and join them, one at a time. */ - for (i = 0; i < NITERATIONS; i++) { - if ((error = pthread_create(&thread, NULL, thread_entry, NULL)) - != 0) { - fprintf(stderr, "Error in pthread_create(): %s\n", - strerror(error)); - exit(1); - } - if ((error = pthread_join(thread, NULL)) != 0) { - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - exit(1); - } - } - - /* Get a final brk value. */ - nbrk = sbrk(0); - - /* - * Check that the amount of heap space allocated is below an acceptable - * threshold. We could just compare brk and nbrk, but the test could - * conceivably break if the internals of the threads library changes. - */ - if (nbrk > brk) { - /* Heap grows up. */ - growth = nbrk - brk; - } else if (nbrk <= brk) { - /* Heap grows down, or no growth. */ - growth = brk - nbrk; - } - - if (growth > MAXGROWTH) { - fprintf(stderr, "Heap growth exceeded maximum (%u > %u)\n", - growth, MAXGROWTH); - } -#if (0) - else { - fprintf(stderr, "Heap growth acceptable (%u <= %u)\n", - growth, MAXGROWTH); - } -#endif - - fprintf(stderr, "Test end\n"); - return 0; -} diff --git a/lib/libkse/test/join_leak_d.exp b/lib/libkse/test/join_leak_d.exp deleted file mode 100644 index a54de72..0000000 --- a/lib/libkse/test/join_leak_d.exp +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ -Test begin -Test end diff --git a/lib/libkse/test/mutex_d.c b/lib/libkse/test/mutex_d.c deleted file mode 100644 index 2aa3b1d..0000000 --- a/lib/libkse/test/mutex_d.c +++ /dev/null @@ -1,1558 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/time.h> -#include <sys/ioctl.h> -#include <stdlib.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <sched.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <sysexits.h> -#include "pthread.h" - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof (arr) / sizeof (arr[0])) -#endif - -#ifndef NUM_THREADS -#define NUM_THREADS 10 -#endif - -#define MAX_THREAD_CMDS 10 - -static void log_error(const char *, ...) __printflike(1, 2); -static void log_trace (const char *, ...) __printflike(1, 2); -static void log (const char *, ...) __printflike(1, 2); - -/*------------------------------------------------------------ - * Types - *----------------------------------------------------------*/ - -typedef enum { - STAT_INITIAL, /* initial state */ - STAT_WAITCONDVAR, /* waiting for condition variable signal */ - STAT_WAITMUTEX /* waiting for mutex lock */ -} thread_status_t; - -typedef enum { - FLAGS_REPORT_WAITCONDMUTEX = 0x01, - FLAGS_REPORT_WAITCONDVAR = 0x02, - FLAGS_REPORT_WAITMUTEX = 0x04, - FLAGS_REPORT_BUSY_LOOP = 0x08, - FLAGS_IS_BUSY = 0x10, - FLAGS_WAS_BUSY = 0x20 -} thread_flags_t; - -typedef enum { - CMD_NONE, - CMD_TAKE_MUTEX, - CMD_RELEASE_MUTEX, - CMD_WAIT_FOR_SIGNAL, - CMD_BUSY_LOOP, - CMD_PROTECTED_OP, - CMD_RELEASE_ALL -} thread_cmd_id_t; - -typedef struct { - thread_cmd_id_t cmd_id; - pthread_mutex_t *mutex; - pthread_cond_t *cond; -} thread_cmd_t; - -typedef struct { - pthread_cond_t cond_var; - thread_status_t status; - thread_cmd_t cmd; - int flags; - int priority; - int ret; - pthread_t tid; - u_int8_t id; -} thread_state_t; - -typedef enum { - M_POSIX, - M_SS2_DEFAULT, - M_SS2_ERRORCHECK, - M_SS2_NORMAL, - M_SS2_RECURSIVE -} mutex_kind_t; - - -/*------------------------------------------------------------ - * Constants - *----------------------------------------------------------*/ - -const char *protocol_strs[] = { - "PTHREAD_PRIO_NONE", - "PTHREAD_PRIO_INHERIT", - "PTHREAD_PRIO_PROTECT" -}; - -const int protocols[] = { - PTHREAD_PRIO_NONE, - PTHREAD_PRIO_INHERIT, - PTHREAD_PRIO_PROTECT -}; - -const char *mutextype_strs[] = { - "POSIX (type not specified)", - "SS2 PTHREAD_MUTEX_DEFAULT", - "SS2 PTHREAD_MUTEX_ERRORCHECK", - "SS2 PTHREAD_MUTEX_NORMAL", - "SS2 PTHREAD_MUTEX_RECURSIVE" -}; - -const int mutex_types[] = { - 0, /* M_POSIX */ - PTHREAD_MUTEX_DEFAULT, /* M_SS2_DEFAULT */ - PTHREAD_MUTEX_ERRORCHECK, /* M_SS2_ERRORCHECK */ - PTHREAD_MUTEX_NORMAL, /* M_SS2_NORMAL */ - PTHREAD_MUTEX_RECURSIVE /* M_SS2_RECURSIVE */ -}; - - -/*------------------------------------------------------------ - * Objects - *----------------------------------------------------------*/ - -static int done = 0; -static int trace_enabled = 0; -static int use_global_condvar = 0; -static thread_state_t states[NUM_THREADS]; -static int pipefd[2]; - -static pthread_mutex_t waiter_mutex; -static pthread_mutex_t cond_mutex; -static pthread_cond_t cond_var; - -static FILE *logfile; -static int error_count = 0, pass_count = 0, total = 0; - - -/*------------------------------------------------------------ - * Prototypes - *----------------------------------------------------------*/ -extern char *strtok_r(char *str, const char *sep, char **last); - - -/*------------------------------------------------------------ - * Functions - *----------------------------------------------------------*/ - -#if defined(_LIBC_R_) && defined(DEBUG) -static void -kern_switch (pthread_t pthread_out, pthread_t pthread_in) -{ - if (pthread_out != NULL) - printf ("Swapping out thread 0x%lx, ", (long) pthread_out); - else - printf ("Swapping out kernel thread, "); - - if (pthread_in != NULL) - printf ("swapping in thread 0x%lx\n", (long) pthread_in); - else - printf ("swapping in kernel thread.\n"); -} -#endif - - -static void -log_error (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - fprintf (logfile, "FAIL: "); - vfprintf (logfile, fmt, ap); - error_count = error_count + 1; - total = total + 1; -} - - -static void -log_pass (void) -{ - fprintf (logfile, "PASS\n"); - pass_count = pass_count + 1; - total = total + 1; -} - - -static void -log_trace (const char *fmt, ...) -{ - va_list ap; - - if (trace_enabled) { - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); - } -} - - -static void -log (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); -} - - -static void -check_result (int expected, int actual) -{ - if (expected != actual) - log_error ("expected %d, returned %d\n", expected, actual); - else - log_pass (); -} - - -/* - * Check to see that the threads ran in the specified order. - */ -static void -check_run_order (char *order) -{ - const char *sep = ":,"; - char *tok, *last, *idstr, *endptr; - int expected_id, bytes, count = 0, errors = 0; - u_int8_t id; - - assert ((tok = (char *) malloc (strlen(order) + 1)) != NULL); - strcpy (tok, order); /* tok has to be larger than order */ - assert (ioctl (pipefd[0], FIONREAD, &bytes) == 0); - log_trace ("%d bytes read from FIFO.\n", bytes); - - for (idstr = strtok_r (tok, sep, &last); - (idstr != NULL) && (count < bytes); - idstr = strtok_r (NULL, sep, &last)) { - - /* Get the expected id: */ - expected_id = (int) strtol (idstr, &endptr, 10); - assert ((endptr != NULL) && (*endptr == '\0')); - - /* Read the actual id from the pipe: */ - assert (read (pipefd[0], &id, sizeof (id)) == sizeof (id)); - count = count + sizeof (id); - - if (id != expected_id) { - log_trace ("Thread %d ran out of order.\n", id); - errors = errors + 1; - } - else { - log_trace ("Thread %d at priority %d reporting.\n", - (int) id, states[id].priority); - } - } - - if (count < bytes) { - /* Clear the pipe: */ - while (count < bytes) { - read (pipefd[0], &id, sizeof (id)); - count = count + 1; - errors = errors + 1; - } - } - else if (bytes < count) - errors = errors + count - bytes; - - if (errors == 0) - log_pass (); - else - log_error ("%d threads ran out of order", errors); -} - - -static void * -waiter (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - pthread_mutex_t *held_mutex[MAX_THREAD_CMDS]; - int held_mutex_owned[MAX_THREAD_CMDS]; - sigset_t mask; - struct timeval tv1, tv2; - thread_cmd_t cmd; - int i, mutex_count = 0; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (done == 0) { - /* Wait for signal from the main thread to continue. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: locking cond_mutex.\n", - (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - /* Do we report our status. */ - if (statep->flags & FLAGS_REPORT_WAITCONDMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: waiting for cond_var.\n", - (int) statep->id); - - /* Wait for a command. */ - statep->status = STAT_WAITCONDVAR; - - /* - * The threads are allowed commanded to wait either on - * their own unique condition variable (so they may be - * separately signaled) or on one global condition variable - * (so they may be signaled together). - */ - if (use_global_condvar != 0) - pthread_cond_wait (&cond_var, &cond_mutex); - else - pthread_cond_wait (&statep->cond_var, &cond_mutex); - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_WAITCONDVAR) { - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: wrote to pipe.\n", - (int) statep->id); - } - log_trace ("Thread %d: received cond_var signal.\n", - (int) statep->id); - - /* Get a copy of the command before releasing the mutex. */ - cmd = statep->cmd; - - /* Clear the command after copying it. */ - statep->cmd.cmd_id = CMD_NONE; - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Peform the command.*/ - switch (cmd.cmd_id) { - case CMD_TAKE_MUTEX: - statep->ret = pthread_mutex_lock (cmd.mutex); - if (statep->ret == 0) { - assert (mutex_count < sizeof (held_mutex)); - held_mutex[mutex_count] = cmd.mutex; - held_mutex_owned[mutex_count] = 1; - mutex_count++; - } - else { - held_mutex_owned[mutex_count] = 0; - log_trace ("Thread id %d unable to lock mutex, " - "error = %d\n", (int) statep->id, - statep->ret); - } - break; - - case CMD_RELEASE_MUTEX: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - mutex_count--; - if (held_mutex_owned[mutex_count] != 0) - assert (pthread_mutex_unlock - (held_mutex[mutex_count]) == 0); - break; - - case CMD_WAIT_FOR_SIGNAL: - assert (pthread_mutex_lock (cmd.mutex) == 0); - assert (pthread_cond_wait (cmd.cond, cmd.mutex) == 0); - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_BUSY_LOOP: - log_trace ("Thread %d: Entering busy loop.\n", - (int) statep->id); - /* Spin for 15 seconds. */ - assert (gettimeofday (&tv2, NULL) == 0); - tv1.tv_sec = tv2.tv_sec + 5; - tv1.tv_usec = tv2.tv_usec; - statep->flags |= FLAGS_IS_BUSY; - while (timercmp (&tv2, &tv1,<)) { - assert (gettimeofday (&tv2, NULL) == 0); - } - statep->flags &= ~FLAGS_IS_BUSY; - statep->flags |= FLAGS_WAS_BUSY; - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - log_trace ("Thread %d: Leaving busy loop.\n", - (int) statep->id); - break; - - case CMD_PROTECTED_OP: - assert (pthread_mutex_lock (cmd.mutex) == 0); - statep->flags |= FLAGS_WAS_BUSY; - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_RELEASE_ALL: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - for (i = mutex_count - 1; i >= 0; i--) { - if (held_mutex_owned[i] != 0) - assert (pthread_mutex_unlock - (held_mutex[i]) == 0); - } - mutex_count = 0; - break; - - case CMD_NONE: - default: - break; - } - - /* Wait for the big giant waiter lock. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: waiting for big giant lock.\n", - (int) statep->id); - pthread_mutex_lock (&waiter_mutex); - if (statep->flags & FLAGS_REPORT_WAITMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: got big giant lock.\n", - (int) statep->id); - statep->status = STAT_INITIAL; - pthread_mutex_unlock (&waiter_mutex); - } - - log_trace ("Thread %ld: Exiting thread 0x%lx\n", (long) statep->id, - (long) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void * -lock_twice (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - sigset_t mask; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - /* Wait for a signal to continue. */ - log_trace ("Thread %d: locking cond_mutex.\n", (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - log_trace ("Thread %d: waiting for cond_var.\n", (int) statep->id); - statep->status = STAT_WAITCONDVAR; - pthread_cond_wait (&cond_var, &cond_mutex); - - log_trace ("Thread %d: received cond_var signal.\n", (int) statep->id); - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - statep->status = STAT_WAITMUTEX; - /* Lock the mutex once. */ - assert (pthread_mutex_lock (statep->cmd.mutex) == 0); - - /* Lock it again and capture the error. */ - statep->ret = pthread_mutex_lock (statep->cmd.mutex); - statep->status = 0; - - assert (pthread_mutex_unlock (statep->cmd.mutex) == 0); - - /* Unlock it again if it is locked recursively. */ - if (statep->ret == 0) - pthread_mutex_unlock (statep->cmd.mutex); - - log_trace ("Thread %ld: Exiting thread 0x%lx\n", (long) statep->id, - (long) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - log ("Signal handler caught signal %d, thread id 0x%lx\n", - signo, (long) pthread_self()); - - if (signo == SIGINT) - done = 1; -} - - -static void -send_cmd (int id, thread_cmd_id_t cmd) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = NULL; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cv_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m, - pthread_cond_t *cv) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = cv; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -mutex_init_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - mutex_kind_t mkind; - int mproto, ret; - - /* - * Initialize a mutex attribute. - * - * pthread_mutexattr_init not tested for: ENOMEM - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize a mutex. - * - * pthread_mutex_init not tested for: EAGAIN ENOMEM EPERM EBUSY - */ - log ("Testing pthread_mutex_init\n"); - log ("--------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - log (" Protocol %s, Type %s - ", - protocol_strs[mproto], mutextype_strs[mkind]); - ret = pthread_mutex_init (&mutex, &mattr); - check_result (/* expected */ 0, ret); - assert (pthread_mutex_destroy (&mutex) == 0); - - /* - * Destroy a mutex attribute. - * - * XXX - There should probably be a magic number - * associated with a mutex attribute so that - * destroy can be reasonably sure the attribute - * is valid. - * - * pthread_mutexattr_destroy not tested for: EINVAL - */ - assert (pthread_mutexattr_destroy (&mattr) == 0); - } - } -} - - -static void -mutex_destroy_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_condattr_t cattr; - pthread_cond_t cv; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Destroy a mutex. - * - * XXX - There should probably be a magic number associated - * with a mutex so that destroy can be reasonably sure - * the mutex is valid. - * - * pthread_mutex_destroy not tested for: - */ - log ("Testing pthread_mutex_destroy\n"); - log ("-----------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Destruction of unused mutex - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ 0, ret); - - log (" Destruction of mutex locked by self - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - assert (pthread_mutex_unlock (&mutex) == 0); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex locked by another " - "thread - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - send_mutex_cmd (0, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - send_cmd (0, CMD_RELEASE_ALL); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex while being used in " - "cond_wait - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cv, &cattr) == 0); - send_mutex_cv_cmd (0, CMD_WAIT_FOR_SIGNAL, &mutex, &cv); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - pthread_cond_signal (&cv); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - } - } -} - - -static void -mutex_lock_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Lock a mutex. - * - * pthread_lock not tested for: - */ - log ("Testing pthread_mutex_lock\n"); - log ("--------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Lock on unlocked mutex - "); - ret = pthread_mutex_lock (&mutex); - check_result (/* expected */ 0, ret); - pthread_mutex_unlock (&mutex); - - log (" Lock on invalid mutex - "); - ret = pthread_mutex_lock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Lock on mutex held by self - "); - assert (pthread_create (&state.tid, &pattr, lock_twice, - (void *) &state) == 0); - /* Let the thread start. */ - sleep (1); - state.cmd.mutex = &mutex; - state.ret = 0xdeadbeef; - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - /* Let the thread receive and process the command. */ - sleep (1); - - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ 0xdeadbeef, - state.ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ 0, state.ret); - break; - } - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -mutex_unlock_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - int mproto, ret; - mutex_kind_t mkind; - - /* - * Unlock a mutex. - * - * pthread_unlock not tested for: - */ - log ("Testing pthread_mutex_unlock\n"); - log ("----------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Unlock on mutex held by self - "); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_unlock (&mutex); - check_result (/* expected */ 0, ret); - - log (" Unlock on invalid mutex - "); - ret = pthread_mutex_unlock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Unlock on mutex locked by another thread - "); - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_unlock (&mutex); - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ EPERM, ret); - break; - } - if (ret == 0) { - /* - * If for some reason we were able to unlock - * the mutex, relock it so that the test - * thread has no problems releasing the mutex. - */ - pthread_mutex_lock (&mutex); - } - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -queueing_order_test (void) -{ - int i; - - log ("Testing queueing order\n"); - log ("----------------------\n"); - assert (pthread_mutex_lock (&waiter_mutex) == 0); - /* - * Tell the threads to report when they take the waiters mutex. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - for (i = 0; i < NUM_THREADS; i++) { - states[i].flags = FLAGS_REPORT_WAITMUTEX; - assert (pthread_cond_signal (&states[i].cond_var) == 0); - } - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Signal the threads to continue. */ - sleep (1); - - /* Use the global condition variable next time. */ - use_global_condvar = 1; - - /* Release the waiting threads and allow them to run again. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); - - log (" Queueing order on a mutex - "); - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads to report when they've been signaled. */ - states[i].flags = FLAGS_REPORT_WAITCONDVAR; - } - - /* - * Prevent the threads from continuing their loop after we - * signal them. - */ - assert (pthread_mutex_lock (&waiter_mutex) == 0); - - - log (" Queueing order on a condition variable - "); - /* - * Signal one thread to run and see that the highest priority - * thread executes. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - if (states[NUM_THREADS - 1].status != STAT_WAITMUTEX) - log_error ("highest priority thread does not run.\n"); - - /* Signal the remaining threads. */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_broadcast (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads not to report anything. */ - states[i].flags = 0; - } - - /* Use the thread unique condition variable next time. */ - use_global_condvar = 0; - - /* Allow the threads to continue their loop. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); -} - - -static void -mutex_prioceiling_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, ret, policy, my_prio, old_ceiling; - - log ("Testing priority ceilings\n"); - log ("-------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_PROTECT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - /* - * Initialize and create 3 priority protection mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_PROTECT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Set the ceiling priorities for the 3 priority protection - * mutexes to, 5 less than, equal to, and 5 greater than, - * this threads current priority. - */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_setprioceiling (&m[i], - my_prio - 5 + 5*i, &old_ceiling) == 0); - - /* - * Check that if we attempt to take a mutex whose priority - * ceiling is lower than our priority, we get an error. - */ - log (" Lock with ceiling priority < thread priority - "); - ret = pthread_mutex_lock (&m[0]); - check_result (/* expected */ EINVAL, ret); - if (ret == 0) - pthread_mutex_unlock (&m[0]); - - /* - * Check that we can take a mutex whose priority ceiling - * is equal to our priority. - */ - log (" Lock with ceiling priority = thread priority - "); - ret = pthread_mutex_lock (&m[1]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[1]); - - /* - * Check that we can take a mutex whose priority ceiling - * is higher than our priority. - */ - log (" Lock with ceiling priority > thread priority - "); - ret = pthread_mutex_lock (&m[2]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[2]); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it doesn't block this thread (since the - * priority ceiling of mutex 0 and the priority of the test - * thread are both less than the priority of this thread). - */ - log (" Preemption with ceiling priority < thread " - "priority - "); - /* Have the test thread take mutex 0. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - log_trace ("Sending busy command.\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if (states[test_thread_id].flags & - (FLAGS_IS_BUSY | FLAGS_WAS_BUSY)) - log_error ("test thread inproperly preempted us.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 0. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 1 is the same as the priority of this - * thread). The test thread should not run to completion - * as its time quantum should expire before the 5 seconds - * are up. - */ - log (" Preemption with ceiling priority = thread " - "priority - "); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) == 0) - log_error ("test thread did not switch in on yield.\n"); - else if (states[test_thread_id].flags & FLAGS_WAS_BUSY) - log_error ("test thread ran to completion.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Set the scheduling policy of the test thread to SCHED_FIFO - * and have it go into a busy loop for 5 seconds. This - * thread is SCHED_RR, and since the priority ceiling of - * mutex 1 is the same as the priority of this thread, the - * test thread should run to completion once it is switched - * in. - */ - log (" SCHED_FIFO scheduling and ceiling priority = " - "thread priority - "); - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_FIFO, ¶m) == 0); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Restore the test thread scheduling parameters. */ - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_RR, ¶m) == 0); - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 2 is the greater than the priority of - * this thread). The test thread should run to completion - * and block this thread because its active priority is - * higher. - */ - log (" SCHED_FIFO scheduling and ceiling priority > " - "thread priority - "); - /* Have the test thread take mutex 2. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[2]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) != 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 2. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -static void -mutex_prioinherit_test (void) -{ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, policy, my_prio; - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - log ("Testing priority inheritence\n"); - log ("----------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_INHERIT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize and create 3 priority inheritence mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_INHERIT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Test setup: - * Thread 4 - take mutex 0, 1 - * Thread 2 - enter protected busy loop with mutex 0 - * Thread 3 - enter protected busy loop with mutex 1 - * Thread 4 - enter protected busy loop with mutex 2 - * Thread 5 - enter busy loop - * Thread 6 - enter protected busy loop with mutex 0 - * Thread 4 - releases mutexes 1 and 0. - * - * Expected results: - * Threads complete in order 4, 6, 5, 3, 2 - */ - log (" Simple inheritence test - "); - - /* - * Command thread 4 to take mutexes 0 and 1. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); /* Allow command to be received. */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - /* - * Tell the threads to report themselves when they are - * at the bottom of their loop (waiting on wait_mutex). - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags |= FLAGS_REPORT_WAITMUTEX; - - /* - * Command thread 2 to take mutex 0 and thread 3 to take - * mutex 1, both via a protected operation command. Since - * thread 4 owns mutexes 0 and 1, both threads 2 and 3 - * will block until the mutexes are released by thread 4. - */ - log_trace ("Commanding protected operation to thread 2.\n"); - send_mutex_cmd (2, CMD_PROTECTED_OP, &m[0]); - log_trace ("Commanding protected operation to thread 3.\n"); - send_mutex_cmd (3, CMD_PROTECTED_OP, &m[1]); - sleep (1); - - /* - * Command thread 4 to take mutex 2 via a protected operation - * and thread 5 to enter a busy loop for 5 seconds. Since - * thread 5 has higher priority than thread 4, thread 5 will - * enter the busy loop before thread 4 is activated. - */ - log_trace ("Commanding protected operation to thread 4.\n"); - send_mutex_cmd (4, CMD_PROTECTED_OP, &m[2]); - log_trace ("Commanding busy loop to thread 5.\n"); - send_cmd (5, CMD_BUSY_LOOP); - sleep (1); - if ((states[5].flags & FLAGS_IS_BUSY) == 0) - log_error ("thread 5 is not running.\n"); - log_trace ("Commanding protected operation thread 6.\n"); - send_mutex_cmd (6, CMD_PROTECTED_OP, &m[0]); - sleep (1); - if ((states[4].flags & FLAGS_WAS_BUSY) == 0) - log_error ("thread 4 failed to inherit priority.\n"); - states[4].flags = 0; - send_cmd (4, CMD_RELEASE_ALL); - sleep (5); - check_run_order ("4,6,5,3,2"); - - /* - * Clear the flags. - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags = 0; - - /* - * Test setup: - * Thread 2 - enter busy loop (SCHED_FIFO) - * Thread 4 - take mutex 0 - * Thread 4 - priority change to same priority as thread 2 - * Thread 4 - release mutex 0 - * - * Expected results: - * Since thread 4 owns a priority mutex, it should be - * placed at the front of the run queue (for its new - * priority slot) when its priority is lowered to the - * same priority as thread 2. If thread 4 did not own - * a priority mutex, then it would have been added to - * the end of the run queue and thread 2 would have - * executed until it blocked (because it's scheduling - * policy is SCHED_FIFO). - * - */ - log (" Inheritence test with change of priority - "); - - /* - * Change threads 2 and 4 scheduling policies to be - * SCHED_FIFO. - */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_FIFO, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - - /* - * Command thread 4 to take mutex 0. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - /* - * Command thread 2 to enter busy loop. - */ - send_cmd (2, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* - * Command thread 4 to enter busy loop. - */ - send_cmd (4, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* Have threads 2 and 4 report themselves. */ - states[2].flags = FLAGS_REPORT_WAITMUTEX; - states[4].flags = FLAGS_REPORT_WAITMUTEX; - - /* Change the priority of thread 4. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - sleep (5); - check_run_order ("4,2"); - - /* Clear the flags */ - states[2].flags = 0; - states[4].flags = 0; - - /* Reset the policies. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_RR, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_RR, - ¶m) == 0); - - send_cmd (4, CMD_RELEASE_MUTEX); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_condattr_t cattr; - pthread_attr_t pattr; - int i, policy, main_prio; - void * exit_status; - sigset_t mask; - struct sigaction act; - struct sched_param param; - - logfile = stdout; - - assert (pthread_getschedparam (pthread_self (), &policy, ¶m) == 0); - main_prio = param.sched_priority; - - /* Setupt our signal mask. */ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_SETMASK, &mask, NULL); - - /* Install a signal handler for SIGINT */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGINT); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGINT, &act, NULL); - - /* This test relies on the concurrency level being 1. */ - pthread_setconcurrency(1); - - /* - * Initialize the thread attribute. - */ - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) == 0); - - /* - * Initialize and create the waiter and condvar mutexes. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutex_init (&waiter_mutex, &mattr) == 0); - assert (pthread_mutex_init (&cond_mutex, &mattr) == 0); - - /* - * Initialize and create a condition variable. - */ - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cond_var, &cattr) == 0); - - /* Create a pipe to catch the results of thread wakeups. */ - assert (pipe (pipefd) == 0); - -#if defined(_LIBC_R_) && defined(DEBUG) - assert (pthread_switch_add_np (kern_switch) == 0); -#endif - - /* - * Create the waiting threads. - */ - for (i = 0; i < NUM_THREADS; i++) { - assert (pthread_cond_init (&states[i].cond_var, &cattr) == 0); - states[i].id = (u_int8_t) i; /* NUM_THREADS must be <= 256 */ - states[i].status = 0; - states[i].cmd.cmd_id = CMD_NONE; - states[i].flags = 0; /* No flags yet. */ - assert (pthread_create (&states[i].tid, &pattr, waiter, - (void *) &states[i]) == 0); - param.sched_priority = main_prio - 10 + i; - states[i].priority = param.sched_priority; - assert (pthread_setschedparam (states[i].tid, SCHED_OTHER, - ¶m) == 0); -#if defined(_LIBC_R_) - { - char buf[30]; - - snprintf (buf, sizeof(buf), "waiter_%d", i); - pthread_set_name_np (states[i].tid, buf); - } -#endif - } - - /* Allow the threads to start. */ - sleep (1); - log_trace ("Done creating threads.\n"); - - log ("\n"); - mutex_init_test (); - log ("\n"); - mutex_destroy_test (); - log ("\n"); - mutex_lock_test (); - log ("\n"); - mutex_unlock_test (); - log ("\n"); - queueing_order_test (); - log ("\n"); - mutex_prioinherit_test (); - log ("\n"); - mutex_prioceiling_test (); - log ("\n"); - - log ("Total tests %d, passed %d, failed %d\n", - total, pass_count, error_count); - - /* Set the done flag and signal the threads to exit. */ - log_trace ("Setting done flag.\n"); - done = 1; - - /* - * Wait for the threads to finish. - */ - log_trace ("Trying to join threads.\n"); - for (i = 0; i < NUM_THREADS; i++) { - send_cmd (i, CMD_NONE); - assert (pthread_join (states[i].tid, &exit_status) == 0); - } - - /* Clean up after ourselves. */ - close (pipefd[0]); - close (pipefd[1]); - - if (error_count != 0) - exit (EX_OSERR); /* any better ideas??? */ - else - exit (EX_OK); -} diff --git a/lib/libkse/test/mutex_d.exp b/lib/libkse/test/mutex_d.exp deleted file mode 100644 index dd2f7bd..0000000 --- a/lib/libkse/test/mutex_d.exp +++ /dev/null @@ -1,291 +0,0 @@ -# $FreeBSD$ - -Testing pthread_mutex_init --------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - -Testing pthread_mutex_destroy ------------------------------ - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - -Testing pthread_mutex_lock --------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - -Testing pthread_mutex_unlock ----------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - -Testing queueing order ----------------------- - Queueing order on a mutex - PASS - Queueing order on a condition variable - PASS - -Testing priority inheritence ----------------------------- - Protype PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - -Testing priority ceilings -------------------------- - Protype PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - -Total tests 212, passed 212, failed 0 diff --git a/lib/libkse/test/propagate_s.pl b/lib/libkse/test/propagate_s.pl deleted file mode 100644 index 6b85090..0000000 --- a/lib/libkse/test/propagate_s.pl +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. -# 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(s), this list of conditions and the following disclaimer as -# the first lines of this file unmodified other than the possible -# addition of one or more copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. -# -########################################################################### -# -# Verify that no cancellation points are propagated inside of libpthread. -# -# $FreeBSD$ -# - -@CPOINTS = ("aio_suspend", "close", "creat", "fcntl", "fsync", "mq_receive", - "mq_send", "msync", "nanosleep", "open", "pause", - "pthread_cond_timedwait", "pthread_cond_wait", "pthread_join", - "pthread_testcancel", "read", "sem_wait", "sigsuspend", - "sigtimedwait", "sigwait", "sigwaitinfo", "sleep", "system", - "tcdrain", "wait", "waitpid", "write"); - -print "1..1\n"; - -$cpoints = join '\|', @CPOINTS; -$regexp = "\" U \\(" . $cpoints . "\\\)\$\""; - -`nm -a /usr/lib/libc.a |grep $regexp >propagate_s.out`; -if (!open (NMOUT, "<./propagate_s.out")) -{ - print "not ok 1\n"; -} -else -{ - $propagations = 0; - - while (<NMOUT>) - { - $propagations++; - print "$_\n"; - } - if ($propagations != 0) - { - print "$propagations propagation(s)\n"; - print "not ok 1\n"; - } - else - { - print "ok 1\n"; - } - close NMOUT; - unlink "propagate_s.out"; -} diff --git a/lib/libkse/test/sem_d.c b/lib/libkse/test/sem_d.c deleted file mode 100644 index b834591..0000000 --- a/lib/libkse/test/sem_d.c +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. - * - **************************************************************************** - * - * sem test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <assert.h> -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <semaphore.h> -#include <pthread.h> - -#define NTHREADS 10 - -void * -entry(void * a_arg) -{ - sem_t * sem = (sem_t *) a_arg; - - sem_wait(sem); - fprintf(stderr, "Got semaphore\n"); - - return NULL; -} - -int -main() -{ - sem_t sem_a, sem_b; - pthread_t threads[NTHREADS]; - unsigned i; - int val; - - fprintf(stderr, "Test begin\n"); - -#ifdef _LIBC_R_ - assert(-1 == sem_init(&sem_b, 1, 0)); - assert(EPERM == errno); -#endif - - assert(0 == sem_init(&sem_b, 0, 0)); - assert(0 == sem_getvalue(&sem_b, &val)); - assert(0 == val); - - assert(0 == sem_post(&sem_b)); - assert(0 == sem_getvalue(&sem_b, &val)); - assert(1 == val); - - assert(0 == sem_wait(&sem_b)); - assert(-1 == sem_trywait(&sem_b)); - assert(EAGAIN == errno); - assert(0 == sem_post(&sem_b)); - assert(0 == sem_trywait(&sem_b)); - assert(0 == sem_post(&sem_b)); - assert(0 == sem_wait(&sem_b)); - assert(0 == sem_post(&sem_b)); - -#ifdef _LIBC_R_ - assert(SEM_FAILED == sem_open("/foo", O_CREAT | O_EXCL, 0644, 0)); - assert(ENOSYS == errno); - - assert(-1 == sem_close(&sem_b)); - assert(ENOSYS == errno); - - assert(-1 == sem_unlink("/foo")); - assert(ENOSYS == errno); -#endif - - assert(0 == sem_destroy(&sem_b)); - - assert(0 == sem_init(&sem_a, 0, 0)); - - for (i = 0; i < NTHREADS; i++) { - pthread_create(&threads[i], NULL, entry, (void *) &sem_a); - } - - for (i = 0; i < NTHREADS; i++) { - assert(0 == sem_post(&sem_a)); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_join(threads[i], NULL); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_create(&threads[i], NULL, entry, (void *) &sem_a); - } - - for (i = 0; i < NTHREADS; i++) { - assert(0 == sem_post(&sem_a)); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_join(threads[i], NULL); - } - - assert(0 == sem_destroy(&sem_a)); - - fprintf(stderr, "Test end\n"); - return 0; -} diff --git a/lib/libkse/test/sem_d.exp b/lib/libkse/test/sem_d.exp deleted file mode 100644 index cd86f12..0000000 --- a/lib/libkse/test/sem_d.exp +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ -Test begin -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Test end diff --git a/lib/libkse/test/sigsuspend_d.c b/lib/libkse/test/sigsuspend_d.c deleted file mode 100644 index d405e3d..0000000 --- a/lib/libkse/test/sigsuspend_d.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -static int sigcounts[NSIG + 1]; -static int sigfifo[NSIG + 1]; -static int fifo_depth = 0; -static sigset_t suspender_mask; -static pthread_t suspender_tid; - - -static void * -sigsuspender (void *arg) -{ - int save_count, status, i; - sigset_t run_mask; - - /* Run with all signals blocked. */ - sigfillset (&run_mask); - sigprocmask (SIG_SETMASK, &run_mask, NULL); - - /* Allow these signals to wake us up during a sigsuspend. */ - sigfillset (&suspender_mask); /* Default action */ - sigdelset (&suspender_mask, SIGKILL); /* Cannot catch */ - sigdelset (&suspender_mask, SIGSTOP); /* Cannot catch */ - sigdelset (&suspender_mask, SIGINT); /* terminate */ - sigdelset (&suspender_mask, SIGHUP); /* terminate */ - sigdelset (&suspender_mask, SIGQUIT); /* create core image */ - sigdelset (&suspender_mask, SIGURG); /* ignore */ - sigdelset (&suspender_mask, SIGIO); /* ignore */ - sigdelset (&suspender_mask, SIGUSR2); /* terminate */ - - while (sigcounts[SIGINT] == 0) { - save_count = sigcounts[SIGUSR2]; - - status = sigsuspend (&suspender_mask); - if ((status == 0) || (errno != EINTR)) { - fprintf (stderr, "Unable to suspend for signals, " - "errno %d, return value %d\n", - errno, status); - exit (1); - } - for (i = 0; i < fifo_depth; i++) - fprintf (stderr, "Sigsuspend woke up by signal %d\n", - sigfifo[i]); - fifo_depth = 0; - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - sigset_t set, suspend_set; - pthread_t self; - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; - - /* - * If we are running on behalf of the suspender thread, - * ensure that we have the correct mask set. - */ - self = pthread_self (); - if (self == suspender_tid) { - sigfifo[fifo_depth] = signo; - fifo_depth++; - fprintf (stderr, - " -> Suspender thread signal handler caught signal %d\n", - signo); - - /* Get the current signal mask. */ - sigprocmask (SIG_SETMASK, NULL, &set); - - /* The handler should run with the current signal masked. */ - suspend_set = suspender_mask; - sigaddset(&suspend_set, signo); - - if (memcmp(&set, &suspend_set, sizeof(set))) - fprintf (stderr, - " >>> FAIL: sigsuspender signal handler running " - "with incorrect mask.\n"); - } - else - fprintf (stderr, - " -> Main thread signal handler caught signal %d\n", - signo); -} - - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - fprintf (stderr, "Unable to send thread signal, errno %d.\n", - errno); - exit (1); - } -} - - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - fprintf (stderr, "Unable to send process signal, errno %d.\n", - errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_attr_t pattr; - void * exit_status; - struct sigaction act; - sigset_t oldset; - sigset_t newset; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Ignore signal SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* Get our current signal mask. */ - sigprocmask (SIG_SETMASK, NULL, &oldset); - - /* Mask out SIGUSR1 and SIGUSR2. */ - newset = oldset; - sigaddset (&newset, SIGUSR1); - sigaddset (&newset, SIGUSR2); - sigprocmask (SIG_SETMASK, &newset, NULL); - - /* Install a signal handler for SIGUSR1 */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGUSR1); - sigaction (SIGUSR1, &act, NULL); - - /* Install a signal handler for SIGUSR2 */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGUSR2); - sigaction (SIGUSR2, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - fprintf (stderr, "Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Create the sigsuspender thread. - */ - if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) { - fprintf (stderr, "Unable to create thread, errno %d.\n", errno); - exit (1); - } -#if defined(_LIBC_R_) - pthread_set_name_np (suspender_tid, "sigsuspender"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (suspender_tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - fprintf (stderr, "FAIL: sigsuspend wakes up for ignored signal " - "SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a - * sigsuspend. - */ - send_thread_signal (suspender_tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 2) - fprintf (stderr, - "FAIL: sigsuspend doesn't wake up for SIGURG.\n"); - - /* - * Verify that a SIGUSR2 signal will release a sigsuspended - * thread. - */ - send_thread_signal (suspender_tid, SIGUSR2); - sleep (1); - send_process_signal (SIGUSR2); - sleep (1); - if (sigcounts[SIGUSR2] != 2) - fprintf (stderr, - "FAIL: sigsuspend doesn't wake up for SIGUSR2.\n"); - - /* - * Verify that a signal, blocked in both the main and - * sigsuspender threads, does not cause the signal handler - * to be called. - */ - send_thread_signal (suspender_tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 0) - fprintf (stderr, "FAIL: signal hander called for SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (suspender_tid, &exit_status); - - return (0); -} diff --git a/lib/libkse/test/sigsuspend_d.exp b/lib/libkse/test/sigsuspend_d.exp deleted file mode 100644 index 03c9a72..0000000 --- a/lib/libkse/test/sigsuspend_d.exp +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -> Suspender thread signal handler caught signal 16 -Sigsuspend woke up by signal 16 - -> Suspender thread signal handler caught signal 16 -Sigsuspend woke up by signal 16 - -> Suspender thread signal handler caught signal 31 -Sigsuspend woke up by signal 31 - -> Suspender thread signal handler caught signal 31 -Sigsuspend woke up by signal 31 diff --git a/lib/libkse/test/sigwait_d.c b/lib/libkse/test/sigwait_d.c deleted file mode 100644 index f3ccd6b..0000000 --- a/lib/libkse/test/sigwait_d.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -static int sigcounts[NSIG + 1]; -static sigset_t wait_mask; -static pthread_mutex_t waiter_mutex; - - -static void * -sigwaiter (void *arg) -{ - int signo; - sigset_t mask; - - /* Block SIGHUP */ - sigemptyset (&mask); - sigaddset (&mask, SIGHUP); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (sigcounts[SIGINT] == 0) { - if (sigwait (&wait_mask, &signo) != 0) { - fprintf (stderr, - "Unable to wait for signal, errno %d\n", - errno); - exit (1); - } - sigcounts[signo]++; - fprintf (stderr, "Sigwait caught signal %d\n", signo); - - /* Allow the main thread to prevent the sigwait. */ - pthread_mutex_lock (&waiter_mutex); - pthread_mutex_unlock (&waiter_mutex); - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - fprintf (stderr, " -> Signal handler caught signal %d\n", signo); - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; -} - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - fprintf (stderr, "Unable to send thread signal, errno %d.\n", - errno); - exit (1); - } -} - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - fprintf (stderr, "Unable to send process signal, errno %d.\n", - errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_attr_t pattr; - pthread_t tid; - void * exit_status; - struct sigaction act; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Setup our wait mask. */ - sigemptyset (&wait_mask); /* Default action */ - sigaddset (&wait_mask, SIGHUP); /* terminate */ - sigaddset (&wait_mask, SIGINT); /* terminate */ - sigaddset (&wait_mask, SIGQUIT); /* create core image */ - sigaddset (&wait_mask, SIGURG); /* ignore */ - sigaddset (&wait_mask, SIGIO); /* ignore */ - sigaddset (&wait_mask, SIGUSR1); /* terminate */ - - /* Ignore signals SIGHUP and SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGHUP, &act, NULL); - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - fprintf (stderr, "Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Initialize and create a mutex. - */ - if ((pthread_mutexattr_init (&mattr) != 0) || - (pthread_mutex_init (&waiter_mutex, &mattr) != 0)) { - fprintf (stderr, "Unable to create waiter mutex.\n"); - exit (1); - } - - /* - * Create the sigwaiter thread. - */ - if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) { - fprintf (stderr, "Unable to create thread.\n"); - exit (1); - } -#if defined(_LIBC_R_) - pthread_set_name_np (tid, "sigwaiter"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - fprintf (stderr, - "FAIL: sigwait wakes up for ignored signal SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a sigwait. - */ - send_thread_signal (tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 2) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGURG.\n"); - - /* - * Verify that a signal with a default action that terminates - * the process will release a sigwait. - */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - - /* - * Verify that if we install a signal handler for a previously - * ignored signal, an occurrence of this signal will release - * the (already waiting) sigwait. - */ - - /* Install a signal handler for SIGHUP. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGHUP, &act, NULL); - - /* Sending SIGHUP should release the sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - send_thread_signal (tid, SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 2) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n"); - - /* - * Verify that a pending signal in the waiters mask will - * cause sigwait to return the pending signal. We do this - * by taking the waiters mutex and signaling the waiter to - * release him from the sigwait. The waiter will block - * on taking the mutex, and we can then send the waiter a - * signal which should be added to his pending signals. - * The next time the waiter does a sigwait, he should - * return with the pending signal. - */ - sigcounts[SIGHUP] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 1) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n"); - /* - * Add SIGHUP to the process pending signals. Since there is - * a signal handler installed for SIGHUP and this signal is - * blocked from the waiter thread and unblocked in the main - * thread, the signal handler should be called once for SIGHUP. - */ - send_process_signal (SIGHUP); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGHUP] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't return for pending SIGHUP.\n"); - - /* - * Repeat the above test using pthread_kill and SIGUSR1. - */ - sigcounts[SIGUSR1] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 1) - fprintf (stderr, - "FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - /* Add SIGUSR1 to the waiters pending signals. */ - send_thread_signal (tid, SIGUSR1); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't return for pending SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (tid, &exit_status); - - return (0); -} diff --git a/lib/libkse/test/sigwait_d.exp b/lib/libkse/test/sigwait_d.exp deleted file mode 100644 index b9245be..0000000 --- a/lib/libkse/test/sigwait_d.exp +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ -Sigwait caught signal 16 -Sigwait caught signal 16 -Sigwait caught signal 30 -Sigwait caught signal 30 -Sigwait caught signal 1 -Sigwait caught signal 1 -Sigwait caught signal 1 - -> Signal handler caught signal 1 -Sigwait caught signal 30 -Sigwait caught signal 30 diff --git a/lib/libkse/test/verify b/lib/libkse/test/verify deleted file mode 100644 index 2863e5c..0000000 --- a/lib/libkse/test/verify +++ /dev/null @@ -1,474 +0,0 @@ -#!/usr/bin/perl -w -#-*-mode:perl-*- -############################################################################# -# -# Copyright (C) 1999-2001 Jason Evans <jasone@freebsd.org>. -# 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(s), this list of conditions and the following disclaimer as -# the first lines of this file unmodified other than the possible -# addition of one or more copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. -# -############################################################################# -# -# Test harness. -# -# $FreeBSD$ -# -############################################################################# - -# Shut off buffering. -select(STDOUT); -$| = 1; - -# -# Parse command-line arguments. -# -use Getopt::Long; -Getopt::Long::config("bundling"); # Allow -hv rather than forcing -h -v. - -# Set option defaults for optional arguments. -$opt_help = 0; -$opt_verbose = 0; -$opt_quiet = 0; -$opt_srcdir = "."; -$opt_objdir = "."; -$opt_ustats = 0; -$opt_zero = 0; - -$opt_retval = -&GetOptions("h|help" => \$opt_help, - "v|verbose" => \$opt_verbose, - "q|quiet" => \$opt_quiet, - "s|srcdir=s" => \$opt_srcdir, - "o|objdir=s" => \$opt_objdir, - "u|ustats" => \$opt_ustats, - "z|zero" => \$opt_zero - ); - -if ($opt_help) -{ - &usage(); - exit(0); -} - -if ($opt_retval == 0) -{ - &usage(); - exit 1; -} - -if ($opt_verbose && $opt_quiet) -{ - print STDERR "-v and -q are incompatible\n"; - &usage(); - exit 1; -} - -if ($#ARGV + 1 == 0) -{ - print STDERR "No tests specified\n"; - &usage(); - exit 1; -} - -if ($opt_verbose) -{ - print STDERR "Option values: h:$opt_help, v:$opt_verbose, " - . "s:\"$opt_srcdir\", o:\"$opt_objdir\" " - . "q:$opt_quiet, u:$opt_ustats, z:$opt_zero\n"; - printf STDERR "Tests (%d total): @ARGV\n", $#ARGV + 1; -} - -# -# Create and print header. -# -@TSTATS = -( - "--------------------------------------------------------------------------\n", - "Test c_user c_system c_total chng\n", - " passed/FAILED h_user h_system h_total %% chng\n" - ); - -if (!$opt_quiet) -{ - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } -} - -# -# Run sequence test(s). -# -$total_utime = 0.0; # Total user time. -$total_stime = 0.0; # Total system time. -$total_hutime = 0.0; # Total historical user time. -$total_hstime = 0.0; # Total historical system time. -$total_ntime = 0.0; # Total time for tests that have historical data. - -foreach $test (@ARGV) -{ - # Strip out any whitespace in $test. - $test =~ s/^\s*(.*)\s*$/$1/; - - $okay = 1; - - if (-e "$opt_srcdir/$test.exp") - { - # Diff mode. - - ($okay, $utime, $stime) = &run_test($test); - - if (-e "$opt_objdir/$test.out") - { - `diff $opt_srcdir/$test.exp $opt_objdir/$test.out > $opt_objdir/$test.diff 2>&1`; - if ($?) - { - # diff returns non-zero if there is a difference. - $okay = 0; - } - } - else - { - $okay = 0; - if ($opt_verbose) - { - print STDERR - "Nonexistent output file \"$opt_objdir/$test.out\"\n"; - } - } - - ($hutime, $hstime) = &print_stats($test, $okay, 0, 0, $utime, $stime); - } - else - { - # Sequence mode. - - ($okay, $utime, $stime) = &run_test($test); - - if (open (STEST_OUT, "<$opt_objdir/$test.out")) - { - $num_subtests = 0; - $num_failed_subtests = 0; - - while (defined($line = <STEST_OUT>)) - { - if ($line =~ /1\.\.(\d+)/) - { - $num_subtests = $1; - last; - } - } - if ($num_subtests == 0) - { - $okay = 0; - if ($opt_verbose) - { - print STDERR "Malformed or missing 1..n line\n"; - } - } - else - { - for ($subtest = 1; $subtest <= $num_subtests; $subtest++) - { - while (defined($line = <STEST_OUT>)) - { - if ($line =~ /^not\s+ok\s+(\d+)?/) - { - $not = 1; - $test_num = $1; - last; - } - elsif ($line =~ /^ok\s+(\d+)?/) - { - $not = 0; - $test_num = $1; - last; - } - } - if (defined($line)) - { - if (defined($test_num) && ($test_num != $subtest)) - { - # There was no output printed for one or more tests. - for (; $subtest < $test_num; $subtest++) - { - $num_failed_subtests++; - } - } - if ($not) - { - $num_failed_subtests++; - } - } - else - { - for (; $subtest <= $num_subtests; $subtest++) - { - $num_failed_subtests++; - } - } - } - - if (0 < $num_failed_subtests) - { - $okay = 0; - } - } - } - else - { - if (!$opt_quiet) - { - print STDERR "Cannot open output file \"$opt_objdir/$test.out\"\n"; - } - exit 1; - } - - ($hutime, $hstime) = &print_stats($test, $okay, - $num_failed_subtests, $num_subtests, - $utime, $stime); - } - - $total_hutime += $hutime; - $total_hstime += $hstime; - - if ($okay) - { - $total_utime += $utime; - $total_stime += $stime; - } - else - { - @FAILED_TESTS = (@FAILED_TESTS, $test); - } - - # If there were historical data, add the run time to the total time to - # compare against the historical run time. - if (0 < ($hutime + $hstime)) - { - $total_ntime += $utime + $stime; - } -} - -# Print summary stats. -$tt_str = sprintf ("%d / %d passed (%5.2f%%%%)", - ($#ARGV + 1) - ($#FAILED_TESTS + 1), - $#ARGV + 1, - (($#ARGV + 1) - ($#FAILED_TESTS + 1)) - / ($#ARGV + 1) * 100); - -$t_str = sprintf ("Totals %7.2f %7.2f %7.2f" - . " %7.2f\n" - . " %s %7.2f %7.2f %7.2f %7.2f%%%%\n", - $total_utime, $total_stime, $total_utime + $total_stime, - ($total_ntime - ($total_hutime + $total_hstime)), - $tt_str . ' ' x (40 - length($tt_str)), - $total_hutime, $total_hstime, $total_hutime + $total_hstime, - ($total_hutime + $total_hstime == 0.0) ? 0.0 : - (($total_ntime - - ($total_hutime + $total_hstime)) - / ($total_hutime + $total_hstime) * 100)); - -@TSTATS = ("--------------------------------------------------------------------------\n", - $t_str, - "--------------------------------------------------------------------------\n" - ); -if (!$opt_quiet) -{ - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } -} - -if ($#FAILED_TESTS >= 0) -{ - # One or more tests failed, so return an error. - exit 1; -} -# End of main execution. - -sub run_test -{ - my ($test) = @_; - my ($okay) = 1; - my ($tutime, $tstime); - my ($utime, $stime, $cutime, $cstime); - my (@TSTATS, @TPATH); - my ($t_str); - my ($srcdir, $objdir); - - # Get the path component of $test, if any. - @TPATH = split(/\//, $test); - pop(@TPATH); - $srcdir = join('/', ($opt_srcdir, @TPATH)); - $objdir = join('/', ($opt_objdir, @TPATH)); - - @TSTATS = ("--------------------------------------------------------------------------\n"); - - $t_str = sprintf ("%s%s", $test, ' ' x (40 - length($test))); - @TSTATS = (@TSTATS, $t_str); - @STATS = (@STATS, @TSTATS); - if (!$opt_quiet) - { - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } - } - - ($utime, $stime, $cutime, $cstime) = times; - `$opt_objdir/$test $srcdir $objdir > $opt_objdir/$test.out 2>&1`; - ($utime, $stime, $tutime, $tstime) = times; - - # Subtract the before time from the after time. - $tutime -= $cutime; - $tstime -= $cstime; - - if ($opt_zero) - { - if ($?) - { - $okay = 0; - if ($opt_verbose) - { - print STDERR - "\"$opt_objdir/$test > $opt_objdir/$test.out 2>&1\" returned $?\n"; - } - } - } - - return ($okay, $tutime, $tstime); -} - -sub print_stats -{ - my ($test, $okay, $failed_subtests, $subtests, $utime, $stime) = @_; - my ($hutime, $hstime); -# my (TEST_PERF); - my (@TSTATS); - my ($t_str, $pass_str); - - $pass_str = $okay ? "passed" : "*** FAILED ***"; - if ((0 != $subtests) && (!$okay)) - { - $pass_str = $pass_str . " ($failed_subtests/$subtests failed)"; - } - $pass_str = $pass_str . ' ' x (39 - length($pass_str)); - - if (-r "$test.perf") - { - if (!open (TEST_PERF, "<$opt_objdir/$test.perf")) - { - print STDERR "Unable to open \"$opt_objdir/$test.perf\"\n"; - exit 1; - } - $_ = <TEST_PERF>; - - ($hutime, $hstime) = split; - close TEST_PERF; - - $t_str = sprintf (" %7.2f %7.2f %7.2f %7.2f\n" - . " %s %7.2f %7.2f %7.2f %7.2f%%%%\n", - $utime, $stime, $utime + $stime, - ($utime + $stime) - ($hutime + $hstime), - $pass_str, - $hutime, $hstime, $hutime + $hstime, - (($hutime + $hstime) == 0.0) ? 0.0 : - ((($utime + $stime) - ($hutime + $hstime)) - / ($hutime + $hstime) * 100)); - } - else - { - $hutime = 0.0; - $hstime = 0.0; - - $t_str = sprintf (" %7.2f %7.2f %7.2f \n" - . " %s\n", - $utime, $stime, $utime + $stime, - $pass_str); - } - @TSTATS = ($t_str); - if (!$opt_quiet) - { - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } - } - - if ($okay && $opt_ustats) - { - if (!open (TEST_PERF, ">$opt_objdir/$test.perf")) - { - if (!$opt_quiet) - { - print STDERR "Unable to update \"$opt_objdir/$test.perf\"\n"; - } - } - else - { - print TEST_PERF "$utime $stime\n"; - close TEST_PERF; - } - } - - return ($hutime, $hstime); -} - -sub usage -{ - print <<EOF; -$0 usage: - $0 [<options>] <test>+ - - Option | Description - --------------+------------------------------------------------------------- - -h --help | Print usage and exit. - -v --verbose | Verbose (incompatible with quiet). - -q --quiet | Quiet (incompatible with verbose). - -s --srcdir | Path to source tree (default is "."). - -o --objdir | Path to object tree (default is "."). - -u --ustats | Update historical statistics (stored in "<test>.perf". - -z --zero | Consider non-zero exit code to be an error. - --------------+------------------------------------------------------------- - - If <test>.exp exists, <test>'s output is diff'ed with <test>.exp. Any - difference is considered failure. - - If <test>.exp does not exist, output to stdout of the following form is - expected: - - 1..<n> - {not }ok[ 1] - {not }ok[ 2] - ... - {not }ok[ n] - - 1 <= <n> < 2^31 - - Lines which do not match the patterns shown above are ignored. -EOF -} diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc deleted file mode 100644 index 561be93..0000000 --- a/lib/libkse/thread/Makefile.inc +++ /dev/null @@ -1,117 +0,0 @@ -# $FreeBSD$ - -# thr sources -.PATH: ${.CURDIR}/thread - -SRCS+= \ - thr_accept.c \ - thr_aio_suspend.c \ - thr_atfork.c \ - thr_attr_destroy.c \ - thr_attr_init.c \ - thr_attr_get_np.c \ - thr_attr_getdetachstate.c \ - thr_attr_getguardsize.c \ - thr_attr_getinheritsched.c \ - thr_attr_getschedparam.c \ - thr_attr_getschedpolicy.c \ - thr_attr_getscope.c \ - thr_attr_getstack.c \ - thr_attr_getstackaddr.c \ - thr_attr_getstacksize.c \ - thr_attr_setcreatesuspend_np.c \ - thr_attr_setdetachstate.c \ - thr_attr_setguardsize.c \ - thr_attr_setinheritsched.c \ - thr_attr_setschedparam.c \ - thr_attr_setschedpolicy.c \ - thr_attr_setscope.c \ - thr_attr_setstack.c \ - thr_attr_setstackaddr.c \ - thr_attr_setstacksize.c \ - thr_autoinit.c \ - thr_barrier.c \ - thr_barrierattr.c \ - thr_cancel.c \ - thr_clean.c \ - thr_close.c \ - thr_concurrency.c \ - thr_cond.c \ - thr_condattr_destroy.c \ - thr_condattr_init.c \ - thr_condattr_pshared.c \ - thr_connect.c \ - thr_creat.c \ - thr_create.c \ - thr_detach.c \ - thr_equal.c \ - thr_execve.c \ - thr_exit.c \ - thr_fcntl.c \ - thr_find_thread.c \ - thr_fork.c \ - thr_fsync.c \ - thr_getprio.c \ - thr_getschedparam.c \ - thr_info.c \ - thr_init.c \ - thr_join.c \ - thr_kern.c \ - thr_kill.c \ - thr_main_np.c \ - thr_mattr_init.c \ - thr_mattr_kind_np.c \ - thr_mattr_pshared.c \ - thr_msync.c \ - thr_multi_np.c \ - thr_mutex.c \ - thr_mutex_prioceiling.c \ - thr_mutex_protocol.c \ - thr_mutexattr_destroy.c \ - thr_nanosleep.c \ - thr_once.c \ - thr_open.c \ - thr_pause.c \ - thr_poll.c \ - thr_printf.c \ - thr_priority_queue.c \ - thr_pselect.c \ - thr_pspinlock.c \ - thr_raise.c \ - thr_read.c \ - thr_readv.c \ - thr_resume_np.c \ - thr_rtld.c \ - thr_rwlock.c \ - thr_rwlockattr.c \ - thr_select.c \ - thr_self.c \ - thr_sem.c \ - thr_seterrno.c \ - thr_setprio.c \ - thr_setschedparam.c \ - thr_sig.c \ - thr_sigaction.c \ - thr_sigaltstack.c \ - thr_sigmask.c \ - thr_sigpending.c \ - thr_sigprocmask.c \ - thr_sigsuspend.c \ - thr_sigwait.c \ - thr_single_np.c \ - thr_sleep.c \ - thr_spec.c \ - thr_spinlock.c \ - thr_stack.c \ - thr_suspend_np.c \ - thr_switch_np.c \ - thr_system.c \ - thr_symbols.c \ - thr_tcdrain.c \ - thr_vfork.c \ - thr_wait.c \ - thr_wait4.c \ - thr_waitpid.c \ - thr_write.c \ - thr_writev.c \ - thr_yield.c diff --git a/lib/libkse/thread/thr_accept.c b/lib/libkse/thread/thr_accept.c deleted file mode 100644 index 76327ef..0000000 --- a/lib/libkse/thread/thr_accept.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/socket.h> -#include <pthread.h> -#include "thr_private.h" - -int __accept(int s, struct sockaddr *addr, socklen_t *addrlen); - -__weak_reference(__accept, accept); - -int -__accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - ret = __sys_accept(s, addr, addrlen); - _thr_cancel_leave(curthread, ret == -1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_aio_suspend.c b/lib/libkse/thread/thr_aio_suspend.c deleted file mode 100644 index 87797f2..0000000 --- a/lib/libkse/thread/thr_aio_suspend.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <aio.h> -#include <pthread.h> -#include "thr_private.h" - - -int -_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct - timespec *timeout); - -__weak_reference(_aio_suspend, aio_suspend); - -int -_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct - timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_aio_suspend(iocbs, niocb, timeout); - _thr_cancel_leave(curthread, 1); - - return (ret); -} - diff --git a/lib/libkse/thread/thr_atfork.c b/lib/libkse/thread/thr_atfork.c deleted file mode 100644 index 638f27b..0000000 --- a/lib/libkse/thread/thr_atfork.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include <sys/queue.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_atfork, pthread_atfork); - -int -_pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)) -{ - struct pthread_atfork *af; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - if ((af = malloc(sizeof(struct pthread_atfork))) == NULL) - return (ENOMEM); - - af->prepare = prepare; - af->parent = parent; - af->child = child; - _pthread_mutex_lock(&_thr_atfork_mutex); - TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe); - _pthread_mutex_unlock(&_thr_atfork_mutex); - return (0); -} - diff --git a/lib/libkse/thread/thr_attr_destroy.c b/lib/libkse/thread/thr_attr_destroy.c deleted file mode 100644 index 3f48e1f..0000000 --- a/lib/libkse/thread/thr_attr_destroy.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_destroy, pthread_attr_destroy); - -int -_pthread_attr_destroy(pthread_attr_t *attr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL) - /* Invalid argument: */ - ret = EINVAL; - else { - /* Free the memory allocated to the attribute object: */ - free(*attr); - - /* - * Leave the attribute pointer NULL now that the memory - * has been freed: - */ - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getdetachstate.c b/lib/libkse/thread/thr_attr_getdetachstate.c deleted file mode 100644 index d9e16b8..0000000 --- a/lib/libkse/thread/thr_attr_getdetachstate.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate); - -int -_pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || detachstate == NULL) - ret = EINVAL; - else { - /* Check if the detached flag is set: */ - if ((*attr)->flags & PTHREAD_DETACHED) - /* Return detached: */ - *detachstate = PTHREAD_CREATE_DETACHED; - else - /* Return joinable: */ - *detachstate = PTHREAD_CREATE_JOINABLE; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getguardsize.c b/lib/libkse/thread/thr_attr_getguardsize.c deleted file mode 100644 index 65a1641..0000000 --- a/lib/libkse/thread/thr_attr_getguardsize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize); - -int -_pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || guardsize == NULL) - ret = EINVAL; - else { - /* Return the guard size: */ - *guardsize = (*attr)->guardsize_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getinheritsched.c b/lib/libkse/thread/thr_attr_getinheritsched.c deleted file mode 100644 index fdbdbe9..0000000 --- a/lib/libkse/thread/thr_attr_getinheritsched.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched); - -int -_pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else - *sched_inherit = (*attr)->sched_inherit; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getschedparam.c b/lib/libkse/thread/thr_attr_getschedparam.c deleted file mode 100644 index 369fc38..0000000 --- a/lib/libkse/thread/thr_attr_getschedparam.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam); - -int -_pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (param == NULL)) - ret = EINVAL; - else - param->sched_priority = (*attr)->prio; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getschedpolicy.c b/lib/libkse/thread/thr_attr_getschedpolicy.c deleted file mode 100644 index 28d48bc..0000000 --- a/lib/libkse/thread/thr_attr_getschedpolicy.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); - -int -_pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (policy == NULL)) - ret = EINVAL; - else - *policy = (*attr)->sched_policy; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getscope.c b/lib/libkse/thread/thr_attr_getscope.c deleted file mode 100644 index 96963cb..0000000 --- a/lib/libkse/thread/thr_attr_getscope.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getscope, pthread_attr_getscope); - -int -_pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL)) - /* Return an invalid argument: */ - ret = EINVAL; - - else - *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? - PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getstack.c b/lib/libkse/thread/thr_attr_getstack.c deleted file mode 100644 index 3d279f9..0000000 --- a/lib/libkse/thread/thr_attr_getstack.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Rodrigues. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstack, pthread_attr_getstack); - -int -_pthread_attr_getstack(const pthread_attr_t * __restrict attr, - void ** __restrict stackaddr, - size_t * __restrict stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL - || stacksize == NULL ) - ret = EINVAL; - else { - /* Return the stack address and size */ - *stackaddr = (*attr)->stackaddr_attr; - *stacksize = (*attr)->stacksize_attr; - ret = 0; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_attr_getstackaddr.c b/lib/libkse/thread/thr_attr_getstackaddr.c deleted file mode 100644 index 2c8e593..0000000 --- a/lib/libkse/thread/thr_attr_getstackaddr.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr); - -int -_pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL) - ret = EINVAL; - else { - /* Return the stack address: */ - *stackaddr = (*attr)->stackaddr_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getstacksize.c b/lib/libkse/thread/thr_attr_getstacksize.c deleted file mode 100644 index 25bb372..0000000 --- a/lib/libkse/thread/thr_attr_getstacksize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize); - -int -_pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stacksize == NULL) - ret = EINVAL; - else { - /* Return the stack size: */ - *stacksize = (*attr)->stacksize_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_init.c b/lib/libkse/thread/thr_attr_init.c deleted file mode 100644 index f320e4b..0000000 --- a/lib/libkse/thread/thr_attr_init.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_init, pthread_attr_init); - -int -_pthread_attr_init(pthread_attr_t *attr) -{ - int ret; - pthread_attr_t pattr; - - /* Allocate memory for the attribute object: */ - if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) - /* Insufficient memory: */ - ret = ENOMEM; - else { - /* Initialise the attribute object with the defaults: */ - memcpy(pattr, &_pthread_attr_default, - sizeof(struct pthread_attr)); - pattr->guardsize_attr = _thr_guard_default; - pattr->stacksize_attr = _thr_stack_default; - - /* Return a pointer to the attribute object: */ - *attr = pattr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setcreatesuspend_np.c b/lib/libkse/thread/thr_attr_setcreatesuspend_np.c deleted file mode 100644 index 4dbd181..0000000 --- a/lib/libkse/thread/thr_attr_setcreatesuspend_np.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr); - -__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np); - -int -_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) -{ - int ret; - - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - (*attr)->suspend = THR_CREATE_SUSPENDED; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setdetachstate.c b/lib/libkse/thread/thr_attr_setdetachstate.c deleted file mode 100644 index 6f45a18..0000000 --- a/lib/libkse/thread/thr_attr_setdetachstate.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate); - -int -_pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || - (detachstate != PTHREAD_CREATE_DETACHED && - detachstate != PTHREAD_CREATE_JOINABLE)) - ret = EINVAL; - else { - /* Check if detached state: */ - if (detachstate == PTHREAD_CREATE_DETACHED) - /* Set the detached flag: */ - (*attr)->flags |= PTHREAD_DETACHED; - else - /* Reset the detached flag: */ - (*attr)->flags &= ~PTHREAD_DETACHED; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setguardsize.c b/lib/libkse/thread/thr_attr_setguardsize.c deleted file mode 100644 index aa6e508..0000000 --- a/lib/libkse/thread/thr_attr_setguardsize.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize); - -int -_pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) -{ - int ret; - - /* Check for invalid arguments. */ - if (attr == NULL || *attr == NULL) - ret = EINVAL; - else { - /* Save the stack size. */ - (*attr)->guardsize_attr = guardsize; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setinheritsched.c b/lib/libkse/thread/thr_attr_setinheritsched.c deleted file mode 100644 index 5c1766b..0000000 --- a/lib/libkse/thread/thr_attr_setinheritsched.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched); - -int -_pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if (sched_inherit != PTHREAD_INHERIT_SCHED && - sched_inherit != PTHREAD_EXPLICIT_SCHED) - ret = ENOTSUP; - else - (*attr)->sched_inherit = sched_inherit; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setschedparam.c b/lib/libkse/thread/thr_attr_setschedparam.c deleted file mode 100644 index d7a6721..0000000 --- a/lib/libkse/thread/thr_attr_setschedparam.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam); - -int -_pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if (param == NULL) { - ret = ENOTSUP; - } else if ((param->sched_priority < THR_MIN_PRIORITY) || - (param->sched_priority > THR_MAX_PRIORITY)) { - /* Return an unsupported value error. */ - ret = ENOTSUP; - } else - (*attr)->prio = param->sched_priority; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setschedpolicy.c b/lib/libkse/thread/thr_attr_setschedpolicy.c deleted file mode 100644 index ac5df02..0000000 --- a/lib/libkse/thread/thr_attr_setschedpolicy.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); - -int -_pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) { - ret = ENOTSUP; - } else - (*attr)->sched_policy = policy; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setscope.c b/lib/libkse/thread/thr_attr_setscope.c deleted file mode 100644 index 97930e7..0000000 --- a/lib/libkse/thread/thr_attr_setscope.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setscope, pthread_attr_setscope); - -int -_pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) { - /* Return an invalid argument: */ - ret = EINVAL; - } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) && - (contentionscope != PTHREAD_SCOPE_SYSTEM)) { - ret = EINVAL; - } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) { - (*attr)->flags |= contentionscope; - } else { - (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_attr_setstack.c b/lib/libkse/thread/thr_attr_setstack.c deleted file mode 100644 index 127e60f..0000000 --- a/lib/libkse/thread/thr_attr_setstack.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Rodrigues. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstack, pthread_attr_setstack); - -int -_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, - size_t stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL - || stacksize < PTHREAD_STACK_MIN ) - ret = EINVAL; - else { - /* Save the stack address and stack size */ - (*attr)->stackaddr_attr = stackaddr; - (*attr)->stacksize_attr = stacksize; - ret = 0; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_attr_setstackaddr.c b/lib/libkse/thread/thr_attr_setstackaddr.c deleted file mode 100644 index 2d6cc1b..0000000 --- a/lib/libkse/thread/thr_attr_setstackaddr.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr); - -int -_pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL) - ret = EINVAL; - else { - /* Save the stack address: */ - (*attr)->stackaddr_attr = stackaddr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setstacksize.c b/lib/libkse/thread/thr_attr_setstacksize.c deleted file mode 100644 index 7d72d71..0000000 --- a/lib/libkse/thread/thr_attr_setstacksize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize); - -int -_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) - ret = EINVAL; - else { - /* Save the stack size: */ - (*attr)->stacksize_attr = stacksize; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_autoinit.c b/lib/libkse/thread/thr_autoinit.c deleted file mode 100644 index 95b2a85..0000000 --- a/lib/libkse/thread/thr_autoinit.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2002 Alfred Perlstein <alfred@freebsd.org>. - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * This module uses GCC extentions to initialize the - * threads package at program start-up time. - */ - -#include <pthread.h> -#include "thr_private.h" - -void _thread_init_hack(void) __attribute__ ((constructor)); - -void -_thread_init_hack(void) -{ - - _libpthread_init(NULL); -} - -/* - * For the shared version of the threads library, the above is sufficient. - * But for the archive version of the library, we need a little bit more. - * Namely, we must arrange for this particular module to be pulled in from - * the archive library at link time. To accomplish that, we define and - * initialize a variable, "_thread_autoinit_dummy_decl". This variable is - * referenced (as an extern) from libc/stdlib/exit.c. This will always - * create a need for this module, ensuring that it is present in the - * executable. - */ -extern int _thread_autoinit_dummy_decl; -int _thread_autoinit_dummy_decl = 0; diff --git a/lib/libkse/thread/thr_barrier.c b/lib/libkse/thread/thr_barrier.c deleted file mode 100644 index 21113cb..0000000 --- a/lib/libkse/thread/thr_barrier.c +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_barrier_init, pthread_barrier_init); -__weak_reference(_pthread_barrier_wait, pthread_barrier_wait); -__weak_reference(_pthread_barrier_destroy, pthread_barrier_destroy); - -int -_pthread_barrier_destroy(pthread_barrier_t *barrier) -{ - pthread_barrier_t bar; - int ret, ret2; - - if (barrier == NULL || *barrier == NULL) - return (EINVAL); - - bar = *barrier; - if (bar->b_waiters > 0) - return (EBUSY); - *barrier = NULL; - ret = _pthread_mutex_destroy(&bar->b_lock); - ret2 = _pthread_cond_destroy(&bar->b_cond); - free(bar); - return (ret ? ret : ret2); -} - -int -_pthread_barrier_init(pthread_barrier_t *barrier, - const pthread_barrierattr_t *attr __unused, unsigned count) -{ - pthread_barrier_t bar; - int ret; - - if (barrier == NULL || count <= 0) - return (EINVAL); - - bar = malloc(sizeof(struct pthread_barrier)); - if (bar == NULL) - return (ENOMEM); - - if ((ret = _pthread_mutex_init(&bar->b_lock, NULL)) != 0) { - free(bar); - return (ret); - } - - if ((ret = _pthread_cond_init(&bar->b_cond, NULL)) != 0) { - _pthread_mutex_destroy(&bar->b_lock); - free(bar); - return (ret); - } - - bar->b_waiters = 0; - bar->b_count = count; - bar->b_generation = 0; - *barrier = bar; - - return (0); -} - -int -_pthread_barrier_wait(pthread_barrier_t *barrier) -{ - int ret, gen; - pthread_barrier_t bar; - - if (barrier == NULL || *barrier == NULL) - return (EINVAL); - - bar = *barrier; - if ((ret = _pthread_mutex_lock(&bar->b_lock)) != 0) - return (ret); - - if (++bar->b_waiters == bar->b_count) { - /* Current thread is lastest thread */ - bar->b_generation++; - bar->b_waiters = 0; - ret = _pthread_cond_broadcast(&bar->b_cond); - if (ret == 0) - ret = PTHREAD_BARRIER_SERIAL_THREAD; - } else { - gen = bar->b_generation; - do { - ret = _pthread_cond_wait( - &bar->b_cond, &bar->b_lock); - /* test generation to avoid bogus wakeup */ - } while (ret == 0 && gen == bar->b_generation); - } - _pthread_mutex_unlock(&bar->b_lock); - return (ret); -} diff --git a/lib/libkse/thread/thr_barrierattr.c b/lib/libkse/thread/thr_barrierattr.c deleted file mode 100644 index 66411dc..0000000 --- a/lib/libkse/thread/thr_barrierattr.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2003 David Xu <davidxu@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_barrierattr_destroy, pthread_barrierattr_destroy); -__weak_reference(_pthread_barrierattr_init, pthread_barrierattr_init); -__weak_reference(_pthread_barrierattr_setpshared, - pthread_barrierattr_setpshared); -__weak_reference(_pthread_barrierattr_getpshared, - pthread_barrierattr_getpshared); - -int -_pthread_barrierattr_destroy(pthread_barrierattr_t *attr) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - free(*attr); - return (0); -} - -int -_pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, - int *pshared) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - *pshared = (*attr)->pshared; - return (0); -} - -int -_pthread_barrierattr_init(pthread_barrierattr_t *attr) -{ - - if (attr == NULL) - return (EINVAL); - - if ((*attr = malloc(sizeof(struct pthread_barrierattr))) == NULL) - return (ENOMEM); - - (*attr)->pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - - (*attr)->pshared = pshared; - return (0); -} diff --git a/lib/libkse/thread/thr_cancel.c b/lib/libkse/thread/thr_cancel.c deleted file mode 100644 index 7cffec4..0000000 --- a/lib/libkse/thread/thr_cancel.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * $FreeBSD$ - */ -#include "namespace.h" -#include <sys/errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_cancel, pthread_cancel); -__weak_reference(_pthread_setcancelstate, pthread_setcancelstate); -__weak_reference(_pthread_setcanceltype, pthread_setcanceltype); -__weak_reference(_pthread_testcancel, pthread_testcancel); - -static inline int -checkcancel(struct pthread *curthread) -{ - if ((curthread->cancelflags & THR_CANCELLING) != 0) { - /* - * It is possible for this thread to be swapped out - * while performing cancellation; do not allow it - * to be cancelled again. - */ - if ((curthread->flags & THR_FLAGS_EXITING) != 0) { - /* - * This may happen once, but after this, it - * shouldn't happen again. - */ - curthread->cancelflags &= ~THR_CANCELLING; - return (0); - } - if ((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) { - curthread->cancelflags &= ~THR_CANCELLING; - return (1); - } - } - return (0); -} - -static inline void -testcancel(struct pthread *curthread) -{ - if (checkcancel(curthread) != 0) { - /* Unlock before exiting: */ - THR_THREAD_UNLOCK(curthread, curthread); - - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } -} - -int -_pthread_cancel(pthread_t pthread) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *joinee = NULL; - struct kse_mailbox *kmbx = NULL; - int ret; - - if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) { - /* - * Take the thread's lock while we change the cancel flags. - */ - THR_THREAD_LOCK(curthread, pthread); - THR_SCHED_LOCK(curthread, pthread); - if (pthread->flags & THR_FLAGS_EXITING) { - THR_SCHED_UNLOCK(curthread, pthread); - THR_THREAD_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - return (ESRCH); - } - if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) || - (((pthread->cancelflags & THR_AT_CANCEL_POINT) == 0) && - ((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0))) - /* Just mark it for cancellation: */ - pthread->cancelflags |= THR_CANCELLING; - else { - /* - * Check if we need to kick it back into the - * run queue: - */ - switch (pthread->state) { - case PS_RUNNING: - /* No need to resume: */ - pthread->cancelflags |= THR_CANCELLING; - break; - - case PS_LOCKWAIT: - /* - * These can't be removed from the queue. - * Just mark it as cancelling and tell it - * to yield once it leaves the critical - * region. - */ - pthread->cancelflags |= THR_CANCELLING; - pthread->critical_yield = 1; - break; - - case PS_SLEEP_WAIT: - case PS_SIGSUSPEND: - case PS_SIGWAIT: - /* Interrupt and resume: */ - pthread->interrupted = 1; - pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - break; - - case PS_JOIN: - /* Disconnect the thread from the joinee: */ - joinee = pthread->join_status.thread; - pthread->join_status.thread = NULL; - pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - if ((joinee != NULL) && - (pthread->kseg == joinee->kseg)) { - /* Remove the joiner from the joinee. */ - joinee->joiner = NULL; - joinee = NULL; - } - break; - - case PS_SUSPENDED: - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - /* - * Threads in these states may be in queues. - * In order to preserve queue integrity, the - * cancelled thread must remove itself from the - * queue. Mark the thread as interrupted and - * needing cancellation, and set the state to - * running. When the thread resumes, it will - * remove itself from the queue and call the - * cancellation completion routine. - */ - pthread->interrupted = 1; - pthread->cancelflags |= THR_CANCEL_NEEDED; - kmbx = _thr_setrunnable_unlocked(pthread); - pthread->continuation = - _thr_finish_cancellation; - break; - - case PS_DEAD: - case PS_DEADLOCK: - case PS_STATE_MAX: - /* Ignore - only here to silence -Wall: */ - break; - } - if ((pthread->cancelflags & THR_AT_CANCEL_POINT) && - (pthread->blocked != 0 || - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); - } - - /* - * Release the thread's lock and remove the - * reference: - */ - THR_SCHED_UNLOCK(curthread, pthread); - THR_THREAD_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - - if ((joinee != NULL) && - (_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) { - /* Remove the joiner from the joinee. */ - THR_SCHED_LOCK(curthread, joinee); - joinee->joiner = NULL; - THR_SCHED_UNLOCK(curthread, joinee); - _thr_ref_delete(curthread, joinee); - } - } - return (ret); -} - -int -_pthread_setcancelstate(int state, int *oldstate) -{ - struct pthread *curthread = _get_curthread(); - int ostate; - int ret; - int need_exit = 0; - - /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); - - ostate = curthread->cancelflags & PTHREAD_CANCEL_DISABLE; - - switch (state) { - case PTHREAD_CANCEL_ENABLE: - curthread->cancelflags &= ~PTHREAD_CANCEL_DISABLE; - if ((curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0) - need_exit = checkcancel(curthread); - ret = 0; - break; - case PTHREAD_CANCEL_DISABLE: - curthread->cancelflags |= PTHREAD_CANCEL_DISABLE; - ret = 0; - break; - default: - ret = EINVAL; - } - - THR_THREAD_UNLOCK(curthread, curthread); - if (need_exit != 0) { - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } - if (ret == 0 && oldstate != NULL) - *oldstate = ostate; - - return (ret); -} - -int -_pthread_setcanceltype(int type, int *oldtype) -{ - struct pthread *curthread = _get_curthread(); - int otype; - int ret; - int need_exit = 0; - - /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); - - otype = curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS; - switch (type) { - case PTHREAD_CANCEL_ASYNCHRONOUS: - curthread->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS; - need_exit = checkcancel(curthread); - ret = 0; - break; - case PTHREAD_CANCEL_DEFERRED: - curthread->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS; - ret = 0; - break; - default: - ret = EINVAL; - } - - THR_THREAD_UNLOCK(curthread, curthread); - if (need_exit != 0) { - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } - if (ret == 0 && oldtype != NULL) - *oldtype = otype; - - return (ret); -} - -void -_pthread_testcancel(void) -{ - struct pthread *curthread = _get_curthread(); - - THR_THREAD_LOCK(curthread, curthread); - testcancel(curthread); - THR_THREAD_UNLOCK(curthread, curthread); -} - -void -_thr_cancel_enter(struct pthread *thread) -{ - /* Look for a cancellation before we block: */ - THR_THREAD_LOCK(thread, thread); - testcancel(thread); - thread->cancelflags |= THR_AT_CANCEL_POINT; - THR_THREAD_UNLOCK(thread, thread); -} - -void -_thr_cancel_leave(struct pthread *thread, int check) -{ - THR_THREAD_LOCK(thread, thread); - thread->cancelflags &= ~THR_AT_CANCEL_POINT; - /* Look for a cancellation after we unblock: */ - if (check) - testcancel(thread); - THR_THREAD_UNLOCK(thread, thread); -} - -void -_thr_finish_cancellation(void *arg __unused) -{ - struct pthread *curthread = _get_curthread(); - - curthread->continuation = NULL; - curthread->interrupted = 0; - - THR_THREAD_LOCK(curthread, curthread); - if ((curthread->cancelflags & THR_CANCEL_NEEDED) != 0) { - curthread->cancelflags &= ~THR_CANCEL_NEEDED; - THR_THREAD_UNLOCK(curthread, curthread); - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - } - THR_THREAD_UNLOCK(curthread, curthread); -} diff --git a/lib/libkse/thread/thr_clean.c b/lib/libkse/thread/thr_clean.c deleted file mode 100644 index 37323fd..0000000 --- a/lib/libkse/thread/thr_clean.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <signal.h> -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_cleanup_push, pthread_cleanup_push); -__weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop); - -void -_pthread_cleanup_push(void (*routine) (void *), void *routine_arg) -{ - struct pthread *curthread = _get_curthread(); - struct pthread_cleanup *new; - - if ((new = (struct pthread_cleanup *) - malloc(sizeof(struct pthread_cleanup))) != NULL) { - new->routine = routine; - new->routine_arg = routine_arg; - new->onstack = 0; - new->next = curthread->cleanup; - - curthread->cleanup = new; - } -} - -void -_pthread_cleanup_pop(int execute) -{ - struct pthread *curthread = _get_curthread(); - struct pthread_cleanup *old; - - if ((old = curthread->cleanup) != NULL) { - curthread->cleanup = old->next; - if (execute) { - old->routine(old->routine_arg); - } - if (old->onstack == 0) - free(old); - } -} diff --git a/lib/libkse/thread/thr_close.c b/lib/libkse/thread/thr_close.c deleted file mode 100644 index a76dab1..0000000 --- a/lib/libkse/thread/thr_close.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __close(int fd); - -__weak_reference(__close, close); - -int -__close(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_close(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_concurrency.c b/lib/libkse/thread/thr_concurrency.c deleted file mode 100644 index 8b1cf56..0000000 --- a/lib/libkse/thread/thr_concurrency.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (c) 2003 Sergey Osokin <osa@freebsd.org.ru>. - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/sysctl.h> -#include "un-namespace.h" - -#include "thr_private.h" - -/*#define DEBUG_CONCURRENCY */ -#ifdef DEBUG_CONCURRENCY -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -static int level = 0; - -__weak_reference(_pthread_getconcurrency, pthread_getconcurrency); -__weak_reference(_pthread_setconcurrency, pthread_setconcurrency); - -int -_pthread_getconcurrency(void) -{ - return (level); -} - -int -_pthread_setconcurrency(int new_level) -{ - int ret; - - if (new_level < 0) - ret = EINVAL; - else if (new_level == level) - ret = 0; - else if (new_level == 0) { - level = 0; - ret = 0; - } else if ((_kse_isthreaded() == 0) && (_kse_setthreaded(1) != 0)) { - DBG_MSG("Can't enable threading.\n"); - ret = EAGAIN; - } else { - ret = _thr_setconcurrency(new_level); - if (ret == 0) - level = new_level; - } - return (ret); -} - -int -_thr_setconcurrency(int new_level) -{ - struct pthread *curthread; - struct kse *newkse, *kse; - kse_critical_t crit; - int kse_count; - int i; - int ret; - - /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. - */ - if (_kse_isthreaded() == 0 && _kse_setthreaded(1)) - return (EAGAIN); - - ret = 0; - curthread = _get_curthread(); - /* Race condition, but so what. */ - kse_count = _kse_initial->k_kseg->kg_ksecount; - if (new_level > kse_count) { - for (i = kse_count; i < new_level; i++) { - newkse = _kse_alloc(curthread, 0); - if (newkse == NULL) { - DBG_MSG("Can't alloc new KSE.\n"); - ret = EAGAIN; - break; - } - newkse->k_kseg = _kse_initial->k_kseg; - newkse->k_schedq = _kse_initial->k_schedq; - newkse->k_curthread = NULL; - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); - TAILQ_INSERT_TAIL(&newkse->k_kseg->kg_kseq, - newkse, k_kgqe); - newkse->k_kseg->kg_ksecount++; - newkse->k_flags |= KF_STARTED; - KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg); - if (kse_create(&newkse->k_kcb->kcb_kmbx, 0) != 0) { - KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); - TAILQ_REMOVE(&newkse->k_kseg->kg_kseq, - newkse, k_kgqe); - newkse->k_kseg->kg_ksecount--; - KSE_SCHED_UNLOCK(curthread->kse, - newkse->k_kseg); - _kse_critical_leave(crit); - _kse_free(curthread, newkse); - DBG_MSG("kse_create syscall failed.\n"); - ret = EAGAIN; - break; - } else { - _kse_critical_leave(crit); - } - } - } else if (new_level < kse_count) { - kse_count = 0; - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, _kse_initial->k_kseg); - /* Count the number of active KSEs */ - TAILQ_FOREACH(kse, &_kse_initial->k_kseg->kg_kseq, k_kgqe) { - if ((kse->k_flags & KF_TERMINATED) == 0) - kse_count++; - } - /* Reduce the number of active KSEs appropriately. */ - kse = TAILQ_FIRST(&_kse_initial->k_kseg->kg_kseq); - while ((kse != NULL) && (kse_count > new_level)) { - if ((kse != _kse_initial) && - ((kse->k_flags & KF_TERMINATED) == 0)) { - kse->k_flags |= KF_TERMINATED; - kse_count--; - /* Wakup the KSE in case it is idle. */ - kse_wakeup(&kse->k_kcb->kcb_kmbx); - } - kse = TAILQ_NEXT(kse, k_kgqe); - } - KSE_SCHED_UNLOCK(curthread->kse, _kse_initial->k_kseg); - _kse_critical_leave(crit); - } - return (ret); -} - -int -_thr_setmaxconcurrency(void) -{ - int vcpu; - size_t len; - int ret; - - len = sizeof(vcpu); - ret = sysctlbyname("kern.threads.virtual_cpu", &vcpu, &len, NULL, 0); - if (ret == 0 && vcpu > 0) - ret = _thr_setconcurrency(vcpu); - return (ret); -} - diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c deleted file mode 100644 index 3f0b8a9..0000000 --- a/lib/libkse/thread/thr_cond.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -#define THR_IN_CONDQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0) -#define THR_CONDQ_SET(thr) (thr)->sflags |= THR_FLAGS_IN_SYNCQ -#define THR_CONDQ_CLEAR(thr) (thr)->sflags &= ~THR_FLAGS_IN_SYNCQ - -/* - * Prototypes - */ -static inline struct pthread *cond_queue_deq(pthread_cond_t); -static inline void cond_queue_remove(pthread_cond_t, pthread_t); -static inline void cond_queue_enq(pthread_cond_t, pthread_t); -static void cond_wait_backout(void *); -static inline void check_continuation(struct pthread *, - struct pthread_cond *, pthread_mutex_t *); - -int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); -int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime); - -/* - * Double underscore versions are cancellation points. Single underscore - * versions are not and are provided for libc internal usage (which - * shouldn't introduce cancellation points). - */ -__weak_reference(__pthread_cond_wait, pthread_cond_wait); -__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait); - -__weak_reference(_pthread_cond_init, pthread_cond_init); -__weak_reference(_pthread_cond_destroy, pthread_cond_destroy); -__weak_reference(_pthread_cond_signal, pthread_cond_signal); -__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast); - - -int -_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) -{ - enum pthread_cond_type type; - pthread_cond_t pcond; - int flags; - int rval = 0; - - if (cond == NULL) - rval = EINVAL; - else { - /* - * Check if a pointer to a condition variable attribute - * structure was passed by the caller: - */ - if (cond_attr != NULL && *cond_attr != NULL) { - /* Default to a fast condition variable: */ - type = (*cond_attr)->c_type; - flags = (*cond_attr)->c_flags; - } else { - /* Default to a fast condition variable: */ - type = COND_TYPE_FAST; - flags = 0; - } - - /* Process according to condition variable type: */ - switch (type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Nothing to do here. */ - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Check for no errors: */ - if (rval == 0) { - if ((pcond = (pthread_cond_t) - malloc(sizeof(struct pthread_cond))) == NULL) { - rval = ENOMEM; - } else if (_lock_init(&pcond->c_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) { - free(pcond); - rval = ENOMEM; - } else { - /* - * Initialise the condition variable - * structure: - */ - TAILQ_INIT(&pcond->c_queue); - pcond->c_flags = COND_FLAGS_INITED; - pcond->c_type = type; - pcond->c_mutex = NULL; - pcond->c_seqno = 0; - *cond = pcond; - } - } - } - /* Return the completion status: */ - return (rval); -} - -int -_pthread_cond_destroy(pthread_cond_t *cond) -{ - struct pthread_cond *cv; - struct pthread *curthread = _get_curthread(); - int rval = 0; - - if (cond == NULL || *cond == NULL) - rval = EINVAL; - else { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* - * NULL the caller's pointer now that the condition - * variable has been destroyed: - */ - cv = *cond; - *cond = NULL; - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cv->c_lock); - - /* Free the cond lock structure: */ - _lock_destroy(&cv->c_lock); - - /* - * Free the memory allocated for the condition - * variable structure: - */ - free(cv); - - } - /* Return the completion status: */ - return (rval); -} - -int -_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int rval = 0; - int done = 0; - int mutex_locked = 1; - int seqno; - - if (cond == NULL) - return (EINVAL); - - /* - * If the condition variable is statically initialized, - * perform the dynamic initialization: - */ - if (*cond == NULL && - (rval = _pthread_cond_init(cond, NULL)) != 0) - return (rval); - - if (!_kse_isthreaded()) - _kse_setthreaded(1); - - /* - * Enter a loop waiting for a condition signal or broadcast - * to wake up this thread. A loop is needed in case the waiting - * thread is interrupted by a signal to execute a signal handler. - * It is not (currently) possible to remain in the waiting queue - * while running a handler. Instead, the thread is interrupted - * and backed out of the waiting queue prior to executing the - * signal handler. - */ - - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - seqno = (*cond)->c_seqno; - do { - /* - * If the condvar was statically allocated, properly - * initialize the tail queue. - */ - if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*cond)->c_queue); - (*cond)->c_flags |= COND_FLAGS_INITED; - } - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - if ((mutex == NULL) || (((*cond)->c_mutex != NULL) && - ((*cond)->c_mutex != *mutex))) { - /* Return invalid argument error: */ - rval = EINVAL; - } else { - /* Reset the timeout and interrupted flags: */ - curthread->timeout = 0; - curthread->interrupted = 0; - - /* - * Queue the running thread for the condition - * variable: - */ - cond_queue_enq(*cond, curthread); - - /* Wait forever: */ - curthread->wakeup_time.tv_sec = -1; - - /* Unlock the mutex: */ - if (mutex_locked && - ((rval = _mutex_cv_unlock(mutex)) != 0)) { - /* - * Cannot unlock the mutex, so remove - * the running thread from the condition - * variable queue: - */ - cond_queue_remove(*cond, curthread); - } - else { - /* Remember the mutex: */ - (*cond)->c_mutex = *mutex; - - /* - * Don't unlock the mutex the next - * time through the loop (if the - * thread has to be requeued after - * handling a signal). - */ - mutex_locked = 0; - - /* - * This thread is active and is in a - * critical region (holding the cv - * lock); we should be able to safely - * set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - THR_SET_STATE(curthread, PS_COND_WAIT); - - /* Remember the CV: */ - curthread->data.cond = *cond; - curthread->sigbackout = cond_wait_backout; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the CV structure: */ - THR_LOCK_RELEASE(curthread, - &(*cond)->c_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - /* - * XXX - This really isn't a good check - * since there can be more than one - * thread waiting on the CV. Signals - * sent to threads waiting on mutexes - * or CVs should really be deferred - * until the threads are no longer - * waiting, but POSIX says that signals - * should be sent "as soon as possible". - */ - done = (seqno != (*cond)->c_seqno); - if (done && !THR_IN_CONDQ(curthread)) { - /* - * The thread is dequeued, so - * it is safe to clear these. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - check_continuation(curthread, - NULL, mutex); - return (_mutex_cv_lock(mutex)); - } - - /* Relock the CV structure: */ - THR_LOCK_ACQUIRE(curthread, - &(*cond)->c_lock); - - /* - * Clear these after taking the lock to - * prevent a race condition where a - * signal can arrive before dequeueing - * the thread. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - done = (seqno != (*cond)->c_seqno); - - if (THR_IN_CONDQ(curthread)) { - cond_queue_remove(*cond, - curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - } - } - } - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - check_continuation(curthread, *cond, - mutex_locked ? NULL : mutex); - } while ((done == 0) && (rval == 0)); - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - - if (mutex_locked == 0) - _mutex_cv_lock(mutex); - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_wait, _thr_cond_wait); - -int -__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _pthread_cond_wait(cond, mutex); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, - const struct timespec * abstime) -{ - struct pthread *curthread = _get_curthread(); - int rval = 0; - int done = 0; - int mutex_locked = 1; - int seqno; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - - if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || - abstime->tv_nsec >= 1000000000) - return (EINVAL); - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - if (*cond == NULL && (rval = _pthread_cond_init(cond, NULL)) != 0) - return (rval); - - if (!_kse_isthreaded()) - _kse_setthreaded(1); - - /* - * Enter a loop waiting for a condition signal or broadcast - * to wake up this thread. A loop is needed in case the waiting - * thread is interrupted by a signal to execute a signal handler. - * It is not (currently) possible to remain in the waiting queue - * while running a handler. Instead, the thread is interrupted - * and backed out of the waiting queue prior to executing the - * signal handler. - */ - - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - seqno = (*cond)->c_seqno; - do { - /* - * If the condvar was statically allocated, properly - * initialize the tail queue. - */ - if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*cond)->c_queue); - (*cond)->c_flags |= COND_FLAGS_INITED; - } - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - if ((mutex == NULL) || (((*cond)->c_mutex != NULL) && - ((*cond)->c_mutex != *mutex))) { - /* Return invalid argument error: */ - rval = EINVAL; - } else { - /* Reset the timeout and interrupted flags: */ - curthread->timeout = 0; - curthread->interrupted = 0; - - /* - * Queue the running thread for the condition - * variable: - */ - cond_queue_enq(*cond, curthread); - - /* Unlock the mutex: */ - if (mutex_locked && - ((rval = _mutex_cv_unlock(mutex)) != 0)) { - /* - * Cannot unlock the mutex; remove the - * running thread from the condition - * variable queue: - */ - cond_queue_remove(*cond, curthread); - } else { - /* Remember the mutex: */ - (*cond)->c_mutex = *mutex; - - /* - * Don't unlock the mutex the next - * time through the loop (if the - * thread has to be requeued after - * handling a signal). - */ - mutex_locked = 0; - - /* - * This thread is active and is in a - * critical region (holding the cv - * lock); we should be able to safely - * set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - THR_SET_STATE(curthread, PS_COND_WAIT); - - /* Remember the CV: */ - curthread->data.cond = *cond; - curthread->sigbackout = cond_wait_backout; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the CV structure: */ - THR_LOCK_RELEASE(curthread, - &(*cond)->c_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - /* - * XXX - This really isn't a good check - * since there can be more than one - * thread waiting on the CV. Signals - * sent to threads waiting on mutexes - * or CVs should really be deferred - * until the threads are no longer - * waiting, but POSIX says that signals - * should be sent "as soon as possible". - */ - done = (seqno != (*cond)->c_seqno); - if (done && !THR_IN_CONDQ(curthread)) { - /* - * The thread is dequeued, so - * it is safe to clear these. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - check_continuation(curthread, - NULL, mutex); - return (_mutex_cv_lock(mutex)); - } - - /* Relock the CV structure: */ - THR_LOCK_ACQUIRE(curthread, - &(*cond)->c_lock); - - /* - * Clear these after taking the lock to - * prevent a race condition where a - * signal can arrive before dequeueing - * the thread. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - - done = (seqno != (*cond)->c_seqno); - - if (THR_IN_CONDQ(curthread)) { - cond_queue_remove(*cond, - curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - } - - if (curthread->timeout != 0) { - /* The wait timedout. */ - rval = ETIMEDOUT; - } - } - } - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - check_continuation(curthread, *cond, - mutex_locked ? NULL : mutex); - } while ((done == 0) && (rval == 0)); - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - - if (mutex_locked == 0) - _mutex_cv_lock(mutex); - - /* Return the completion status: */ - return (rval); -} - -int -__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _pthread_cond_timedwait(cond, mutex, abstime); - _thr_cancel_leave(curthread, 1); - return (ret); -} - - -int -_pthread_cond_signal(pthread_cond_t * cond) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *pthread; - struct kse_mailbox *kmbx; - int rval = 0; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - if (cond == NULL) - rval = EINVAL; - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Increment the sequence number: */ - (*cond)->c_seqno++; - - /* - * Wakeups have to be done with the CV lock held; - * otherwise there is a race condition where the - * thread can timeout, run on another KSE, and enter - * another blocking state (including blocking on a CV). - */ - if ((pthread = TAILQ_FIRST(&(*cond)->c_queue)) - != NULL) { - THR_SCHED_LOCK(curthread, pthread); - cond_queue_remove(*cond, pthread); - pthread->sigbackout = NULL; - if ((pthread->kseg == curthread->kseg) && - (pthread->active_priority > - curthread->active_priority)) - curthread->critical_yield = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - } - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_signal, _thr_cond_signal); - -int -_pthread_cond_broadcast(pthread_cond_t * cond) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *pthread; - struct kse_mailbox *kmbx; - int rval = 0; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - if (cond == NULL) - rval = EINVAL; - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Increment the sequence number: */ - (*cond)->c_seqno++; - - /* - * Enter a loop to bring all threads off the - * condition queue: - */ - while ((pthread = TAILQ_FIRST(&(*cond)->c_queue)) - != NULL) { - THR_SCHED_LOCK(curthread, pthread); - cond_queue_remove(*cond, pthread); - pthread->sigbackout = NULL; - if ((pthread->kseg == curthread->kseg) && - (pthread->active_priority > - curthread->active_priority)) - curthread->critical_yield = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* There are no more waiting threads: */ - (*cond)->c_mutex = NULL; - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - } - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_broadcast, _thr_cond_broadcast); - -static inline void -check_continuation(struct pthread *curthread, struct pthread_cond *cond, - pthread_mutex_t *mutex) -{ - if ((curthread->interrupted != 0) && - (curthread->continuation != NULL)) { - if (cond != NULL) - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cond->c_lock); - /* - * Note that even though this thread may have been - * canceled, POSIX requires that the mutex be - * reaquired prior to cancellation. - */ - if (mutex != NULL) - _mutex_cv_lock(mutex); - curthread->continuation((void *) curthread); - PANIC("continuation returned in pthread_cond_wait.\n"); - } -} - -static void -cond_wait_backout(void *arg) -{ - struct pthread *curthread = (struct pthread *)arg; - pthread_cond_t cond; - - cond = curthread->data.cond; - if (cond != NULL) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &cond->c_lock); - - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - cond_queue_remove(cond, curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&cond->c_queue)) - cond->c_mutex = NULL; - break; - - default: - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cond->c_lock); - } - /* No need to call this again. */ - curthread->sigbackout = NULL; -} - -/* - * Dequeue a waiting thread from the head of a condition queue in - * descending priority order. - */ -static inline struct pthread * -cond_queue_deq(pthread_cond_t cond) -{ - struct pthread *pthread; - - while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) { - TAILQ_REMOVE(&cond->c_queue, pthread, sqe); - THR_CONDQ_CLEAR(pthread); - if ((pthread->timeout == 0) && (pthread->interrupted == 0)) - /* - * Only exit the loop when we find a thread - * that hasn't timed out or been canceled; - * those threads are already running and don't - * need their run state changed. - */ - break; - } - - return (pthread); -} - -/* - * Remove a waiting thread from a condition queue in descending priority - * order. - */ -static inline void -cond_queue_remove(pthread_cond_t cond, struct pthread *pthread) -{ - /* - * Because pthread_cond_timedwait() can timeout as well - * as be signaled by another thread, it is necessary to - * guard against removing the thread from the queue if - * it isn't in the queue. - */ - if (THR_IN_CONDQ(pthread)) { - TAILQ_REMOVE(&cond->c_queue, pthread, sqe); - THR_CONDQ_CLEAR(pthread); - } -} - -/* - * Enqueue a waiting thread to a condition queue in descending priority - * order. - */ -static inline void -cond_queue_enq(pthread_cond_t cond, struct pthread *pthread) -{ - struct pthread *tid = TAILQ_LAST(&cond->c_queue, cond_head); - - THR_ASSERT(!THR_IN_SYNCQ(pthread), - "cond_queue_enq: thread already queued!"); - - /* - * For the common case of all threads having equal priority, - * we perform a quick check against the priority of the thread - * at the tail of the queue. - */ - if ((tid == NULL) || (pthread->active_priority <= tid->active_priority)) - TAILQ_INSERT_TAIL(&cond->c_queue, pthread, sqe); - else { - tid = TAILQ_FIRST(&cond->c_queue); - while (pthread->active_priority <= tid->active_priority) - tid = TAILQ_NEXT(tid, sqe); - TAILQ_INSERT_BEFORE(tid, pthread, sqe); - } - THR_CONDQ_SET(pthread); - pthread->data.cond = cond; -} diff --git a/lib/libkse/thread/thr_condattr_destroy.c b/lib/libkse/thread/thr_condattr_destroy.c deleted file mode 100644 index 67af37f..0000000 --- a/lib/libkse/thread/thr_condattr_destroy.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_condattr_destroy, pthread_condattr_destroy); - -int -_pthread_condattr_destroy(pthread_condattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_condattr_init.c b/lib/libkse/thread/thr_condattr_init.c deleted file mode 100644 index e67364d..0000000 --- a/lib/libkse/thread/thr_condattr_init.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_condattr_init, pthread_condattr_init); - -int -_pthread_condattr_init(pthread_condattr_t *attr) -{ - int ret; - pthread_condattr_t pattr; - - if ((pattr = (pthread_condattr_t) - malloc(sizeof(struct pthread_cond_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_condattr_default, - sizeof(struct pthread_cond_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_condattr_pshared.c b/lib/libkse/thread/thr_condattr_pshared.c deleted file mode 100644 index 79e1d60..0000000 --- a/lib/libkse/thread/thr_condattr_pshared.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2005 David Xu <davidxu@freebsd.org> - * 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 unmodified, 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include <errno.h> -#include "thr_private.h" - -int _pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared); -int _pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); - -__weak_reference(_pthread_condattr_getpshared, pthread_condattr_getpshared); -__weak_reference(_pthread_condattr_setpshared, pthread_condattr_setpshared); - -int -_pthread_condattr_getpshared(const pthread_condattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libkse/thread/thr_connect.c b/lib/libkse/thread/thr_connect.c deleted file mode 100644 index 523a1d3..0000000 --- a/lib/libkse/thread/thr_connect.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/socket.h> -#include <pthread.h> -#include "thr_private.h" - -int __connect(int fd, const struct sockaddr *name, socklen_t namelen); - -__weak_reference(__connect, connect); - -int -__connect(int fd, const struct sockaddr *name, socklen_t namelen) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - ret = __sys_connect(fd, name, namelen); - _thr_cancel_leave(curthread, ret == -1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_creat.c b/lib/libkse/thread/thr_creat.c deleted file mode 100644 index 63c8067..0000000 --- a/lib/libkse/thread/thr_creat.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -extern int __creat(const char *, mode_t); - -int ___creat(const char *path, mode_t mode); - -__weak_reference(___creat, creat); - -int -___creat(const char *path, mode_t mode) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __creat(path, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c deleted file mode 100644 index de1719c..0000000 --- a/lib/libkse/thread/thr_create.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com> - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <stddef.h> -#include <sys/time.h> -#include <machine/reg.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" -#include "libc_private.h" - -static void free_thread(struct pthread *curthread, struct pthread *thread); -static int create_stack(struct pthread_attr *pattr); -static void free_stack(struct pthread_attr *pattr); -static void thread_start(struct pthread *curthread, - void *(*start_routine) (void *), void *arg); - -__weak_reference(_pthread_create, pthread_create); - -/* - * Some notes on new thread creation and first time initializion - * to enable multi-threading. - * - * There are basically two things that need to be done. - * - * 1) The internal library variables must be initialized. - * 2) Upcalls need to be enabled to allow multiple threads - * to be run. - * - * The first may be done as a result of other pthread functions - * being called. When _thr_initial is null, _libpthread_init is - * called to initialize the internal variables; this also creates - * or sets the initial thread. It'd be nice to automatically - * have _libpthread_init called on program execution so we don't - * have to have checks throughout the library. - * - * The second part is only triggered by the creation of the first - * thread (other than the initial/main thread). If the thread - * being created is a scope system thread, then a new KSE/KSEG - * pair needs to be allocated. Also, if upcalls haven't been - * enabled on the initial thread's KSE, they must be now that - * there is more than one thread; this could be delayed until - * the initial KSEG has more than one thread. - */ -int -_pthread_create(pthread_t * thread, const pthread_attr_t * attr, - void *(*start_routine) (void *), void *arg) -{ - struct pthread *curthread, *new_thread; - struct kse *kse = NULL; - struct kse_group *kseg = NULL; - kse_critical_t crit; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. - */ - if (_kse_isthreaded() == 0 && _kse_setthreaded(1)) { - return (EAGAIN); - } - curthread = _get_curthread(); - - /* - * Allocate memory for the thread structure. - * Some functions use malloc, so don't put it - * in a critical region. - */ - if ((new_thread = _thr_alloc(curthread)) == NULL) { - /* Insufficient memory to create a thread: */ - ret = EAGAIN; - } else { - /* Check if default thread attributes are required: */ - if (attr == NULL || *attr == NULL) - /* Use the default thread attributes: */ - new_thread->attr = _pthread_attr_default; - else { - new_thread->attr = *(*attr); - if ((*attr)->sched_inherit == PTHREAD_INHERIT_SCHED) { - /* inherit scheduling contention scop */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - /* - * scheduling policy and scheduling parameters will be - * inherited in following code. - */ - } - } - if (_thread_scope_system > 0) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else if ((_thread_scope_system < 0) - && (thread != &_thr_sig_daemon)) - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - if (create_stack(&new_thread->attr) != 0) { - /* Insufficient memory to create a stack: */ - ret = EAGAIN; - _thr_free(curthread, new_thread); - } - else if (((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - (((kse = _kse_alloc(curthread, 1)) == NULL) - || ((kseg = _kseg_alloc(curthread)) == NULL))) { - /* Insufficient memory to create a new KSE/KSEG: */ - ret = EAGAIN; - if (kse != NULL) { - kse->k_kcb->kcb_kmbx.km_flags |= KMF_DONE; - _kse_free(curthread, kse); - } - free_stack(&new_thread->attr); - _thr_free(curthread, new_thread); - } - else { - if (kseg != NULL) { - /* Add the KSE to the KSEG's list of KSEs. */ - TAILQ_INSERT_HEAD(&kseg->kg_kseq, kse, k_kgqe); - kseg->kg_ksecount = 1; - kse->k_kseg = kseg; - kse->k_schedq = &kseg->kg_schedq; - } - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - new_thread->magic = THR_MAGIC; - - new_thread->slice_usec = -1; - new_thread->start_routine = start_routine; - new_thread->arg = arg; - new_thread->cancelflags = PTHREAD_CANCEL_ENABLE | - PTHREAD_CANCEL_DEFERRED; - - /* No thread is wanting to join to this one: */ - new_thread->joiner = NULL; - - /* - * Initialize the machine context. - * Enter a critical region to get consistent context. - */ - crit = _kse_critical_enter(); - THR_GETCONTEXT(&new_thread->tcb->tcb_tmbx.tm_context); - /* Initialize the thread for signals: */ - new_thread->sigmask = curthread->sigmask; - _kse_critical_leave(crit); - - new_thread->tcb->tcb_tmbx.tm_udata = new_thread; - new_thread->tcb->tcb_tmbx.tm_context.uc_sigmask = - new_thread->sigmask; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - new_thread->attr.stacksize_attr; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - new_thread->attr.stackaddr_attr; - makecontext(&new_thread->tcb->tcb_tmbx.tm_context, - (void (*)(void))thread_start, 3, new_thread, - start_routine, arg); - /* - * Check if this thread is to inherit the scheduling - * attributes from its parent: - */ - if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { - /* - * Copy the scheduling attributes. - * Lock the scheduling lock to get consistent - * scheduling parameters. - */ - THR_SCHED_LOCK(curthread, curthread); - new_thread->base_priority = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.prio = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.sched_policy = - curthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - } else { - /* - * Use just the thread priority, leaving the - * other scheduling attributes as their - * default values: - */ - new_thread->base_priority = - new_thread->attr.prio; - } - new_thread->active_priority = new_thread->base_priority; - new_thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&new_thread->mutexq); - - /* Initialise hooks in the thread structure: */ - new_thread->specific = NULL; - new_thread->specific_data_count = 0; - new_thread->cleanup = NULL; - new_thread->flags = 0; - new_thread->tlflags = 0; - new_thread->sigbackout = NULL; - new_thread->continuation = NULL; - new_thread->wakeup_time.tv_sec = -1; - new_thread->lock_switch = 0; - sigemptyset(&new_thread->sigpend); - new_thread->check_pending = 0; - new_thread->locklevel = 0; - new_thread->rdlock_count = 0; - new_thread->sigstk.ss_sp = 0; - new_thread->sigstk.ss_size = 0; - new_thread->sigstk.ss_flags = SS_DISABLE; - new_thread->oldsigmask = NULL; - - if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { - new_thread->state = PS_SUSPENDED; - new_thread->flags = THR_FLAGS_SUSPENDED; - } - else - new_thread->state = PS_RUNNING; - - /* - * System scope threads have their own kse and - * kseg. Process scope threads are all hung - * off the main process kseg. - */ - if ((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) { - new_thread->kseg = _kse_initial->k_kseg; - new_thread->kse = _kse_initial; - } - else { - kse->k_curthread = NULL; - kse->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - new_thread->kse = kse; - new_thread->kseg = kse->k_kseg; - kse->k_kcb->kcb_kmbx.km_udata = kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - } - - /* - * Schedule the new thread starting a new KSEG/KSE - * pair if necessary. - */ - ret = _thr_schedule_add(curthread, new_thread); - if (ret != 0) - free_thread(curthread, new_thread); - else { - /* Return a pointer to the thread structure: */ - (*thread) = new_thread; - } - } - } - - /* Return the status: */ - return (ret); -} - -static void -free_thread(struct pthread *curthread, struct pthread *thread) -{ - free_stack(&thread->attr); - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* Free the KSE and KSEG. */ - _kseg_free(thread->kseg); - _kse_free(curthread, thread->kse); - } - _thr_free(curthread, thread); -} - -static int -create_stack(struct pthread_attr *pattr) -{ - int ret; - - /* Check if a stack was specified in the thread attributes: */ - if ((pattr->stackaddr_attr) != NULL) { - pattr->guardsize_attr = 0; - pattr->flags |= THR_STACK_USER; - ret = 0; - } - else - ret = _thr_stack_alloc(pattr); - return (ret); -} - -static void -free_stack(struct pthread_attr *pattr) -{ - struct kse *curkse; - kse_critical_t crit; - - if ((pattr->flags & THR_STACK_USER) == 0) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Stack routines don't use malloc/free. */ - _thr_stack_free(pattr); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} - -static void -thread_start(struct pthread *curthread __unused, void *(*start_routine) (void *), - void *arg) -{ - /* Run the current thread's start routine with argument: */ - _pthread_exit(start_routine(arg)); - - /* This point should never be reached. */ - PANIC("Thread has resumed after exit"); -} diff --git a/lib/libkse/thread/thr_detach.c b/lib/libkse/thread/thr_detach.c deleted file mode 100644 index adb6861..0000000 --- a/lib/libkse/thread/thr_detach.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include "namespace.h" -#include <sys/types.h> -#include <machine/atomic.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_detach, pthread_detach); - -int -_pthread_detach(pthread_t pthread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - struct pthread *joiner; - int rval = 0; - - /* Check for invalid calling parameters: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) - /* Return an invalid argument error: */ - rval = EINVAL; - - else if ((rval = _thr_ref_add(curthread, pthread, - /*include dead*/1)) != 0) { - /* Return an error: */ - } - - /* Check if the thread is already detached: */ - else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - /* Return an error: */ - _thr_ref_delete(curthread, pthread); - rval = EINVAL; - } else { - /* Lock the detached thread: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Flag the thread as detached: */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Retrieve any joining thread and remove it: */ - joiner = pthread->joiner; - if ((joiner != NULL) && (joiner->kseg == pthread->kseg)) { - /* - * We already own the scheduler lock for the joiner. - * Take advantage of that and make the joiner runnable. - */ - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - joiner = NULL; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* See if there is a thread waiting in pthread_join(): */ - if ((joiner != NULL) && - (_thr_ref_add(curthread, joiner, 0) == 0)) { - /* Lock the joiner before fiddling with it. */ - THR_SCHED_LOCK(curthread, joiner); - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - THR_SCHED_UNLOCK(curthread, joiner); - _thr_ref_delete(curthread, joiner); - } - _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (rval); -} diff --git a/lib/libkse/thread/thr_execve.c b/lib/libkse/thread/thr_execve.c deleted file mode 100644 index 2e700fc..0000000 --- a/lib/libkse/thread/thr_execve.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2004 Daniel Eischen <deischen@freebsd.org> - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <unistd.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_execve, execve); - -int -_execve(const char *name, char *const *argv, char *const *envp) -{ - struct kse_execve_args args; - struct pthread *curthread = _get_curthread(); - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - ret = __sys_execve(name, argv, envp); - else { - /* - * When exec'ing, set the kernel signal mask to the thread's - * signal mask to satisfy POSIX requirements. - */ - args.sigmask = curthread->sigmask; - args.sigpend = curthread->sigpend; - args.path = (char *)name; - args.argv = (char **)argv; - args.envp = (char **)envp; - args.reserved = NULL; - ret = kse_thr_interrupt(NULL, KSE_INTR_EXECVE, (long)&args); - } - - return (ret); -} diff --git a/lib/libkse/thread/thr_exit.c b/lib/libkse/thread/thr_exit.c deleted file mode 100644 index 7c61821..0000000 --- a/lib/libkse/thread/thr_exit.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -void _pthread_exit(void *status); - -__weak_reference(_pthread_exit, pthread_exit); - -void -_thr_exit(const char *fname, int lineno, const char *msg) -{ - - /* Write an error message to the standard error file descriptor: */ - _thread_printf(2, - "Fatal error '%s' at line %d in file %s (errno = %d)\n", - msg, lineno, fname, errno); - - abort(); -} - -/* - * Only called when a thread is cancelled. It may be more useful - * to call it from pthread_exit() if other ways of asynchronous or - * abnormal thread termination can be found. - */ -void -_thr_exit_cleanup(void) -{ - struct pthread *curthread = _get_curthread(); - - /* - * POSIX states that cancellation/termination of a thread should - * not release any visible resources (such as mutexes) and that - * it is the applications responsibility. Resources that are - * internal to the threads library, including file and fd locks, - * are not visible to the application and need to be released. - */ - /* Unlock all private mutexes: */ - _mutex_unlock_private(curthread); - - /* - * This still isn't quite correct because we don't account - * for held spinlocks (see libc/stdlib/malloc.c). - */ -} - -void -_pthread_exit(void *status) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - struct kse *curkse; - - /* Check if this thread is already in the process of exiting: */ - if ((curthread->flags & THR_FLAGS_EXITING) != 0) { - char msg[128]; - snprintf(msg, sizeof(msg), "Thread %p has called " - "pthread_exit() from a destructor. POSIX 1003.1 " - "1996 s16.2.5.2 does not allow this!", curthread); - PANIC(msg); - } - - /* - * Flag this thread as exiting. Threads should now be prevented - * from joining to this thread. - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->flags |= THR_FLAGS_EXITING; - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * To avoid signal-lost problem, if signals had already been - * delivered to us, handle it. we have already set EXITING flag - * so no new signals should be delivered to us. - * XXX this is not enough if signal was delivered just before - * thread called sigprocmask and masked it! in this case, we - * might have to re-post the signal by kill() if the signal - * is targeting process (not for a specified thread). - * Kernel has same signal-lost problem, a signal may be delivered - * to a thread which is on the way to call sigprocmask or thr_exit()! - */ - if (curthread->check_pending) - _thr_sig_check_pending(curthread); - /* Save the return value: */ - curthread->ret = status; - while (curthread->cleanup != NULL) { - _pthread_cleanup_pop(1); - } - if (curthread->attr.cleanup_attr != NULL) { - curthread->attr.cleanup_attr(curthread->attr.arg_attr); - } - /* Check if there is thread specific data: */ - if (curthread->specific != NULL) { - /* Run the thread-specific data destructors: */ - _thread_cleanupspecific(); - } - if (!_kse_isthreaded()) - exit(0); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Use thread_list_lock */ - _thread_active_threads--; - if ((_thread_scope_system <= 0 && _thread_active_threads == 1) || - (_thread_scope_system > 0 && _thread_active_threads == 0)) { - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - exit(0); - /* Never reach! */ - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - /* This thread will never be re-scheduled. */ - KSE_LOCK(curkse); - THR_SET_STATE(curthread, PS_DEAD); - _thr_sched_switch_unlocked(curthread); - /* Never reach! */ - - /* This point should not be reached. */ - PANIC("Dead thread has resumed"); -} diff --git a/lib/libkse/thread/thr_fcntl.c b/lib/libkse/thread/thr_fcntl.c deleted file mode 100644 index e739633..0000000 --- a/lib/libkse/thread/thr_fcntl.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdarg.h> -#include <fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __fcntl(int fd, int cmd,...); -extern int __fcntl_compat(int fd, int cmd,...); - -__weak_reference(__fcntl, fcntl); - -int -__fcntl(int fd, int cmd,...) -{ - struct pthread *curthread = _get_curthread(); - int ret, check = 1; - va_list ap; - - _thr_cancel_enter(curthread); - - va_start(ap, cmd); - switch (cmd) { - case F_DUPFD: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - check = (ret == -1); - break; - case F_SETFD: - case F_SETFL: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - break; - case F_GETFD: - case F_GETFL: - ret = __sys_fcntl(fd, cmd); - break; - default: - ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); - } - va_end(ap); - - _thr_cancel_leave(curthread, check); - - return (ret); -} diff --git a/lib/libkse/thread/thr_find_thread.c b/lib/libkse/thread/thr_find_thread.c deleted file mode 100644 index e146e97..0000000 --- a/lib/libkse/thread/thr_find_thread.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* - * Find a thread in the linked list of active threads and add a reference - * to it. Threads with positive reference counts will not be deallocated - * until all references are released. - */ -int -_thr_ref_add(struct pthread *curthread, struct pthread *thread, - int include_dead) -{ - kse_critical_t crit; - struct pthread *pthread; - struct kse *curkse; - - if (thread == NULL) - /* Invalid thread: */ - return (EINVAL); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - pthread = _thr_hash_find(thread); - if (pthread) { - if ((include_dead == 0) && - ((pthread->state == PS_DEAD) || - ((pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)))) - pthread = NULL; - else { - pthread->refcount++; - if (curthread != NULL) - curthread->critical_count++; - } - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Return zero if the thread exists: */ - return ((pthread != NULL) ? 0 : ESRCH); -} - -void -_thr_ref_delete(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - if (thread != NULL) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->refcount--; - if (curthread != NULL) - curthread->critical_count--; - if ((thread->refcount == 0) && - (thread->tlflags & TLFLAGS_GC_SAFE) != 0) - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} diff --git a/lib/libkse/thread/thr_fork.c b/lib/libkse/thread/thr_fork.c deleted file mode 100644 index 659bcb3..0000000 --- a/lib/libkse/thread/thr_fork.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <pthread.h> -#include <spinlock.h> -#include <sys/signalvar.h> -#include "un-namespace.h" - -#include "libc_private.h" -#include "thr_private.h" - -pid_t _fork(void); - -__weak_reference(_fork, fork); - -pid_t -_fork(void) -{ - sigset_t sigset, oldset; - struct pthread *curthread; - struct pthread_atfork *af; - pid_t ret; - int errsave; - - curthread = _get_curthread(); - - if (!_kse_isthreaded()) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - ret = __sys_fork(); - if (ret == 0) - /* Child */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - else - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - return (ret); - } - - /* - * Masks all signals until we reach a safe point in - * _kse_single_thread, and the signal masks will be - * restored in that function, for M:N thread, all - * signals were already masked in kernel atomically, - * we only need to do this for bound thread. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - } - - _pthread_mutex_lock(&_thr_atfork_mutex); - - /* Run down atfork prepare handlers. */ - TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { - if (af->prepare != NULL) - af->prepare(); - } - - /* Fork a new process: */ - if (_kse_isthreaded() != 0) { - _malloc_prefork(); - } - if ((ret = __sys_fork()) == 0) { - /* Child process */ - errsave = errno; - - /* Kernel signal mask is restored in _kse_single_thread */ - _kse_single_thread(curthread); - - /* Run down atfork child handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->child != NULL) - af->child(); - } - _thr_mutex_reinit(&_thr_atfork_mutex); - } else { - if (_kse_isthreaded() != 0) { - _malloc_postfork(); - } - errsave = errno; - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - } - /* Run down atfork parent handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->parent != NULL) - af->parent(); - } - _pthread_mutex_unlock(&_thr_atfork_mutex); - } - errno = errsave; - - /* Return the process ID: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_fsync.c b/lib/libkse/thread/thr_fsync.c deleted file mode 100644 index 7cf52aa..0000000 --- a/lib/libkse/thread/thr_fsync.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __fsync(int fd); - -__weak_reference(__fsync, fsync); - -int -__fsync(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_fsync(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_getprio.c b/lib/libkse/thread/thr_getprio.c deleted file mode 100644 index 0672d90..0000000 --- a/lib/libkse/thread/thr_getprio.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -__weak_reference(_pthread_getprio, pthread_getprio); - -int -_pthread_getprio(pthread_t pthread) -{ - int policy, ret; - struct sched_param param; - - if ((ret = _pthread_getschedparam(pthread, &policy, ¶m)) == 0) - ret = param.sched_priority; - else { - /* Invalid thread: */ - errno = ret; - ret = -1; - } - - /* Return the thread priority or an error status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_getschedparam.c b/lib/libkse/thread/thr_getschedparam.c deleted file mode 100644 index 0cb1cc5..0000000 --- a/lib/libkse/thread/thr_getschedparam.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_getschedparam, pthread_getschedparam); - -int -_pthread_getschedparam(pthread_t pthread, int *policy, - struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int ret, tmp; - - if ((param == NULL) || (policy == NULL)) - /* Return an invalid argument error: */ - ret = EINVAL; - else if (pthread == curthread) { - /* - * Avoid searching the thread list when it is the current - * thread. - */ - THR_SCHED_LOCK(curthread, curthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - *policy = tmp; - ret = 0; - } - /* Find the thread in the list of active threads. */ - else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - THR_SCHED_LOCK(curthread, pthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - *policy = tmp; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_info.c b/lib/libkse/thread/thr_info.c deleted file mode 100644 index ac0e750..0000000 --- a/lib/libkse/thread/thr_info.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <errno.h> -#include "un-namespace.h" -#include "thr_private.h" - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof(arr) / sizeof(arr[0])) -#endif - -static void dump_thread(int fd, pthread_t pthread, int long_version); -void _pthread_set_name_np(pthread_t thread, char *name); - -__weak_reference(_pthread_set_name_np, pthread_set_name_np); - -struct s_thread_info { - enum pthread_state state; - const char *name; -}; - -/* Static variables: */ -static const struct s_thread_info thread_info[] = { - {PS_RUNNING , "Running"}, - {PS_LOCKWAIT , "Waiting on an internal lock"}, - {PS_MUTEX_WAIT , "Waiting on a mutex"}, - {PS_COND_WAIT , "Waiting on a condition variable"}, - {PS_SLEEP_WAIT , "Sleeping"}, - {PS_SIGSUSPEND , "Suspended, waiting for a signal"}, - {PS_SIGWAIT , "Waiting for a signal"}, - {PS_JOIN , "Waiting to join"}, - {PS_SUSPENDED , "Suspended"}, - {PS_DEAD , "Dead"}, - {PS_DEADLOCK , "Deadlocked"}, - {PS_STATE_MAX , "Not a real state!"} -}; - -void -_thread_dump_info(void) -{ - char s[512], tempfile[128]; - pthread_t pthread; - int fd, i; - - for (i = 0; i < 100000; i++) { - snprintf(tempfile, sizeof(tempfile), "/tmp/pthread.dump.%u.%i", - getpid(), i); - /* Open the dump file for append and create it if necessary: */ - if ((fd = __sys_open(tempfile, O_RDWR | O_CREAT | O_EXCL, - 0666)) < 0) { - /* Can't open the dump file. */ - if (errno == EEXIST) - continue; - /* - * We only need to continue in case of - * EEXIT error. Most other error - * codes means that we will fail all - * the times. - */ - return; - } else { - break; - } - } - if (i==100000) { - /* all 100000 possibilities are in use :( */ - return; - } else { - /* Dump the active threads. */ - strcpy(s, "\n\n========\nACTIVE THREADS\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Enter a loop to report each thread in the global list: */ - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread->state != PS_DEAD) - dump_thread(fd, pthread, /*long_verson*/ 1); - } - - /* - * Dump the ready threads. - * XXX - We can't easily do this because the run queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nREADY THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - - /* - * Dump the waiting threads. - * XXX - We can't easily do this because the wait queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nWAITING THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Close the dump file. */ - __sys_close(fd); - } -} - -static void -dump_thread(int fd, pthread_t pthread, int long_version) -{ - struct pthread *curthread = _get_curthread(); - char s[512]; - int i; - - /* Find the state: */ - for (i = 0; i < (int)NELEMENTS(thread_info) - 1; i++) - if (thread_info[i].state == pthread->state) - break; - - /* Output a record for the thread: */ - snprintf(s, sizeof(s), - "--------------------\n" - "Thread %p (%s), scope %s, prio %3d, blocked %s, state %s [%s:%d]\n", - pthread, (pthread->name == NULL) ? "" : pthread->name, - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM ? "system" : "process", - pthread->active_priority, (pthread->blocked != 0) ? "yes" : "no", - thread_info[i].name, pthread->fname, pthread->lineno); - __sys_write(fd, s, strlen(s)); - - if (long_version != 0) { - /* Check if this is the running thread: */ - if (pthread == curthread) { - /* Output a record for the running thread: */ - strcpy(s, "This is the running thread\n"); - __sys_write(fd, s, strlen(s)); - } - /* Check if this is the initial thread: */ - if (pthread == _thr_initial) { - /* Output a record for the initial thread: */ - strcpy(s, "This is the initial thread\n"); - __sys_write(fd, s, strlen(s)); - } - - /* Process according to thread state: */ - switch (pthread->state) { - case PS_SIGWAIT: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - - snprintf(s, sizeof(s), "waitset (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->data.sigwait->waitset->__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - /* - * Trap other states that are not explicitly - * coded to dump information: - */ - default: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - } - } -} - -/* Set the thread name for debug: */ -void -_pthread_set_name_np(pthread_t thread, char *name) -{ - struct pthread *curthread = _get_curthread(); - char *new_name; - char *prev_name; - int ret; - - new_name = strdup(name); - /* Add a reference to the target thread. */ - if (_thr_ref_add(curthread, thread, 0) != 0) { - free(new_name); - ret = ESRCH; - } - else { - THR_THREAD_LOCK(curthread, thread); - prev_name = thread->name; - thread->name = new_name; - THR_THREAD_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (prev_name != NULL) { - /* Free space for previous name. */ - free(prev_name); - } - ret = 0; - } -#if 0 - /* XXX - Should return error code. */ - return (ret); -#endif -} diff --git a/lib/libkse/thread/thr_init.c b/lib/libkse/thread/thr_init.c deleted file mode 100644 index 6c41961..0000000 --- a/lib/libkse/thread/thr_init.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* Allocate space for global thread variables here: */ -#define GLOBAL_PTHREAD_PRIVATE - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <machine/reg.h> - -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/event.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <sys/time.h> -#include <sys/ttycom.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <paths.h> -#include <pthread.h> -#include <pthread_np.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#include "libc_private.h" -#include "thr_private.h" - -int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int __pthread_mutex_lock(pthread_mutex_t *); -int __pthread_mutex_trylock(pthread_mutex_t *); -void _thread_init_hack(void); -extern int _thread_state_running; - -static void init_private(void); -static void init_main_thread(struct pthread *thread); - -/* - * All weak references used within libc should be in this table. - * This is so that static libraries will work. - */ -static void *references[] = { - &_accept, - &_bind, - &_close, - &_connect, - &_dup, - &_dup2, - &_execve, - &_fcntl, - &_flock, - &_flockfile, - &_fstat, - &_fstatfs, - &_fsync, - &_funlockfile, - &_getdirentries, - &_getlogin, - &_getpeername, - &_getsockname, - &_getsockopt, - &_ioctl, - &_kevent, - &_listen, - &_nanosleep, - &_open, - &_pthread_getspecific, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_mutex_destroy, - &_pthread_mutex_init, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock, - &_pthread_mutexattr_init, - &_pthread_mutexattr_destroy, - &_pthread_mutexattr_settype, - &_pthread_once, - &_pthread_setspecific, - &_read, - &_readv, - &_recvfrom, - &_recvmsg, - &_select, - &_sendmsg, - &_sendto, - &_setsockopt, - &_sigaction, - &_sigprocmask, - &_sigsuspend, - &_socket, - &_socketpair, - &_thread_init_hack, - &_wait4, - &_write, - &_writev -}; - -/* - * These are needed when linking statically. All references within - * libgcc (and in the future libc) to these routines are weak, but - * if they are not (strongly) referenced by the application or other - * libraries, then the actual functions will not be loaded. - */ -static void *libgcc_references[] = { - &_pthread_once, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_getspecific, - &_pthread_setspecific, - &_pthread_mutex_init, - &_pthread_mutex_destroy, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock -}; - -#define DUAL_ENTRY(entry) \ - (pthread_func_t)entry, (pthread_func_t)entry - -static pthread_func_t jmp_table[][2] = { - {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ - {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ - {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_getinheritsched)}, /* PJT_ATTR_GETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_getschedparam)}, /* PJT_ATTR_GETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_getschedpolicy)}, /* PJT_ATTR_GETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_getscope)}, /* PJT_ATTR_GETSCOPE */ - {DUAL_ENTRY(_pthread_attr_getstackaddr)}, /* PJT_ATTR_GETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_getstacksize)}, /* PJT_ATTR_GETSTACKSIZE */ - {DUAL_ENTRY(_pthread_attr_init)}, /* PJT_ATTR_INIT */ - {DUAL_ENTRY(_pthread_attr_setdetachstate)}, /* PJT_ATTR_SETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_setguardsize)}, /* PJT_ATTR_SETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_setinheritsched)}, /* PJT_ATTR_SETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_setschedparam)}, /* PJT_ATTR_SETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_setschedpolicy)}, /* PJT_ATTR_SETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_setscope)}, /* PJT_ATTR_SETSCOPE */ - {DUAL_ENTRY(_pthread_attr_setstackaddr)}, /* PJT_ATTR_SETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_setstacksize)}, /* PJT_ATTR_SETSTACKSIZE */ - {DUAL_ENTRY(_pthread_cancel)}, /* PJT_CANCEL */ - {DUAL_ENTRY(_pthread_cleanup_pop)}, /* PJT_CLEANUP_POP */ - {DUAL_ENTRY(_pthread_cleanup_push)}, /* PJT_CLEANUP_PUSH */ - {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ - {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ - {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ - {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ - {DUAL_ENTRY(_pthread_cond_timedwait)}, /* PJT_COND_TIMEDWAIT */ - {(pthread_func_t)__pthread_cond_wait, - (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ - {DUAL_ENTRY(_pthread_detach)}, /* PJT_DETACH */ - {DUAL_ENTRY(_pthread_equal)}, /* PJT_EQUAL */ - {DUAL_ENTRY(_pthread_exit)}, /* PJT_EXIT */ - {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ - {DUAL_ENTRY(_pthread_join)}, /* PJT_JOIN */ - {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ - {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ - {DUAL_ENTRY(_pthread_kill)}, /* PJT_KILL */ - {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ - {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ - {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ - {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ - {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ - {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ - {(pthread_func_t)__pthread_mutex_lock, - (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ - {(pthread_func_t)__pthread_mutex_trylock, - (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ - {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ - {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ - {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ - {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ - {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ - {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ - {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ - {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ - {DUAL_ENTRY(_pthread_setcancelstate)}, /* PJT_SETCANCELSTATE */ - {DUAL_ENTRY(_pthread_setcanceltype)}, /* PJT_SETCANCELTYPE */ - {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ - {DUAL_ENTRY(_pthread_sigmask)}, /* PJT_SIGMASK */ - {DUAL_ENTRY(_pthread_testcancel)} /* PJT_TESTCANCEL */ -}; - -static int init_once = 0; - -/* - * Threaded process initialization. - * - * This is only called under two conditions: - * - * 1) Some thread routines have detected that the library hasn't yet - * been initialized (_thr_initial == NULL && curthread == NULL), or - * - * 2) An explicit call to reinitialize after a fork (indicated - * by curthread != NULL) - */ -void -_libpthread_init(struct pthread *curthread) -{ - int fd; - - /* Check if this function has already been called: */ - if ((_thr_initial != NULL) && (curthread == NULL)) - /* Only initialize the threaded application once. */ - return; - - /* - * Make gcc quiescent about {,libgcc_}references not being - * referenced: - */ - if ((references[0] == NULL) || (libgcc_references[0] == NULL)) - PANIC("Failed loading mandatory references in _thread_init"); - - /* Pull debug symbols in for static binary */ - _thread_state_running = PS_RUNNING; - - /* - * Check the size of the jump table to make sure it is preset - * with the correct number of entries. - */ - if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) - PANIC("Thread jump table not properly initialized"); - memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); - - /* - * Check for the special case of this process running as - * or in place of init as pid = 1: - */ - if ((_thr_pid = getpid()) == 1) { - /* - * Setup a new session for this process which is - * assumed to be running as root. - */ - if (setsid() == -1) - PANIC("Can't set session ID"); - if (revoke(_PATH_CONSOLE) != 0) - PANIC("Can't revoke console"); - if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) - PANIC("Can't open console"); - if (setlogin("root") == -1) - PANIC("Can't set login to root"); - if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) - PANIC("Can't set controlling terminal"); - } - - /* Initialize pthread private data. */ - init_private(); - _kse_init(); - - /* Initialize the initial kse and kseg. */ - _kse_initial = _kse_alloc(NULL, _thread_scope_system > 0); - if (_kse_initial == NULL) - PANIC("Can't allocate initial kse."); - _kse_initial->k_kseg = _kseg_alloc(NULL); - if (_kse_initial->k_kseg == NULL) - PANIC("Can't allocate initial kseg."); - _kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - _kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq; - - TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe); - _kse_initial->k_kseg->kg_ksecount = 1; - - /* Set the initial thread. */ - if (curthread == NULL) { - /* Create and initialize the initial thread. */ - curthread = _thr_alloc(NULL); - if (curthread == NULL) - PANIC("Can't allocate initial thread"); - _thr_initial = curthread; - init_main_thread(curthread); - } else { - /* - * The initial thread is the current thread. It is - * assumed that the current thread is already initialized - * because it is left over from a fork(). - */ - _thr_initial = curthread; - } - _kse_initial->k_kseg->kg_threadcount = 0; - _thr_initial->kse = _kse_initial; - _thr_initial->kseg = _kse_initial->k_kseg; - _thr_initial->active = 1; - - /* - * Add the thread to the thread list and to the KSEG's thread - * queue. - */ - THR_LIST_ADD(_thr_initial); - KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial); - - /* Setup the KSE/thread specific data for the current KSE/thread. */ - _thr_initial->kse->k_curthread = _thr_initial; - _kcb_set(_thr_initial->kse->k_kcb); - _tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb); - _thr_initial->kse->k_flags |= KF_INITIALIZED; - - _thr_signal_init(); - _kse_critical_leave(&_thr_initial->tcb->tcb_tmbx); - /* - * activate threaded mode as soon as possible if we are - * being debugged - */ - if (_libkse_debug) - _kse_setthreaded(1); -} - -/* - * This function and pthread_create() do a lot of the same things. - * It'd be nice to consolidate the common stuff in one place. - */ -static void -init_main_thread(struct pthread *thread) -{ - /* Setup the thread attributes. */ - thread->attr = _pthread_attr_default; - thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - /* - * Set up the thread stack. - * - * Create a red zone below the main stack. All other stacks - * are constrained to a maximum size by the parameters - * passed to mmap(), but this stack is only limited by - * resource limits, so this stack needs an explicitly mapped - * red zone to protect the thread stack that is just beyond. - */ - if (mmap((void *)((uintptr_t)_usrstack - _thr_stack_initial - - _thr_guard_default), _thr_guard_default, 0, MAP_ANON, - -1, 0) == MAP_FAILED) - PANIC("Cannot allocate red zone for initial thread"); - - /* - * Mark the stack as an application supplied stack so that it - * isn't deallocated. - * - * XXX - I'm not sure it would hurt anything to deallocate - * the main thread stack because deallocation doesn't - * actually free() it; it just puts it in the free - * stack queue for later reuse. - */ - thread->attr.stackaddr_attr = (void *)((uintptr_t)_usrstack - - _thr_stack_initial); - thread->attr.stacksize_attr = _thr_stack_initial; - thread->attr.guardsize_attr = _thr_guard_default; - thread->attr.flags |= THR_STACK_USER; - - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - thread->magic = THR_MAGIC; - - thread->slice_usec = -1; - thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; - thread->name = strdup("initial thread"); - - /* Initialize the thread for signals: */ - SIGEMPTYSET(thread->sigmask); - - /* - * Set up the thread mailbox. The threads saved context - * is also in the mailbox. - */ - thread->tcb->tcb_tmbx.tm_udata = thread; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - thread->attr.stacksize_attr; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - thread->attr.stackaddr_attr; - - /* Default the priority of the initial thread: */ - thread->base_priority = THR_DEFAULT_PRIORITY; - thread->active_priority = THR_DEFAULT_PRIORITY; - thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&thread->mutexq); - - /* Initialize hooks in the thread structure: */ - thread->specific = NULL; - thread->cleanup = NULL; - thread->flags = 0; - thread->sigbackout = NULL; - thread->continuation = NULL; - - thread->state = PS_RUNNING; - thread->uniqueid = 0; -} - -static void -init_private(void) -{ - struct clockinfo clockinfo; - size_t len; - int mib[2]; - - /* - * Avoid reinitializing some things if they don't need to be, - * e.g. after a fork(). - */ - if (init_once == 0) { - /* Find the stack top */ - mib[0] = CTL_KERN; - mib[1] = KERN_USRSTACK; - len = sizeof (_usrstack); - if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) - PANIC("Cannot get kern.usrstack from sysctl"); - /* Get the kernel clockrate: */ - mib[0] = CTL_KERN; - mib[1] = KERN_CLOCKRATE; - len = sizeof (struct clockinfo); - if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0) - _clock_res_usec = 1000000 / clockinfo.stathz; - else - _clock_res_usec = CLOCK_RES_USEC; - - _thr_page_size = getpagesize(); - _thr_guard_default = _thr_page_size; - if (sizeof(void *) == 8) { - _thr_stack_default = THR_STACK64_DEFAULT; - _thr_stack_initial = THR_STACK64_INITIAL; - } - else { - _thr_stack_default = THR_STACK32_DEFAULT; - _thr_stack_initial = THR_STACK32_INITIAL; - } - _pthread_attr_default.guardsize_attr = _thr_guard_default; - _pthread_attr_default.stacksize_attr = _thr_stack_default; - TAILQ_INIT(&_thr_atfork_list); - init_once = 1; /* Don't do this again. */ - } else { - /* - * Destroy the locks before creating them. We don't - * know what state they are in so it is better to just - * recreate them. - */ - _lock_destroy(&_thread_signal_lock); - _lock_destroy(&_mutex_static_lock); - _lock_destroy(&_rwlock_static_lock); - _lock_destroy(&_keytable_lock); - } - - /* Initialize everything else. */ - TAILQ_INIT(&_thread_list); - TAILQ_INIT(&_thread_gc_list); - _pthread_mutex_init(&_thr_atfork_mutex, NULL); - - /* - * Initialize the lock for temporary installation of signal - * handlers (to support sigwait() semantics) and for the - * process signal mask and pending signal sets. - */ - if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize _thread_signal_lock"); - if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize mutex static init lock"); - if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize rwlock static init lock"); - if (_lock_init(&_keytable_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize thread specific keytable lock"); - _thr_spinlock_init(); - - /* Clear pending signals and get the process signal mask. */ - SIGEMPTYSET(_thr_proc_sigpending); - - /* Are we in M:N mode (default) or 1:1 mode? */ -#ifdef SYSTEM_SCOPE_ONLY - _thread_scope_system = 1; -#else - if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL) - _thread_scope_system = 1; - else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) - _thread_scope_system = -1; -#endif - if (getenv("LIBPTHREAD_DEBUG") != NULL) - _thr_debug_flags |= DBG_INFO_DUMP; - - /* - * _thread_list_lock and _kse_count are initialized - * by _kse_init() - */ -} diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c deleted file mode 100644 index 3a95ed2..0000000 --- a/lib/libkse/thread/thr_join.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_join, pthread_join); - -int -_pthread_join(pthread_t pthread, void **thread_return) -{ - struct pthread *curthread = _get_curthread(); - void *tmp; - kse_critical_t crit; - int ret = 0; - - _thr_cancel_enter(curthread); - - /* Check if the caller has specified an invalid thread: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) { - /* Invalid thread: */ - _thr_cancel_leave(curthread, 1); - return (EINVAL); - } - - /* Check if the caller has specified itself: */ - if (pthread == curthread) { - /* Avoid a deadlock condition: */ - _thr_cancel_leave(curthread, 1); - return (EDEADLK); - } - - /* - * Find the thread in the list of active threads or in the - * list of dead threads: - */ - if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) { - /* Return an error: */ - _thr_cancel_leave(curthread, 1); - return (ESRCH); - } - - THR_SCHED_LOCK(curthread, pthread); - /* Check if this thread has been detached: */ - if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - THR_SCHED_UNLOCK(curthread, pthread); - /* Remove the reference and return an error: */ - _thr_ref_delete(curthread, pthread); - ret = EINVAL; - } else { - /* Lock the target thread while checking its state. */ - if (pthread->state == PS_DEAD) { - /* Return the thread's return value: */ - tmp = pthread->ret; - - /* Detach the thread. */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Unlock the thread. */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Remove the thread from the list of active - * threads and add it to the GC list. - */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - THR_LIST_REMOVE(pthread); - THR_GCLIST_ADD(pthread); - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Remove the reference. */ - _thr_ref_delete(curthread, pthread); - if (thread_return != NULL) - *thread_return = tmp; - } - else if (pthread->joiner != NULL) { - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - /* Multiple joiners are not supported. */ - ret = ENOTSUP; - } - else { - /* Set the running thread to be the joiner: */ - pthread->joiner = curthread; - - /* Keep track of which thread we're joining to: */ - curthread->join_status.thread = pthread; - - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - THR_SCHED_LOCK(curthread, curthread); - while (curthread->join_status.thread == pthread) { - THR_SET_STATE(curthread, PS_JOIN); - THR_SCHED_UNLOCK(curthread, curthread); - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - THR_SCHED_LOCK(curthread, curthread); - } - THR_SCHED_UNLOCK(curthread, curthread); - - if ((curthread->cancelflags & THR_CANCELLING) && - !(curthread->cancelflags & PTHREAD_CANCEL_DISABLE)) { - if (_thr_ref_add(curthread, pthread, 1) == 0) { - THR_SCHED_LOCK(curthread, pthread); - pthread->joiner = NULL; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - } - _pthread_exit(PTHREAD_CANCELED); - } - - /* - * The thread return value and error are set by the - * thread we're joining to when it exits or detaches: - */ - ret = curthread->join_status.error; - if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->join_status.ret; - } - } - _thr_cancel_leave(curthread, 1); - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c deleted file mode 100644 index 6563ca7..0000000 --- a/lib/libkse/thread/thr_kern.c +++ /dev/null @@ -1,2573 +0,0 @@ -/* - * Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (C) 2002 Jonathon Mini <mini@freebsd.org> - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. - * - */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/kse.h> -#include <sys/ptrace.h> -#include <sys/signalvar.h> -#include <sys/queue.h> -#include <machine/atomic.h> -#include <machine/sigframe.h> - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <ucontext.h> -#include <unistd.h> - -#include "atomic_ops.h" -#include "thr_private.h" -#include "libc_private.h" -#ifdef NOTYET -#include "spinlock.h" -#endif - -/* #define DEBUG_THREAD_KERN */ -#ifdef DEBUG_THREAD_KERN -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Define a high water mark for the maximum number of threads that - * will be cached. Once this level is reached, any extra threads - * will be free()'d. - */ -#define MAX_CACHED_THREADS 100 -/* - * Define high water marks for the maximum number of KSEs and KSE groups - * that will be cached. Because we support 1:1 threading, there could have - * same number of KSEs and KSE groups as threads. Once these levels are - * reached, any extra KSE and KSE groups will be free()'d. - */ -#define MAX_CACHED_KSES ((_thread_scope_system <= 0) ? 50 : 100) -#define MAX_CACHED_KSEGS ((_thread_scope_system <= 0) ? 50 : 100) - -#define KSE_SET_MBOX(kse, thrd) \ - (kse)->k_kcb->kcb_kmbx.km_curthread = &(thrd)->tcb->tcb_tmbx - -#define KSE_SET_EXITED(kse) (kse)->k_flags |= KF_EXITED - -/* - * Macros for manipulating the run queues. The priority queue - * routines use the thread's pqe link and also handle the setting - * and clearing of the thread's THR_FLAGS_IN_RUNQ flag. - */ -#define KSE_RUNQ_INSERT_HEAD(kse, thrd) \ - _pq_insert_head(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_INSERT_TAIL(kse, thrd) \ - _pq_insert_tail(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_REMOVE(kse, thrd) \ - _pq_remove(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_FIRST(kse) \ - ((_libkse_debug == 0) ? \ - _pq_first(&(kse)->k_schedq->sq_runq) : \ - _pq_first_debug(&(kse)->k_schedq->sq_runq)) - -#define KSE_RUNQ_THREADS(kse) ((kse)->k_schedq->sq_runq.pq_threads) - -#define THR_NEED_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) != 0 || \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -#define THR_NEED_ASYNC_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) == 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -/* - * We've got to keep track of everything that is allocated, not only - * to have a speedy free list, but also so they can be deallocated - * after a fork(). - */ -static TAILQ_HEAD(, kse) active_kseq; -static TAILQ_HEAD(, kse) free_kseq; -static TAILQ_HEAD(, kse_group) free_kse_groupq; -static TAILQ_HEAD(, kse_group) active_kse_groupq; -static TAILQ_HEAD(, kse_group) gc_ksegq; -static struct lock kse_lock; /* also used for kseg queue */ -static int free_kse_count = 0; -static int free_kseg_count = 0; -static TAILQ_HEAD(, pthread) free_threadq; -static struct lock thread_lock; -static int free_thread_count = 0; -static int inited = 0; -static int active_kse_count = 0; -static int active_kseg_count = 0; -static u_int64_t next_uniqueid = 1; - -LIST_HEAD(thread_hash_head, pthread); -#define THREAD_HASH_QUEUES 127 -static struct thread_hash_head thr_hashtable[THREAD_HASH_QUEUES]; -#define THREAD_HASH(thrd) ((unsigned long)thrd % THREAD_HASH_QUEUES) - -/* Lock for thread tcb constructor/destructor */ -static pthread_mutex_t _tcb_mutex; - -#ifdef DEBUG_THREAD_KERN -static void dump_queues(struct kse *curkse); -#endif -static void kse_check_completed(struct kse *kse); -static void kse_check_waitq(struct kse *kse); -static void kse_fini(struct kse *curkse); -static void kse_reinit(struct kse *kse, int sys_scope); -static void kse_sched_multi(struct kse_mailbox *kmbx); -static void kse_sched_single(struct kse_mailbox *kmbx); -static void kse_switchout_thread(struct kse *kse, struct pthread *thread); -static void kse_wait(struct kse *kse, struct pthread *td_wait, int sigseq); -static void kse_free_unlocked(struct kse *kse); -static void kse_destroy(struct kse *kse); -static void kseg_free_unlocked(struct kse_group *kseg); -static void kseg_init(struct kse_group *kseg); -static void kseg_reinit(struct kse_group *kseg); -static void kseg_destroy(struct kse_group *kseg); -static void kse_waitq_insert(struct pthread *thread); -static void kse_wakeup_multi(struct kse *curkse); -static struct kse_mailbox *kse_wakeup_one(struct pthread *thread); -static void thr_cleanup(struct kse *kse, struct pthread *curthread); -static void thr_link(struct pthread *thread); -static void thr_resume_wrapper(int sig, siginfo_t *, ucontext_t *); -static void thr_resume_check(struct pthread *curthread, ucontext_t *ucp); -static int thr_timedout(struct pthread *thread, struct timespec *curtime); -static void thr_unlink(struct pthread *thread); -static void thr_destroy(struct pthread *curthread, struct pthread *thread); -static void thread_gc(struct pthread *thread); -static void kse_gc(struct pthread *thread); -static void kseg_gc(struct pthread *thread); - -static __inline void -thr_accounting(struct pthread *thread) -{ - if ((thread->slice_usec != -1) && - (thread->slice_usec <= TIMESLICE_USEC) && - (thread->attr.sched_policy != SCHED_FIFO)) { - thread->slice_usec += (thread->tcb->tcb_tmbx.tm_uticks - + thread->tcb->tcb_tmbx.tm_sticks) * _clock_res_usec; - /* Check for time quantum exceeded: */ - if (thread->slice_usec > TIMESLICE_USEC) - thread->slice_usec = -1; - } - thread->tcb->tcb_tmbx.tm_uticks = 0; - thread->tcb->tcb_tmbx.tm_sticks = 0; -} - -/* - * This is called after a fork(). - * No locks need to be taken here since we are guaranteed to be - * single threaded. - * - * XXX - * POSIX says for threaded process, fork() function is used - * only to run new programs, and the effects of calling functions - * that require certain resources between the call to fork() and - * the call to an exec function are undefined. - * - * It is not safe to free memory after fork(), because these data - * structures may be in inconsistent state. - */ -void -_kse_single_thread(struct pthread *curthread) -{ -#ifdef NOTYET - struct kse *kse; - struct kse_group *kseg; - struct pthread *thread; - - _thr_spinlock_init(); - *__malloc_lock = (spinlock_t)_SPINLOCK_INITIALIZER; - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; - - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags &= ~PTHREAD_SCOPE_PROCESS; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* - * Enter a loop to remove and free all threads other than - * the running thread from the active thread list: - */ - while ((thread = TAILQ_FIRST(&_thread_list)) != NULL) { - THR_GCLIST_REMOVE(thread); - /* - * Remove this thread from the list (the current - * thread will be removed but re-added by libpthread - * initialization. - */ - TAILQ_REMOVE(&_thread_list, thread, tle); - /* Make sure this isn't the running thread: */ - if (thread != curthread) { - _thr_stack_free(&thread->attr); - if (thread->specific != NULL) - free(thread->specific); - thr_destroy(curthread, thread); - } - } - - TAILQ_INIT(&curthread->mutexq); /* initialize mutex queue */ - curthread->joiner = NULL; /* no joining threads yet */ - curthread->refcount = 0; - SIGEMPTYSET(curthread->sigpend); /* clear pending signals */ - - /* Don't free thread-specific data as the caller may require it */ - - /* Free the free KSEs: */ - while ((kse = TAILQ_FIRST(&free_kseq)) != NULL) { - TAILQ_REMOVE(&free_kseq, kse, k_qe); - kse_destroy(kse); - } - free_kse_count = 0; - - /* Free the active KSEs: */ - while ((kse = TAILQ_FIRST(&active_kseq)) != NULL) { - TAILQ_REMOVE(&active_kseq, kse, k_qe); - kse_destroy(kse); - } - active_kse_count = 0; - - /* Free the free KSEGs: */ - while ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - free_kseg_count = 0; - - /* Free the active KSEGs: */ - while ((kseg = TAILQ_FIRST(&active_kse_groupq)) != NULL) { - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - active_kseg_count = 0; - - /* Free the free threads. */ - while ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - thr_destroy(curthread, thread); - } - free_thread_count = 0; - - /* Free the to-be-gc'd threads. */ - while ((thread = TAILQ_FIRST(&_thread_gc_list)) != NULL) { - TAILQ_REMOVE(&_thread_gc_list, thread, gcle); - thr_destroy(curthread, thread); - } - TAILQ_INIT(&gc_ksegq); - _gc_count = 0; - - if (inited != 0) { - /* - * Destroy these locks; they'll be recreated to assure they - * are in the unlocked state. - */ - _lock_destroy(&kse_lock); - _lock_destroy(&thread_lock); - _lock_destroy(&_thread_list_lock); - inited = 0; - } - - /* We're no longer part of any lists */ - curthread->tlflags = 0; - - /* - * After a fork, we are still operating on the thread's original - * stack. Don't clear the THR_FLAGS_USER from the thread's - * attribute flags. - */ - - /* Initialize the threads library. */ - curthread->kse = NULL; - curthread->kseg = NULL; - _kse_initial = NULL; - _libpthread_init(curthread); -#else - int i; - - /* Reset the current thread and KSE lock data. */ - for (i = 0; i < curthread->locklevel; i++) { - _lockuser_reinit(&curthread->lockusers[i], (void *)curthread); - } - curthread->locklevel = 0; - for (i = 0; i < curthread->kse->k_locklevel; i++) { - _lockuser_reinit(&curthread->kse->k_lockusers[i], - (void *)curthread->kse); - _LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL); - } - curthread->kse->k_locklevel = 0; - - /* - * Reinitialize the thread and signal locks so that - * sigaction() will work after a fork(). - */ - _lock_reinit(&curthread->lock, LCK_ADAPTIVE, _thr_lock_wait, - _thr_lock_wakeup); - _lock_reinit(&_thread_signal_lock, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup); - - _thr_spinlock_init(); - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* - * After a fork, it is possible that an upcall occurs in - * the parent KSE that fork()'d before the child process - * is fully created and before its vm space is copied. - * During the upcall, the tcb is set to null or to another - * thread, and this is what gets copied in the child process - * when the vm space is cloned sometime after the upcall - * occurs. Note that we shouldn't have to set the kcb, but - * we do it for completeness. - */ - _kcb_set(curthread->kse->k_kcb); - _tcb_set(curthread->kse->k_kcb, curthread->tcb); - - /* After a fork(), there child should have no pending signals. */ - sigemptyset(&curthread->sigpend); - - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; -#endif -} - -/* - * This is used to initialize housekeeping and to initialize the - * KSD for the KSE. - */ -void -_kse_init(void) -{ - if (inited == 0) { - TAILQ_INIT(&active_kseq); - TAILQ_INIT(&active_kse_groupq); - TAILQ_INIT(&free_kseq); - TAILQ_INIT(&free_kse_groupq); - TAILQ_INIT(&free_threadq); - TAILQ_INIT(&gc_ksegq); - if (_lock_init(&kse_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize free KSE queue lock"); - if (_lock_init(&thread_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize free thread queue lock"); - if (_lock_init(&_thread_list_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize thread list lock"); - _pthread_mutex_init(&_tcb_mutex, NULL); - active_kse_count = 0; - active_kseg_count = 0; - _gc_count = 0; - inited = 1; - } -} - -/* - * This is called when the first thread (other than the initial - * thread) is created. - */ -int -_kse_setthreaded(int threaded) -{ - sigset_t sigset; - - if ((threaded != 0) && (__isthreaded == 0)) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - - /* - * Tell the kernel to create a KSE for the initial thread - * and enable upcalls in it. - */ - _kse_initial->k_flags |= KF_STARTED; - - if (_thread_scope_system <= 0) { - _thr_initial->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - _kse_initial->k_kseg->kg_flags &= ~KGF_SINGLE_THREAD; - _kse_initial->k_kcb->kcb_kmbx.km_curthread = NULL; - } - else { - /* - * For bound thread, kernel reads mailbox pointer - * once, we'd set it here before calling kse_create. - */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _kse_initial->k_kcb->kcb_kmbx.km_flags |= KMF_BOUND; - } - - /* - * Locking functions in libc are required when there are - * threads other than the initial thread. - */ - _thr_rtld_init(); - - __isthreaded = 1; - if (kse_create(&_kse_initial->k_kcb->kcb_kmbx, 0) != 0) { - _kse_initial->k_flags &= ~KF_STARTED; - __isthreaded = 0; - PANIC("kse_create() failed\n"); - return (-1); - } - _thr_initial->tcb->tcb_tmbx.tm_lwp = - _kse_initial->k_kcb->kcb_kmbx.km_lwp; - _thread_activated = 1; - -#ifndef SYSTEM_SCOPE_ONLY - if (_thread_scope_system <= 0) { - /* Set current thread to initial thread */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _thr_start_sig_daemon(); - _thr_setmaxconcurrency(); - } - else -#endif - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - } - return (0); -} - -/* - * Lock wait and wakeup handlers for KSE locks. These are only used by - * KSEs, and should never be used by threads. KSE locks include the - * KSE group lock (used for locking the scheduling queue) and the - * kse_lock defined above. - * - * When a KSE lock attempt blocks, the entire KSE blocks allowing another - * KSE to run. For the most part, it doesn't make much sense to try and - * schedule another thread because you need to lock the scheduling queue - * in order to do that. And since the KSE lock is used to lock the scheduling - * queue, you would just end up blocking again. - */ -void -_kse_lock_wait(struct lock *lock __unused, struct lockuser *lu) -{ - struct kse *curkse = (struct kse *)_LCK_GET_PRIVATE(lu); - struct timespec ts; - int saved_flags; - - if (curkse->k_kcb->kcb_kmbx.km_curthread != NULL) - PANIC("kse_lock_wait does not disable upcall.\n"); - /* - * Enter a loop to wait until we get the lock. - */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000; /* 1 sec */ - while (!_LCK_GRANTED(lu)) { - /* - * Yield the kse and wait to be notified when the lock - * is granted. - */ - saved_flags = curkse->k_kcb->kcb_kmbx.km_flags; - curkse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL | - KMF_NOCOMPLETED; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } -} - -void -_kse_lock_wakeup(struct lock *lock, struct lockuser *lu) -{ - struct kse *curkse; - struct kse *kse; - struct kse_mailbox *mbx; - - curkse = _get_curkse(); - kse = (struct kse *)_LCK_GET_PRIVATE(lu); - - if (kse == curkse) - PANIC("KSE trying to wake itself up in lock"); - else { - mbx = &kse->k_kcb->kcb_kmbx; - _lock_grant(lock, lu); - /* - * Notify the owning kse that it has the lock. - * It is safe to pass invalid address to kse_wakeup - * even if the mailbox is not in kernel at all, - * and waking up a wrong kse is also harmless. - */ - kse_wakeup(mbx); - } -} - -/* - * Thread wait and wakeup handlers for thread locks. These are only used - * by threads, never by KSEs. Thread locks include the per-thread lock - * (defined in its structure), and condition variable and mutex locks. - */ -void -_thr_lock_wait(struct lock *lock __unused, struct lockuser *lu) -{ - struct pthread *curthread = (struct pthread *)lu->lu_private; - - do { - THR_LOCK_SWITCH(curthread); - THR_SET_STATE(curthread, PS_LOCKWAIT); - _thr_sched_switch_unlocked(curthread); - } while (!_LCK_GRANTED(lu)); -} - -void -_thr_lock_wakeup(struct lock *lock __unused, struct lockuser *lu) -{ - struct pthread *thread; - struct pthread *curthread; - struct kse_mailbox *kmbx; - - curthread = _get_curthread(); - thread = (struct pthread *)_LCK_GET_PRIVATE(lu); - - THR_SCHED_LOCK(curthread, thread); - _lock_grant(lock, lu); - kmbx = _thr_setrunnable_unlocked(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); -} - -kse_critical_t -_kse_critical_enter(void) -{ - kse_critical_t crit; - - crit = (kse_critical_t)_kcb_critical_enter(); - return (crit); -} - -void -_kse_critical_leave(kse_critical_t crit) -{ - struct pthread *curthread; - - _kcb_critical_leave((struct kse_thr_mailbox *)crit); - if ((crit != NULL) && ((curthread = _get_curthread()) != NULL)) - THR_YIELD_CHECK(curthread); -} - -int -_kse_in_critical(void) -{ - return (_kcb_in_critical()); -} - -void -_thr_critical_enter(struct pthread *thread) -{ - thread->critical_count++; -} - -void -_thr_critical_leave(struct pthread *thread) -{ - thread->critical_count--; - THR_YIELD_CHECK(thread); -} - -void -_thr_sched_switch(struct pthread *curthread) -{ - struct kse *curkse; - - (void)_kse_critical_enter(); - curkse = _get_curkse(); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - _thr_sched_switch_unlocked(curthread); -} - -/* - * XXX - We may need to take the scheduling lock before calling - * this, or perhaps take the lock within here before - * doing anything else. - */ -void -_thr_sched_switch_unlocked(struct pthread *curthread) -{ - struct kse *curkse; - volatile int resume_once = 0; - ucontext_t *uc; - - /* We're in the scheduler, 5 by 5: */ - curkse = curthread->kse; - - curthread->need_switchout = 1; /* The thread yielded on its own. */ - curthread->critical_yield = 0; /* No need to yield anymore. */ - - /* Thread can unlock the scheduler lock. */ - curthread->lock_switch = 1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - kse_sched_single(&curkse->k_kcb->kcb_kmbx); - else { - if (__predict_false(_libkse_debug != 0)) { - /* - * Because debugger saves single step status in thread - * mailbox's tm_dflags, we can safely clear single - * step status here. the single step status will be - * restored by kse_switchin when the thread is - * switched in again. This also lets uts run in full - * speed. - */ - ptrace(PT_CLEARSTEP, curkse->k_kcb->kcb_kmbx.km_lwp, - (caddr_t) 1, 0); - } - - KSE_SET_SWITCH(curkse); - _thread_enter_uts(curthread->tcb, curkse->k_kcb); - } - - /* - * Unlock the scheduling queue and leave the - * critical region. - */ - /* Don't trust this after a switch! */ - curkse = curthread->kse; - - curthread->lock_switch = 0; - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* - * This thread is being resumed; check for cancellations. - */ - if (THR_NEED_ASYNC_CANCEL(curthread) && !THR_IN_CRITICAL(curthread)) { - uc = alloca(sizeof(ucontext_t)); - resume_once = 0; - THR_GETCONTEXT(uc); - if (resume_once == 0) { - resume_once = 1; - curthread->check_pending = 0; - thr_resume_check(curthread, uc); - } - } - THR_ACTIVATE_LAST_LOCK(curthread); -} - -/* - * This is the scheduler for a KSE which runs a scope system thread. - * The multi-thread KSE scheduler should also work for a single threaded - * KSE, but we use a separate scheduler so that it can be fine-tuned - * to be more efficient (and perhaps not need a separate stack for - * the KSE, allowing it to use the thread's stack). - */ - -static void -kse_sched_single(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread; - struct timespec ts; - sigset_t sigmask; - int i, sigseqno, level, first = 0; - - curkse = (struct kse *)kmbx->km_udata; - curthread = curkse->k_curthread; - - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - _tcb_set(curkse->k_kcb, curthread->tcb); - curkse->k_flags |= KF_INITIALIZED; - first = 1; - curthread->active = 1; - - /* Setup kernel signal masks for new thread. */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - /* - * Enter critical region, this is meanless for bound thread, - * It is used to let other code work, those code want mailbox - * to be cleared. - */ - (void)_kse_critical_enter(); - } else { - /* - * Bound thread always has tcb set, this prevent some - * code from blindly setting bound thread tcb to NULL, - * buggy code ? - */ - _tcb_set(curkse->k_kcb, curthread->tcb); - } - - curthread->critical_yield = 0; - curthread->need_switchout = 0; - - /* - * Lock the scheduling queue. - * - * There is no scheduling queue for single threaded KSEs, - * but we need a lock for protection regardless. - */ - if (curthread->lock_switch == 0) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - - /* - * This has to do the job of kse_switchout_thread(), only - * for a single threaded KSE/KSEG. - */ - - switch (curthread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - curthread->continuation = _thr_finish_cancellation; - THR_SET_STATE(curthread, PS_RUNNING); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - level = curthread->locklevel - 1; - if (_LCK_GRANTED(&curthread->lockusers[level])) - THR_SET_STATE(curthread, PS_RUNNING); - break; - - case PS_DEAD: - /* Unlock the scheduling queue and exit the KSE and thread. */ - thr_cleanup(curkse, curthread); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - PANIC("bound thread shouldn't get here\n"); - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(curthread)) { - curthread->join_status.thread = NULL; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SUSPENDED: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_RUNNING: - if ((curthread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(curthread)) { - THR_SET_STATE(curthread, PS_SUSPENDED); - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SIGWAIT: - PANIC("bound thread does not have SIGWAIT state\n"); - - case PS_SLEEP_WAIT: - PANIC("bound thread does not have SLEEP_WAIT state\n"); - - case PS_SIGSUSPEND: - PANIC("bound thread does not have SIGSUSPEND state\n"); - - case PS_DEADLOCK: - /* - * These states don't timeout and don't need - * to be in the waiting queue. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - break; - - default: - PANIC("Unknown state\n"); - break; - } - - while (curthread->state != PS_RUNNING) { - sigseqno = curkse->k_sigseqno; - if (curthread->check_pending != 0) { - /* - * Install pending signals into the frame, possible - * cause mutex or condvar backout. - */ - curthread->check_pending = 0; - SIGFILLSET(sigmask); - - /* - * Lock out kernel signal code when we are processing - * signals, and get a fresh copy of signal mask. - */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) - (void)_thr_sig_add(curthread, i, - &curthread->siginfo[i-1]); - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - /* The above code might make thread runnable */ - if (curthread->state == PS_RUNNING) - break; - } - THR_DEACTIVATE_LAST_LOCK(curthread); - kse_wait(curkse, curthread, sigseqno); - THR_ACTIVATE_LAST_LOCK(curthread); - if (curthread->wakeup_time.tv_sec >= 0) { - KSE_GET_TOD(curkse, &ts); - if (thr_timedout(curthread, &ts)) { - /* Indicate the thread timedout: */ - curthread->timeout = 1; - /* Make the thread runnable. */ - THR_SET_STATE(curthread, PS_RUNNING); - } - } - } - - if (curthread->lock_switch == 0) { - /* Unlock the scheduling queue. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - } - - DBG_MSG("Continuing bound thread %p\n", curthread); - if (first) { - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - pthread_exit(curthread->start_routine(curthread->arg)); - } -} - -#ifdef DEBUG_THREAD_KERN -static void -dump_queues(struct kse *curkse) -{ - struct pthread *thread; - - DBG_MSG("Threads in waiting queue:\n"); - TAILQ_FOREACH(thread, &curkse->k_kseg->kg_schedq.sq_waitq, pqe) { - DBG_MSG(" thread %p, state %d, blocked %d\n", - thread, thread->state, thread->blocked); - } -} -#endif - -/* - * This is the scheduler for a KSE which runs multiple threads. - */ -static void -kse_sched_multi(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread, *td_wait; - int ret; - - curkse = (struct kse *)kmbx->km_udata; - THR_ASSERT(curkse->k_kcb->kcb_kmbx.km_curthread == NULL, - "Mailbox not null in kse_sched_multi"); - - /* Check for first time initialization: */ - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - - /* Set this before grabbing the context. */ - curkse->k_flags |= KF_INITIALIZED; - } - - /* - * No current thread anymore, calling _get_curthread in UTS - * should dump core - */ - _tcb_set(curkse->k_kcb, NULL); - - /* If this is an upcall; take the scheduler lock. */ - if (!KSE_IS_SWITCH(curkse)) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - else - KSE_CLEAR_SWITCH(curkse); - - if (KSE_IS_IDLE(curkse)) { - KSE_CLEAR_IDLE(curkse); - curkse->k_kseg->kg_idle_kses--; - } - - /* - * Now that the scheduler lock is held, get the current - * thread. The KSE's current thread cannot be safely - * examined without the lock because it could have returned - * as completed on another KSE. See kse_check_completed(). - */ - curthread = curkse->k_curthread; - - /* - * If the current thread was completed in another KSE, then - * it will be in the run queue. Don't mark it as being blocked. - */ - if ((curthread != NULL) && - ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) && - (curthread->need_switchout == 0)) { - /* - * Assume the current thread is blocked; when the - * completed threads are checked and if the current - * thread is among the completed, the blocked flag - * will be cleared. - */ - curthread->blocked = 1; - DBG_MSG("Running thread %p is now blocked in kernel.\n", - curthread); - } - - /* Check for any unblocked threads in the kernel. */ - kse_check_completed(curkse); - - /* - * Check for threads that have timed-out. - */ - kse_check_waitq(curkse); - - /* - * Switchout the current thread, if necessary, as the last step - * so that it is inserted into the run queue (if it's runnable) - * _after_ any other threads that were added to it above. - */ - if (curthread == NULL) - ; /* Nothing to do here. */ - else if ((curthread->need_switchout == 0) && DBG_CAN_RUN(curthread) && - (curthread->blocked == 0) && (THR_IN_CRITICAL(curthread))) { - /* - * Resume the thread and tell it to yield when - * it leaves the critical region. - */ - curthread->critical_yield = 1; - curthread->active = 1; - if ((curthread->flags & THR_FLAGS_IN_RUNQ) != 0) - KSE_RUNQ_REMOVE(curkse, curthread); - curkse->k_curthread = curthread; - curthread->kse = curkse; - DBG_MSG("Continuing thread %p in critical region\n", - curthread); - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("Can't resume thread in critical region\n"); - } - else if ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - curthread->tcb->tcb_tmbx.tm_lwp = 0; - kse_switchout_thread(curkse, curthread); - } - curkse->k_curthread = NULL; - -#ifdef DEBUG_THREAD_KERN - dump_queues(curkse); -#endif - - /* Check if there are no threads ready to run: */ - while (((curthread = KSE_RUNQ_FIRST(curkse)) == NULL) && - (curkse->k_kseg->kg_threadcount != 0) && - ((curkse->k_flags & KF_TERMINATED) == 0)) { - /* - * Wait for a thread to become active or until there are - * no more threads. - */ - td_wait = KSE_WAITQ_FIRST(curkse); - kse_wait(curkse, td_wait, 0); - kse_check_completed(curkse); - kse_check_waitq(curkse); - } - - /* Check for no more threads: */ - if ((curkse->k_kseg->kg_threadcount == 0) || - ((curkse->k_flags & KF_TERMINATED) != 0)) { - /* - * Normally this shouldn't return, but it will if there - * are other KSEs running that create new threads that - * are assigned to this KSE[G]. For instance, if a scope - * system thread were to create a scope process thread - * and this kse[g] is the initial kse[g], then that newly - * created thread would be assigned to us (the initial - * kse[g]). - */ - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - kse_fini(curkse); - /* never returns */ - } - - THR_ASSERT(curthread != NULL, - "Return from kse_wait/fini without thread."); - THR_ASSERT(curthread->state != PS_DEAD, - "Trying to resume dead thread!"); - KSE_RUNQ_REMOVE(curkse, curthread); - - /* - * Make the selected thread the current thread. - */ - curkse->k_curthread = curthread; - - /* - * Make sure the current thread's kse points to this kse. - */ - curthread->kse = curkse; - - /* - * Reset the time slice if this thread is running for the first - * time or running again after using its full time slice allocation. - */ - if (curthread->slice_usec == -1) - curthread->slice_usec = 0; - - /* Mark the thread active. */ - curthread->active = 1; - - /* - * The thread's current signal frame will only be NULL if it - * is being resumed after being blocked in the kernel. In - * this case, and if the thread needs to run down pending - * signals or needs a cancellation check, we need to add a - * signal frame to the thread's context. - */ - if (curthread->lock_switch == 0 && curthread->state == PS_RUNNING && - (curthread->check_pending != 0 || - THR_NEED_ASYNC_CANCEL(curthread)) && - !THR_IN_CRITICAL(curthread)) { - curthread->check_pending = 0; - signalcontext(&curthread->tcb->tcb_tmbx.tm_context, 0, - (__sighandler_t *)thr_resume_wrapper); - } - kse_wakeup_multi(curkse); - /* - * Continue the thread at its current frame: - */ - if (curthread->lock_switch != 0) { - /* - * This thread came from a scheduler switch; it will - * unlock the scheduler lock and set the mailbox. - */ - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 0); - } else { - /* This thread won't unlock the scheduler lock. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - } - if (ret != 0) - PANIC("Thread has returned from _thread_switch"); - - /* This point should not be reached. */ - PANIC("Thread has returned from _thread_switch"); -} - -static void -thr_resume_wrapper(int sig __unused, siginfo_t *siginfo __unused, - ucontext_t *ucp) -{ - struct pthread *curthread = _get_curthread(); - struct kse *curkse; - int ret, err_save = errno; - - DBG_MSG(">>> sig wrapper\n"); - if (curthread->lock_switch) - PANIC("thr_resume_wrapper, lock_switch != 0\n"); - thr_resume_check(curthread, ucp); - errno = err_save; - _kse_critical_enter(); - curkse = curthread->kse; - curthread->tcb->tcb_tmbx.tm_context = *ucp; - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("thr_resume_wrapper: thread has returned " - "from _thread_switch"); - /* THR_SETCONTEXT(ucp); */ /* not work, why ? */ -} - -static void -thr_resume_check(struct pthread *curthread, ucontext_t *ucp) -{ - _thr_sig_rundown(curthread, ucp); - - if (THR_NEED_ASYNC_CANCEL(curthread)) - pthread_testcancel(); -} - -/* - * Clean up a thread. This must be called with the thread's KSE - * scheduling lock held. The thread must be a thread from the - * KSE's group. - */ -static void -thr_cleanup(struct kse *curkse, struct pthread *thread) -{ - struct pthread *joiner; - struct kse_mailbox *kmbx = NULL; - int sys_scope; - - thread->active = 0; - thread->need_switchout = 0; - thread->lock_switch = 0; - thread->check_pending = 0; - - if ((joiner = thread->joiner) != NULL) { - /* Joinee scheduler lock held; joiner won't leave. */ - if (joiner->kseg == curkse->k_kseg) { - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - (void)_thr_setrunnable_unlocked(joiner); - } - } else { - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* The joiner may have removed itself and exited. */ - if (_thr_ref_add(thread, joiner, 0) == 0) { - KSE_SCHED_LOCK(curkse, joiner->kseg); - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - kmbx = _thr_setrunnable_unlocked(joiner); - } - KSE_SCHED_UNLOCK(curkse, joiner->kseg); - _thr_ref_delete(thread, joiner); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - } - thread->attr.flags |= PTHREAD_DETACHED; - } - - if (!(sys_scope = (thread->attr.flags & PTHREAD_SCOPE_SYSTEM))) { - /* - * Remove the thread from the KSEG's list of threads. - */ - KSEG_THRQ_REMOVE(thread->kseg, thread); - /* - * Migrate the thread to the main KSE so that this - * KSE and KSEG can be cleaned when their last thread - * exits. - */ - thread->kseg = _kse_initial->k_kseg; - thread->kse = _kse_initial; - } - - /* - * We can't hold the thread list lock while holding the - * scheduler lock. - */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - DBG_MSG("Adding thread %p to GC list\n", thread); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->tlflags |= TLFLAGS_GC_SAFE; - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (sys_scope) { - /* - * System scope thread is single thread group, - * when thread is exited, its kse and ksegrp should - * be recycled as well. - * kse upcall stack belongs to thread, clear it here. - */ - curkse->k_stack.ss_sp = 0; - curkse->k_stack.ss_size = 0; - kse_exit(); - PANIC("kse_exit() failed for system scope thread"); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); -} - -void -_thr_gc(struct pthread *curthread) -{ - thread_gc(curthread); - kse_gc(curthread); - kseg_gc(curthread); -} - -static void -thread_gc(struct pthread *curthread) -{ - struct pthread *td, *td_next; - kse_critical_t crit; - TAILQ_HEAD(, pthread) worklist; - - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - /* Check the threads waiting for GC. */ - for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) { - td_next = TAILQ_NEXT(td, gcle); - if ((td->tlflags & TLFLAGS_GC_SAFE) == 0) - continue; - else if (((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - ((td->kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - /* - * The thread and KSE are operating on the same - * stack. Wait for the KSE to exit before freeing - * the thread's stack as well as everything else. - */ - continue; - } - /* - * Remove the thread from the GC list. If the thread - * isn't yet detached, it will get added back to the - * GC list at a later time. - */ - THR_GCLIST_REMOVE(td); - DBG_MSG("Freeing thread %p stack\n", td); - /* - * We can free the thread stack since it's no longer - * in use. - */ - _thr_stack_free(&td->attr); - if (((td->attr.flags & PTHREAD_DETACHED) != 0) && - (td->refcount == 0)) { - /* - * The thread has detached and is no longer - * referenced. It is safe to remove all - * remnants of the thread. - */ - THR_LIST_REMOVE(td); - TAILQ_INSERT_HEAD(&worklist, td, gcle); - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - while ((td = TAILQ_FIRST(&worklist)) != NULL) { - TAILQ_REMOVE(&worklist, td, gcle); - /* - * XXX we don't free initial thread and its kse - * (if thread is a bound thread), because there might - * have some code referencing initial thread and kse. - */ - if (td == _thr_initial) { - DBG_MSG("Initial thread won't be freed\n"); - continue; - } - - if ((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(td->kse); - kseg_free_unlocked(td->kseg); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - DBG_MSG("Freeing thread %p\n", td); - _thr_free(curthread, td); - } -} - -static void -kse_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse) worklist; - struct kse *kse; - - if (free_kse_count <= MAX_CACHED_KSES) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kse_count > MAX_CACHED_KSES) { - kse = TAILQ_FIRST(&free_kseq); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - TAILQ_INSERT_HEAD(&worklist, kse, k_qe); - free_kse_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kse = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kse, k_qe); - kse_destroy(kse); - } -} - -static void -kseg_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse_group) worklist; - struct kse_group *kseg; - - if (free_kseg_count <= MAX_CACHED_KSEGS) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kseg_count > MAX_CACHED_KSEGS) { - kseg = TAILQ_FIRST(&free_kse_groupq); - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - TAILQ_INSERT_HEAD(&worklist, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kseg = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kseg, kg_qe); - kseg_destroy(kseg); - } -} - -/* - * Only new threads that are running or suspended may be scheduled. - */ -int -_thr_schedule_add(struct pthread *curthread, struct pthread *newthread) -{ - kse_critical_t crit; - int ret; - - /* Add the new thread. */ - thr_link(newthread); - - /* - * If this is the first time creating a thread, make sure - * the mailbox is set for the current thread. - */ - if ((newthread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* We use the thread's stack as the KSE's stack. */ - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_sp = - newthread->attr.stackaddr_attr; - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_size = - newthread->attr.stacksize_attr; - - /* - * No need to lock the scheduling queue since the - * KSE/KSEG pair have not yet been started. - */ - KSEG_THRQ_ADD(newthread->kseg, newthread); - /* this thread never gives up kse */ - newthread->active = 1; - newthread->kse->k_curthread = newthread; - newthread->kse->k_kcb->kcb_kmbx.km_flags = KMF_BOUND; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_single; - newthread->kse->k_kcb->kcb_kmbx.km_quantum = 0; - KSE_SET_MBOX(newthread->kse, newthread); - /* - * This thread needs a new KSE and KSEG. - */ - newthread->kse->k_flags &= ~KF_INITIALIZED; - newthread->kse->k_flags |= KF_STARTED; - /* Fire up! */ - ret = kse_create(&newthread->kse->k_kcb->kcb_kmbx, 1); - if (ret != 0) - ret = errno; - } - else { - /* - * Lock the KSE and add the new thread to its list of - * assigned threads. If the new thread is runnable, also - * add it to the KSE's run queue. - */ - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, newthread->kseg); - KSEG_THRQ_ADD(newthread->kseg, newthread); - if (newthread->state == PS_RUNNING) - THR_RUNQ_INSERT_TAIL(newthread); - if ((newthread->kse->k_flags & KF_STARTED) == 0) { - /* - * This KSE hasn't been started yet. Start it - * outside of holding the lock. - */ - newthread->kse->k_flags |= KF_STARTED; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_multi; - newthread->kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_create(&newthread->kse->k_kcb->kcb_kmbx, 0); - } else if ((newthread->state == PS_RUNNING) && - KSE_IS_IDLE(newthread->kse)) { - /* - * The thread is being scheduled on another KSEG. - */ - kse_wakeup_one(newthread); - } - KSE_SCHED_UNLOCK(curthread->kse, newthread->kseg); - _kse_critical_leave(crit); - ret = 0; - } - if (ret != 0) - thr_unlink(newthread); - - return (ret); -} - -void -kse_waitq_insert(struct pthread *thread) -{ - struct pthread *td; - - if (thread->wakeup_time.tv_sec == -1) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, thread, - pqe); - else { - td = TAILQ_FIRST(&thread->kse->k_schedq->sq_waitq); - while ((td != NULL) && (td->wakeup_time.tv_sec != -1) && - ((td->wakeup_time.tv_sec < thread->wakeup_time.tv_sec) || - ((td->wakeup_time.tv_sec == thread->wakeup_time.tv_sec) && - (td->wakeup_time.tv_nsec <= thread->wakeup_time.tv_nsec)))) - td = TAILQ_NEXT(td, pqe); - if (td == NULL) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, - thread, pqe); - else - TAILQ_INSERT_BEFORE(td, thread, pqe); - } - thread->flags |= THR_FLAGS_IN_WAITQ; -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_completed(struct kse *kse) -{ - struct pthread *thread; - struct kse_thr_mailbox *completed; - int sig; - - if ((completed = kse->k_kcb->kcb_kmbx.km_completed) != NULL) { - kse->k_kcb->kcb_kmbx.km_completed = NULL; - while (completed != NULL) { - thread = completed->tm_udata; - DBG_MSG("Found completed thread %p, name %s\n", - thread, - (thread->name == NULL) ? "none" : thread->name); - thread->blocked = 0; - if (thread != kse->k_curthread) { - thr_accounting(thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else - KSE_RUNQ_INSERT_TAIL(kse, thread); - if ((thread->kse != kse) && - (thread->kse->k_curthread == thread)) { - /* - * Remove this thread from its - * previous KSE so that it (the KSE) - * doesn't think it is still active. - */ - thread->kse->k_curthread = NULL; - thread->active = 0; - } - } - if ((sig = thread->tcb->tcb_tmbx.tm_syncsig.si_signo) - != 0) { - if (SIGISMEMBER(thread->sigmask, sig)) - SIGADDSET(thread->sigpend, sig); - else if (THR_IN_CRITICAL(thread)) - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - else - (void)_thr_sig_add(thread, sig, - &thread->tcb->tcb_tmbx.tm_syncsig); - thread->tcb->tcb_tmbx.tm_syncsig.si_signo = 0; - } - completed = completed->tm_next; - } - } -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_waitq(struct kse *kse) -{ - struct pthread *pthread; - struct timespec ts; - - KSE_GET_TOD(kse, &ts); - - /* - * Wake up threads that have timedout. This has to be - * done before adding the current thread to the run queue - * so that a CPU intensive thread doesn't get preference - * over waiting threads. - */ - while (((pthread = KSE_WAITQ_FIRST(kse)) != NULL) && - thr_timedout(pthread, &ts)) { - /* Remove the thread from the wait queue: */ - KSE_WAITQ_REMOVE(kse, pthread); - DBG_MSG("Found timedout thread %p in waitq\n", pthread); - - /* Indicate the thread timedout: */ - pthread->timeout = 1; - - /* Add the thread to the priority queue: */ - if ((pthread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(pthread, PS_SUSPENDED); - else { - THR_SET_STATE(pthread, PS_RUNNING); - KSE_RUNQ_INSERT_TAIL(kse, pthread); - } - } -} - -static int -thr_timedout(struct pthread *thread, struct timespec *curtime) -{ - if (thread->wakeup_time.tv_sec < 0) - return (0); - else if (thread->wakeup_time.tv_sec > curtime->tv_sec) - return (0); - else if ((thread->wakeup_time.tv_sec == curtime->tv_sec) && - (thread->wakeup_time.tv_nsec > curtime->tv_nsec)) - return (0); - else - return (1); -} - -/* - * This must be called with the scheduling lock held. - * - * Each thread has a time slice, a wakeup time (used when it wants - * to wait for a specified amount of time), a run state, and an - * active flag. - * - * When a thread gets run by the scheduler, the active flag is - * set to non-zero (1). When a thread performs an explicit yield - * or schedules a state change, it enters the scheduler and the - * active flag is cleared. When the active flag is still seen - * set in the scheduler, that means that the thread is blocked in - * the kernel (because it is cleared before entering the scheduler - * in all other instances). - * - * The wakeup time is only set for those states that can timeout. - * It is set to (-1, -1) for all other instances. - * - * The thread's run state, aside from being useful when debugging, - * is used to place the thread in an appropriate queue. There - * are 2 basic queues: - * - * o run queue - queue ordered by priority for all threads - * that are runnable - * o waiting queue - queue sorted by wakeup time for all threads - * that are not otherwise runnable (not blocked - * in kernel, not waiting for locks) - * - * The thread's time slice is used for round-robin scheduling - * (the default scheduling policy). While a SCHED_RR thread - * is runnable it's time slice accumulates. When it reaches - * the time slice interval, it gets reset and added to the end - * of the queue of threads at its priority. When a thread no - * longer becomes runnable (blocks in kernel, waits, etc), its - * time slice is reset. - * - * The job of kse_switchout_thread() is to handle all of the above. - */ -static void -kse_switchout_thread(struct kse *kse, struct pthread *thread) -{ - int level; - int i; - int restart; - siginfo_t siginfo; - - /* - * Place the currently running thread into the - * appropriate queue(s). - */ - DBG_MSG("Switching out thread %p, state %d\n", thread, thread->state); - - THR_DEACTIVATE_LAST_LOCK(thread); - if (thread->blocked != 0) { - thread->active = 0; - thread->need_switchout = 0; - /* This thread must have blocked in the kernel. */ - /* - * Check for pending signals and cancellation for - * this thread to see if we need to interrupt it - * in the kernel. - */ - if (THR_NEED_CANCEL(thread)) { - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); - } else if (thread->check_pending != 0) { - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(thread->sigpend, i) && - !SIGISMEMBER(thread->sigmask, i)) { - restart = _thread_sigact[i - 1].sa_flags & SA_RESTART; - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - break; - } - } - } - } - else { - switch (thread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - thread->continuation = _thr_finish_cancellation; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - level = thread->locklevel - 1; - if (!_LCK_GRANTED(&thread->lockusers[level])) - KSE_WAITQ_INSERT(kse, thread); - else - THR_SET_STATE(thread, PS_RUNNING); - break; - - case PS_SLEEP_WAIT: - case PS_SIGWAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(thread)) { - thread->join_status.thread = NULL; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_SIGSUSPEND: - case PS_SUSPENDED: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_DEAD: - /* - * The scheduler is operating on a different - * stack. It is safe to do garbage collecting - * here. - */ - thr_cleanup(kse, thread); - return; - break; - - case PS_RUNNING: - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(thread)) - THR_SET_STATE(thread, PS_SUSPENDED); - break; - - case PS_DEADLOCK: - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - break; - - default: - PANIC("Unknown state\n"); - break; - } - - thr_accounting(thread); - if (thread->state == PS_RUNNING) { - if (thread->slice_usec == -1) { - /* - * The thread exceeded its time quantum or - * it yielded the CPU; place it at the tail - * of the queue for its priority. - */ - KSE_RUNQ_INSERT_TAIL(kse, thread); - } else { - /* - * The thread hasn't exceeded its interval - * Place it at the head of the queue for its - * priority. - */ - KSE_RUNQ_INSERT_HEAD(kse, thread); - } - } - } - thread->active = 0; - thread->need_switchout = 0; - if (thread->check_pending != 0) { - /* Install pending signals into the frame. */ - thread->check_pending = 0; - KSE_LOCK_ACQUIRE(kse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(thread->sigmask, i)) - continue; - if (SIGISMEMBER(thread->sigpend, i)) - (void)_thr_sig_add(thread, i, - &thread->siginfo[i-1]); - else if (SIGISMEMBER(_thr_proc_sigpending, i) && - _thr_getprocsig_unlocked(i, &siginfo)) { - (void)_thr_sig_add(thread, i, &siginfo); - } - } - KSE_LOCK_RELEASE(kse, &_thread_signal_lock); - } -} - -/* - * This function waits for the smallest timeout value of any waiting - * thread, or until it receives a message from another KSE. - * - * This must be called with the scheduling lock held. - */ -static void -kse_wait(struct kse *kse, struct pthread *td_wait, int sigseqno) -{ - struct timespec ts, ts_sleep; - int saved_flags; - - if ((td_wait == NULL) || (td_wait->wakeup_time.tv_sec < 0)) { - /* Limit sleep to no more than 1 minute. */ - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } else { - KSE_GET_TOD(kse, &ts); - TIMESPEC_SUB(&ts_sleep, &td_wait->wakeup_time, &ts); - if (ts_sleep.tv_sec > 60) { - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } - } - /* Don't sleep for negative times. */ - if ((ts_sleep.tv_sec >= 0) && (ts_sleep.tv_nsec >= 0)) { - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - if ((kse->k_kseg->kg_flags & KGF_SINGLE_THREAD) && - (kse->k_sigseqno != sigseqno)) - ; /* don't sleep */ - else { - saved_flags = kse->k_kcb->kcb_kmbx.km_flags; - kse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL; - kse_release(&ts_sleep); - kse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - if (KSE_IS_IDLE(kse)) { - KSE_CLEAR_IDLE(kse); - kse->k_kseg->kg_idle_kses--; - } - } -} - -/* - * Avoid calling this kse_exit() so as not to confuse it with the - * system call of the same name. - */ -static void -kse_fini(struct kse *kse) -{ - /* struct kse_group *free_kseg = NULL; */ - struct timespec ts; - struct pthread *td; - - /* - * Check to see if this is one of the main kses. - */ - if (kse->k_kseg != _kse_initial->k_kseg) { - PANIC("shouldn't get here"); - /* This is for supporting thread groups. */ -#ifdef NOT_YET - /* Remove this KSE from the KSEG's list of KSEs. */ - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - if (TAILQ_EMPTY(&kse->k_kseg->kg_kseq)) - free_kseg = kse->k_kseg; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - - /* - * Add this KSE to the list of free KSEs along with - * the KSEG if is now orphaned. - */ - KSE_LOCK_ACQUIRE(kse, &kse_lock); - if (free_kseg != NULL) - kseg_free_unlocked(free_kseg); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit()"); -#endif - } else { - /* - * We allow program to kill kse in initial group (by - * lowering the concurrency). - */ - if ((kse != _kse_initial) && - ((kse->k_flags & KF_TERMINATED) != 0)) { - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - /* - * Migrate thread to _kse_initial if its lastest - * kse it ran on is the kse. - */ - td = TAILQ_FIRST(&kse->k_kseg->kg_threadq); - while (td != NULL) { - if (td->kse == kse) - td->kse = _kse_initial; - td = TAILQ_NEXT(td, kle); - } - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - KSE_LOCK_ACQUIRE(kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - /* Make sure there is always at least one is awake */ - KSE_WAKEUP(_kse_initial); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit() failed for initial kseg"); - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - ts.tv_sec = 120; - ts.tv_nsec = 0; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_release(&ts); - /* Never reach */ - } -} - -void -_thr_set_timeout(const struct timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - - /* Reset the timeout flag for the running thread: */ - curthread->timeout = 0; - - /* Check if the thread is to wait forever: */ - if (timeout == NULL) { - /* - * Set the wakeup time to something that can be recognised as - * different to an actual time of day: - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - /* Check if no waiting is required: */ - else if ((timeout->tv_sec == 0) && (timeout->tv_nsec == 0)) { - /* Set the wake up time to 'immediately': */ - curthread->wakeup_time.tv_sec = 0; - curthread->wakeup_time.tv_nsec = 0; - } else { - /* Calculate the time for the current thread to wakeup: */ - KSE_GET_TOD(curthread->kse, &ts); - TIMESPEC_ADD(&curthread->wakeup_time, &ts, timeout); - } -} - -void -_thr_panic_exit(char *file, int line, char *msg) -{ - char buf[256]; - - snprintf(buf, sizeof(buf), "(%s:%d) %s\n", file, line, msg); - __sys_write(2, buf, strlen(buf)); - abort(); -} - -void -_thr_setrunnable(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse_mailbox *kmbx; - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, thread->kseg); - kmbx = _thr_setrunnable_unlocked(thread); - KSE_SCHED_UNLOCK(curthread->kse, thread->kseg); - _kse_critical_leave(crit); - if ((kmbx != NULL) && (__isthreaded != 0)) - kse_wakeup(kmbx); -} - -struct kse_mailbox * -_thr_setrunnable_unlocked(struct pthread *thread) -{ - struct kse_mailbox *kmbx = NULL; - - if ((thread->kseg->kg_flags & KGF_SINGLE_THREAD) != 0) { - /* No silly queues for these threads. */ - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - kmbx = kse_wakeup_one(thread); - } - - } else if (thread->state != PS_RUNNING) { - if ((thread->flags & THR_FLAGS_IN_WAITQ) != 0) - KSE_WAITQ_REMOVE(thread->kse, thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - if ((thread->blocked == 0) && (thread->active == 0) && - (thread->flags & THR_FLAGS_IN_RUNQ) == 0) - THR_RUNQ_INSERT_TAIL(thread); - /* - * XXX - Threads are not yet assigned to specific - * KSEs; they are assigned to the KSEG. So - * the fact that a thread's KSE is waiting - * doesn't necessarily mean that it will be - * the KSE that runs the thread after the - * lock is granted. But we don't know if the - * other KSEs within the same KSEG are also - * in a waiting state or not so we err on the - * side of caution and wakeup the thread's - * last known KSE. We ensure that the - * threads KSE doesn't change while it's - * scheduling lock is held so it is safe to - * reference it (the KSE). If the KSE wakes - * up and doesn't find any more work it will - * again go back to waiting so no harm is - * done. - */ - kmbx = kse_wakeup_one(thread); - } - } - return (kmbx); -} - -static struct kse_mailbox * -kse_wakeup_one(struct pthread *thread) -{ - struct kse *ke; - - if (KSE_IS_IDLE(thread->kse)) { - KSE_CLEAR_IDLE(thread->kse); - thread->kseg->kg_idle_kses--; - return (&thread->kse->k_kcb->kcb_kmbx); - } else { - TAILQ_FOREACH(ke, &thread->kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - return (&ke->k_kcb->kcb_kmbx); - } - } - } - return (NULL); -} - -static void -kse_wakeup_multi(struct kse *curkse) -{ - struct kse *ke; - int tmp; - - if ((tmp = KSE_RUNQ_THREADS(curkse)) && curkse->k_kseg->kg_idle_kses) { - TAILQ_FOREACH(ke, &curkse->k_kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - KSE_WAKEUP(ke); - if (--tmp == 0) - break; - } - } - } -} - -/* - * Allocate a new KSEG. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSEG is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse_group * -_kseg_alloc(struct pthread *curthread) -{ - struct kse_group *kseg = NULL; - kse_critical_t crit; - - if ((curthread != NULL) && (free_kseg_count > 0)) { - /* Use the kse lock for the kseg queue. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - if ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kseg) - kseg_reinit(kseg); - } - - /* - * If requested, attempt to allocate a new KSE group only if the - * KSE allocation was successful and a KSE group wasn't found in - * the free list. - */ - if ((kseg == NULL) && - ((kseg = (struct kse_group *)malloc(sizeof(*kseg))) != NULL)) { - if (_pq_alloc(&kseg->kg_schedq.sq_runq, - THR_MIN_PRIORITY, THR_LAST_PRIORITY) != 0) { - free(kseg); - kseg = NULL; - } else { - kseg_init(kseg); - /* Add the KSEG to the list of active KSEGs. */ - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } else { - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - } - } - } - return (kseg); -} - -static void -kseg_init(struct kse_group *kseg) -{ - kseg_reinit(kseg); - _lock_init(&kseg->kg_lock, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup, calloc); -} - -static void -kseg_reinit(struct kse_group *kseg) -{ - TAILQ_INIT(&kseg->kg_kseq); - TAILQ_INIT(&kseg->kg_threadq); - TAILQ_INIT(&kseg->kg_schedq.sq_waitq); - kseg->kg_threadcount = 0; - kseg->kg_ksecount = 0; - kseg->kg_idle_kses = 0; - kseg->kg_flags = 0; -} - -/* - * This must be called with the kse lock held and when there are - * no more threads that reference it. - */ -static void -kseg_free_unlocked(struct kse_group *kseg) -{ - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - TAILQ_INSERT_HEAD(&free_kse_groupq, kseg, kg_qe); - free_kseg_count++; - active_kseg_count--; -} - -void -_kseg_free(struct kse_group *kseg) -{ - struct kse *curkse; - kse_critical_t crit; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &kse_lock); - kseg_free_unlocked(kseg); - KSE_LOCK_RELEASE(curkse, &kse_lock); - _kse_critical_leave(crit); -} - -static void -kseg_destroy(struct kse_group *kseg) -{ - _lock_destroy(&kseg->kg_lock); - _pq_free(&kseg->kg_schedq.sq_runq); - free(kseg); -} - -/* - * Allocate a new KSE. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSE is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse * -_kse_alloc(struct pthread *curthread, int sys_scope) -{ - struct kse *kse = NULL; - char *stack; - kse_critical_t crit; - int i; - - if ((curthread != NULL) && (free_kse_count > 0)) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - /* Search for a finished KSE. */ - kse = TAILQ_FIRST(&free_kseq); - while ((kse != NULL) && - ((kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - kse = TAILQ_NEXT(kse, k_qe); - } - if (kse != NULL) { - DBG_MSG("found an unused kse.\n"); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - free_kse_count--; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kse != NULL) - kse_reinit(kse, sys_scope); - } - if ((kse == NULL) && - ((kse = (struct kse *)malloc(sizeof(*kse))) != NULL)) { - if (sys_scope != 0) - stack = NULL; - else if ((stack = malloc(KSE_STACKSIZE)) == NULL) { - free(kse); - return (NULL); - } - bzero(kse, sizeof(*kse)); - - /* Initialize KCB without the lock. */ - if ((kse->k_kcb = _kcb_ctor(kse)) == NULL) { - if (stack != NULL) - free(stack); - free(kse); - return (NULL); - } - - /* Initialize the lockusers. */ - for (i = 0; i < MAX_KSE_LOCKLEVEL; i++) { - _lockuser_init(&kse->k_lockusers[i], (void *)kse); - _LCK_SET_PRIVATE2(&kse->k_lockusers[i], NULL); - } - /* _lock_init(kse->k_lock, ...) */ - - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - } - kse->k_flags = 0; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - if (curthread != NULL) { - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - /* - * Create the KSE context. - * Scope system threads (one thread per KSE) are not required - * to have a stack for an unneeded kse upcall. - */ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - kse->k_stack.ss_sp = stack; - kse->k_stack.ss_size = KSE_STACKSIZE; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - } - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - /* - * We need to keep a copy of the stack in case it - * doesn't get used; a KSE running a scope system - * thread will use that thread's stack. - */ - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - } - return (kse); -} - -static void -kse_reinit(struct kse *kse, int sys_scope) -{ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - if (kse->k_stack.ss_sp == NULL) { - /* XXX check allocation failure */ - kse->k_stack.ss_sp = (char *) malloc(KSE_STACKSIZE); - kse->k_stack.ss_size = KSE_STACKSIZE; - } - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - if (kse->k_stack.ss_sp) - free(kse->k_stack.ss_sp); - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - kse->k_kcb->kcb_kmbx.km_quantum = 0; - } - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse->k_curthread = NULL; - kse->k_kseg = 0; - kse->k_schedq = 0; - kse->k_locklevel = 0; - kse->k_flags = 0; - kse->k_error = 0; - kse->k_cpu = 0; - kse->k_sigseqno = 0; -} - -void -kse_free_unlocked(struct kse *kse) -{ - TAILQ_REMOVE(&active_kseq, kse, k_qe); - active_kse_count--; - kse->k_kseg = NULL; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - kse->k_flags = 0; - TAILQ_INSERT_HEAD(&free_kseq, kse, k_qe); - free_kse_count++; -} - -void -_kse_free(struct pthread *curthread, struct kse *kse) -{ - kse_critical_t crit; - - if (curthread == NULL) - kse_free_unlocked(kse); - else { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } -} - -static void -kse_destroy(struct kse *kse) -{ - int i; - - if (kse->k_stack.ss_sp != NULL) - free(kse->k_stack.ss_sp); - _kcb_dtor(kse->k_kcb); - for (i = 0; i < MAX_KSE_LOCKLEVEL; ++i) - _lockuser_destroy(&kse->k_lockusers[i]); - _lock_destroy(&kse->k_lock); - free(kse); -} - -struct pthread * -_thr_alloc(struct pthread *curthread) -{ - kse_critical_t crit; - struct pthread *thread = NULL; - int i; - - if (curthread != NULL) { - if (GC_NEEDED()) - _thr_gc(curthread); - if (free_thread_count > 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - if ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - free_thread_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } - } - if ((thread == NULL) && - ((thread = malloc(sizeof(struct pthread))) != NULL)) { - bzero(thread, sizeof(struct pthread)); - thread->siginfo = calloc(_SIG_MAXSIG, sizeof(siginfo_t)); - if (thread->siginfo == NULL) { - free(thread); - return (NULL); - } - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - thread->tcb = _tcb_ctor(thread, 0 /* not initial tls */); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - thread->tcb = _tcb_ctor(thread, 1 /* initial tls */); - } - if (thread->tcb == NULL) { - free(thread->siginfo); - free(thread); - return (NULL); - } - /* - * Initialize thread locking. - * Lock initializing needs malloc, so don't - * enter critical region before doing this! - */ - if (_lock_init(&thread->lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize thread lock"); - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) { - _lockuser_init(&thread->lockusers[i], (void *)thread); - _LCK_SET_PRIVATE2(&thread->lockusers[i], - (void *)thread); - } - } - return (thread); -} - -void -_thr_free(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - - DBG_MSG("Freeing thread %p\n", thread); - if (thread->name) { - free(thread->name); - thread->name = NULL; - } - if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) { - thr_destroy(curthread, thread); - } else { - /* Add the thread to the free thread list. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - TAILQ_INSERT_TAIL(&free_threadq, thread, tle); - free_thread_count++; - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } -} - -static void -thr_destroy(struct pthread *curthread, struct pthread *thread) -{ - int i; - - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) - _lockuser_destroy(&thread->lockusers[i]); - _lock_destroy(&thread->lock); - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - _tcb_dtor(thread->tcb); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - _tcb_dtor(thread->tcb); - } - free(thread->siginfo); - free(thread); -} - -/* - * Add an active thread: - * - * o Assign the thread a unique id (which GDB uses to track - * threads. - * o Add the thread to the list of all threads and increment - * number of active threads. - */ -static void -thr_link(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * Initialize the unique id (which GDB uses to track - * threads), add the thread to the list of all threads, - * and - */ - thread->uniqueid = next_uniqueid++; - THR_LIST_ADD(thread); - _thread_active_threads++; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -/* - * Remove an active thread. - */ -static void -thr_unlink(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - THR_LIST_REMOVE(thread); - _thread_active_threads--; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -_thr_hash_add(struct pthread *thread) -{ - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_INSERT_HEAD(head, thread, hle); -} - -void -_thr_hash_remove(struct pthread *thread) -{ - LIST_REMOVE(thread, hle); -} - -struct pthread * -_thr_hash_find(struct pthread *thread) -{ - struct pthread *td; - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_FOREACH(td, head, hle) { - if (td == thread) - return (thread); - } - return (NULL); -} - -void -_thr_debug_check_yield(struct pthread *curthread) -{ - /* - * Note that TMDF_SUSPEND is set after process is suspended. - * When we are being debugged, every suspension in process - * will cause all KSEs to schedule an upcall in kernel, unless the - * KSE is in critical region. - * If the function is being called, it means the KSE is no longer - * in critical region, if the TMDF_SUSPEND is set by debugger - * before KSE leaves critical region, we will catch it here, else - * if the flag is changed during testing, it also not a problem, - * because the change only occurs after a process suspension event - * occurs. A suspension event will always cause KSE to schedule an - * upcall, in the case, because we are not in critical region, - * upcall will be scheduled sucessfully, the flag will be checked - * again in kse_sched_multi, we won't back until the flag - * is cleared by debugger, the flag will be cleared in next - * suspension event. - */ - if (!DBG_CAN_RUN(curthread)) { - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) - _thr_sched_switch(curthread); - else - kse_thr_interrupt(&curthread->tcb->tcb_tmbx, - KSE_INTR_DBSUSPEND, 0); - } -} diff --git a/lib/libkse/thread/thr_kill.c b/lib/libkse/thread/thr_kill.c deleted file mode 100644 index e543fea..0000000 --- a/lib/libkse/thread/thr_kill.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <signal.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_kill, pthread_kill); - -int -_pthread_kill(pthread_t pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Check for invalid signal numbers: */ - if (sig < 0 || sig > _SIG_MAXSIG) - /* Invalid signal: */ - ret = EINVAL; - /* - * Ensure the thread is in the list of active threads, and the - * signal is valid (signal 0 specifies error checking only) and - * not being ignored: - */ - else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - if ((sig > 0) && - (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) - _thr_sig_send(pthread, sig); - _thr_ref_delete(curthread, pthread); - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_main_np.c b/lib/libkse/thread/thr_main_np.c deleted file mode 100644 index d3e7a43..0000000 --- a/lib/libkse/thread/thr_main_np.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2001 Alfred Perlstein - * Author: Alfred Perlstein <alfred@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_main_np, pthread_main_np); - -/* - * Provide the equivelant to Solaris thr_main() function - */ -int -_pthread_main_np() -{ - - if (!_thr_initial) - return (-1); - else - return (_pthread_equal(_pthread_self(), _thr_initial) ? 1 : 0); -} diff --git a/lib/libkse/thread/thr_mattr_init.c b/lib/libkse/thread/thr_mattr_init.c deleted file mode 100644 index 50a968c..0000000 --- a/lib/libkse/thread/thr_mattr_init.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_init, pthread_mutexattr_init); - -int -_pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - int ret; - pthread_mutexattr_t pattr; - - if ((pattr = (pthread_mutexattr_t) - malloc(sizeof(struct pthread_mutex_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_mutexattr_default, - sizeof(struct pthread_mutex_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_mattr_kind_np.c b/lib/libkse/thread/thr_mattr_kind_np.c deleted file mode 100644 index 67d338e..0000000 --- a/lib/libkse/thread/thr_mattr_kind_np.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind); -int _pthread_mutexattr_getkind_np(pthread_mutexattr_t attr); - -__weak_reference(_pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np); -__weak_reference(_pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np); -__weak_reference(_pthread_mutexattr_gettype, pthread_mutexattr_gettype); -__weak_reference(_pthread_mutexattr_settype, pthread_mutexattr_settype); - -int -_pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind) -{ - int ret; - if (attr == NULL || *attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = kind; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_getkind_np(pthread_mutexattr_t attr) -{ - int ret; - if (attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - ret = attr->m_type; - } - return(ret); -} - -int -_pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) -{ - int ret; - if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = type; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type) -{ - int ret; - - if (attr == NULL || *attr == NULL || (*attr)->m_type >= - PTHREAD_MUTEX_TYPE_MAX) { - ret = EINVAL; - } else { - *type = (*attr)->m_type; - ret = 0; - } - return ret; -} diff --git a/lib/libkse/thread/thr_mattr_pshared.c b/lib/libkse/thread/thr_mattr_pshared.c deleted file mode 100644 index 12d731c..0000000 --- a/lib/libkse/thread/thr_mattr_pshared.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2005 David Xu <davidxu@freebsd.org> - * 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 unmodified, 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include "namespace.h" -#include <errno.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared); -int _pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); - - -__weak_reference(_pthread_mutexattr_getpshared, pthread_mutexattr_getpshared); -__weak_reference(_pthread_mutexattr_setpshared, pthread_mutexattr_setpshared); - -int -_pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libkse/thread/thr_msync.c b/lib/libkse/thread/thr_msync.c deleted file mode 100644 index 8bb0017..0000000 --- a/lib/libkse/thread/thr_msync.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $ - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/mman.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __msync(void *addr, size_t len, int flags); - -__weak_reference(__msync, msync); - -int -__msync(void *addr, size_t len, int flags) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* - * XXX This is quite pointless unless we know how to get the - * file descriptor associated with the memory, and lock it for - * write. The only real use of this wrapper is to guarantee - * a cancellation point, as per the standard. sigh. - */ - _thr_cancel_enter(curthread); - ret = __sys_msync(addr, len, flags); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_multi_np.c b/lib/libkse/thread/thr_multi_np.c deleted file mode 100644 index 0886540..0000000 --- a/lib/libkse/thread/thr_multi_np.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_multi_np, pthread_multi_np); - -int -_pthread_multi_np() -{ - - /* Return to multi-threaded scheduling mode: */ - /* - * XXX - Do we want to do this? - * __is_threaded = 1; - */ - _pthread_resume_all_np(); - return (0); -} diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c deleted file mode 100644 index 228e650..0000000 --- a/lib/libkse/thread/thr_mutex.c +++ /dev/null @@ -1,1862 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <sys/param.h> -#include <sys/queue.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -#if defined(_PTHREADS_INVARIANTS) -#define MUTEX_INIT_LINK(m) do { \ - (m)->m_qe.tqe_prev = NULL; \ - (m)->m_qe.tqe_next = NULL; \ -} while (0) -#define MUTEX_ASSERT_IS_OWNED(m) do { \ - if ((m)->m_qe.tqe_prev == NULL) \ - PANIC("mutex is not on list"); \ -} while (0) -#define MUTEX_ASSERT_NOT_OWNED(m) do { \ - if (((m)->m_qe.tqe_prev != NULL) || \ - ((m)->m_qe.tqe_next != NULL)) \ - PANIC("mutex is on list"); \ -} while (0) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) do { \ - THR_ASSERT(((thr)->sflags & THR_FLAGS_IN_SYNCQ) == 0, \ - "thread in syncq when it shouldn't be."); \ -} while (0); -#else -#define MUTEX_INIT_LINK(m) -#define MUTEX_ASSERT_IS_OWNED(m) -#define MUTEX_ASSERT_NOT_OWNED(m) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) -#endif - -#define THR_IN_MUTEXQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0) -#define MUTEX_DESTROY(m) do { \ - _lock_destroy(&(m)->m_lock); \ - free(m); \ -} while (0) - - -/* - * Prototypes - */ -static struct kse_mailbox *mutex_handoff(struct pthread *, - struct pthread_mutex *); -static inline int mutex_self_trylock(pthread_mutex_t); -static inline int mutex_self_lock(struct pthread *, pthread_mutex_t); -static int mutex_unlock_common(pthread_mutex_t *, int); -static void mutex_priority_adjust(struct pthread *, pthread_mutex_t); -static void mutex_rescan_owned (struct pthread *, struct pthread *, - struct pthread_mutex *); -static inline pthread_t mutex_queue_deq(pthread_mutex_t); -static inline void mutex_queue_remove(pthread_mutex_t, pthread_t); -static inline void mutex_queue_enq(pthread_mutex_t, pthread_t); -static void mutex_lock_backout(void *arg); - -int __pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr); -int __pthread_mutex_trylock(pthread_mutex_t *mutex); -int __pthread_mutex_lock(pthread_mutex_t *m); -int __pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout); -int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, - void *(calloc_cb)(size_t, size_t)); - - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -/* Single underscore versions provided for libc internal usage: */ -__weak_reference(__pthread_mutex_init, pthread_mutex_init); -__weak_reference(__pthread_mutex_lock, pthread_mutex_lock); -__weak_reference(__pthread_mutex_timedlock, pthread_mutex_timedlock); -__weak_reference(__pthread_mutex_trylock, pthread_mutex_trylock); - -/* No difference between libc and application usage of these: */ -__weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy); -__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock); -__weak_reference(_pthread_mutex_isowned_np, pthread_mutex_isowned_np); - -static int -thr_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr, void *(calloc_cb)(size_t, size_t)) -{ - struct pthread_mutex *pmutex; - enum pthread_mutextype type; - int protocol; - int ceiling; - int flags; - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* Check if default mutex attributes: */ - else if (mutex_attr == NULL || *mutex_attr == NULL) { - /* Default to a (error checking) POSIX mutex: */ - type = PTHREAD_MUTEX_ERRORCHECK; - protocol = PTHREAD_PRIO_NONE; - ceiling = THR_MAX_PRIORITY; - flags = 0; - } - - /* Check mutex type: */ - else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) || - ((*mutex_attr)->m_type >= PTHREAD_MUTEX_TYPE_MAX)) - /* Return an invalid argument error: */ - ret = EINVAL; - - /* Check mutex protocol: */ - else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) || - ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE)) - /* Return an invalid argument error: */ - ret = EINVAL; - - else { - /* Use the requested mutex type and protocol: */ - type = (*mutex_attr)->m_type; - protocol = (*mutex_attr)->m_protocol; - ceiling = (*mutex_attr)->m_ceiling; - flags = (*mutex_attr)->m_flags; - } - - /* Check no errors so far: */ - if (ret == 0) { - if ((pmutex = (pthread_mutex_t) - calloc_cb(1, sizeof(struct pthread_mutex))) == NULL) - ret = ENOMEM; - else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc_cb) != 0) { - free(pmutex); - *mutex = NULL; - ret = ENOMEM; - } else { - /* Set the mutex flags: */ - pmutex->m_flags = flags; - - /* Process according to mutex type: */ - switch (type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - case PTHREAD_MUTEX_ADAPTIVE_NP: - /* Nothing to do here. */ - break; - - /* Single UNIX Spec 2 recursive mutex: */ - case PTHREAD_MUTEX_RECURSIVE: - /* Reset the mutex count: */ - pmutex->m_count = 0; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - if (ret == 0) { - /* Initialise the rest of the mutex: */ - TAILQ_INIT(&pmutex->m_queue); - pmutex->m_flags |= MUTEX_FLAGS_INITED; - pmutex->m_owner = NULL; - pmutex->m_type = type; - pmutex->m_protocol = protocol; - pmutex->m_refcount = 0; - if (protocol == PTHREAD_PRIO_PROTECT) - pmutex->m_prio = ceiling; - else - pmutex->m_prio = -1; - pmutex->m_saved_prio = 0; - MUTEX_INIT_LINK(pmutex); - *mutex = pmutex; - } else { - /* Free the mutex lock structure: */ - MUTEX_DESTROY(pmutex); - *mutex = NULL; - } - } - } - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - - return (thr_mutex_init(mutex, mutex_attr, calloc)); -} - -int -_pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - struct pthread_mutex_attr mattr, *mattrp; - - if ((mutex_attr == NULL) || (*mutex_attr == NULL)) - return (__pthread_mutex_init(mutex, &static_mattr)); - else { - mattr = **mutex_attr; - mattr.m_flags |= MUTEX_FLAGS_PRIVATE; - mattrp = &mattr; - return (__pthread_mutex_init(mutex, &mattrp)); - } -} - -/* This function is used internally by malloc. */ -int -_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, - void *(calloc_cb)(size_t, size_t)) -{ - static const struct pthread_mutex_attr attr = { - .m_type = PTHREAD_MUTEX_NORMAL, - .m_protocol = PTHREAD_PRIO_NONE, - .m_ceiling = 0, - .m_flags = 0 - }; - static const struct pthread_mutex_attr *pattr = &attr; - - return (thr_mutex_init(mutex, (pthread_mutexattr_t *)&pattr, - calloc_cb)); -} - -void -_thr_mutex_reinit(pthread_mutex_t *mutex) -{ - _lock_reinit(&(*mutex)->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup); - TAILQ_INIT(&(*mutex)->m_queue); - (*mutex)->m_owner = NULL; - (*mutex)->m_count = 0; - (*mutex)->m_refcount = 0; - (*mutex)->m_prio = 0; - (*mutex)->m_saved_prio = 0; -} - -int -_pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - pthread_mutex_t m; - int ret = 0; - - if (mutex == NULL || *mutex == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - - /* - * Check to see if this mutex is in use: - */ - if (((*mutex)->m_owner != NULL) || - (!TAILQ_EMPTY(&(*mutex)->m_queue)) || - ((*mutex)->m_refcount != 0)) { - ret = EBUSY; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - } else { - /* - * Save a pointer to the mutex so it can be free'd - * and set the caller's pointer to NULL: - */ - m = *mutex; - *mutex = NULL; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* - * Free the memory allocated for the mutex - * structure: - */ - MUTEX_ASSERT_NOT_OWNED(m); - MUTEX_DESTROY(m); - } - } - - /* Return the completion status: */ - return (ret); -} - -static int -init_static(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = _pthread_mutex_init(mutex, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -init_static_private(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = _pthread_mutex_init(mutex, &static_mattr); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -mutex_trylock_common(struct pthread *curthread, pthread_mutex_t *mutex) -{ - int private; - int ret = 0; - - THR_ASSERT((mutex != NULL) && (*mutex != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - private = (*mutex)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * If the mutex was statically allocated, properly - * initialize the tail queue. - */ - if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*mutex)->m_queue); - MUTEX_INIT_LINK(*mutex); - (*mutex)->m_flags |= MUTEX_FLAGS_INITED; - } - - /* Process according to mutex type: */ - switch ((*mutex)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on the attributes of the - * running thread when there are no waiters. - */ - (*mutex)->m_prio = curthread->active_priority; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*mutex)->m_prio) - ret = EINVAL; - - /* Check if this mutex is not locked: */ - else if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. - */ - curthread->active_priority = (*mutex)->m_prio; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = - (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if (ret == 0 && private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*mutex != NULL) || - ((ret = init_static(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -int -_pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking the mutex private (delete safe): - */ - else if ((*mutex != NULL) || - ((ret = init_static_private(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -static int -mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, - const struct timespec * abstime) -{ - int private; - int ret = 0; - - THR_ASSERT((m != NULL) && (*m != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || - abstime->tv_nsec >= 1000000000)) - return (EINVAL); - - /* Reset the interrupted flag: */ - curthread->interrupted = 0; - curthread->timeout = 0; - curthread->wakeup_time.tv_sec = -1; - - private = (*m)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * Enter a loop waiting to become the mutex owner. We need a - * loop in case the waiting thread is interrupted by a signal - * to execute a signal handler. It is not (currently) possible - * to remain in the waiting queue while running a handler. - * Instead, the thread is interrupted and backed out of the - * waiting queue prior to executing the signal handler. - */ - do { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* - * If the mutex was statically allocated, properly - * initialize the tail queue. - */ - if (((*m)->m_flags & MUTEX_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*m)->m_queue); - (*m)->m_flags |= MUTEX_FLAGS_INITED; - MUTEX_INIT_LINK(*m); - } - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on attributes of the - * running thread when there are no waiters. - * Make sure the thread's scheduling lock is - * held while priorities are adjusted. - */ - (*m)->m_prio = curthread->active_priority; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - if (curthread->active_priority > (*m)->m_prio) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, *m); - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*m)->m_prio) { - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - ret = EINVAL; - } - /* Check if this mutex is not locked: */ - else if ((*m)->m_owner == NULL) { - /* - * Lock the mutex for the running - * thread: - */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. Make sure the thread's - * scheduling lock is held while priorities - * are adjusted. - */ - curthread->active_priority = (*m)->m_prio; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* Clear any previous error: */ - curthread->error = 0; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - - /* - * The threads priority may have changed while - * waiting for the mutex causing a ceiling - * violation. - */ - ret = curthread->error; - curthread->error = 0; - } - break; - - /* Trap invalid mutex types: */ - default: - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - } while (((*m)->m_owner != curthread) && (ret == 0) && - (curthread->interrupted == 0) && (curthread->timeout == 0)); - - if (ret == 0 && (*m)->m_owner != curthread && curthread->timeout) - ret = ETIMEDOUT; - - /* - * Check to see if this thread was interrupted and - * is still in the mutex queue of waiting threads: - */ - if (curthread->interrupted != 0) { - /* Remove this thread from the mutex queue. */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - if (THR_IN_SYNCQ(curthread)) - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Check for asynchronous cancellation. */ - if (curthread->continuation != NULL) - curthread->continuation((void *) curthread); - } - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -__strong_reference(__pthread_mutex_lock, _thr_mutex_lock); - -int -_pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -int -__pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 0)); -} - -__strong_reference(_pthread_mutex_unlock, _thr_mutex_unlock); - -int -_mutex_cv_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 1)); -} - -int -_mutex_cv_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - if ((ret = _pthread_mutex_lock(m)) == 0) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - (*m)->m_refcount--; - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - return (ret); -} - -static inline int -mutex_self_trylock(pthread_mutex_t m) -{ - int ret = 0; - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - case PTHREAD_MUTEX_ADAPTIVE_NP: - ret = EBUSY; - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static inline int -mutex_self_lock(struct pthread *curthread, pthread_mutex_t m) -{ - int ret = 0; - - /* - * Don't allow evil recursive mutexes for private use - * in libc and libpthread. - */ - if (m->m_flags & MUTEX_FLAGS_PRIVATE) - PANIC("Recurse on a private mutex."); - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_ADAPTIVE_NP: - /* - * POSIX specifies that mutexes should return EDEADLK if a - * recursive lock is detected. - */ - ret = EDEADLK; - break; - - case PTHREAD_MUTEX_NORMAL: - /* - * What SS2 define as a 'normal' mutex. Intentionally - * deadlock on attempts to get a lock you already own. - */ - - THR_SCHED_LOCK(curthread, curthread); - THR_SET_STATE(curthread, PS_DEADLOCK); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static int -mutex_unlock_common(pthread_mutex_t *m, int add_reference) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - int ret = 0; - - if (m == NULL || *m == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority ceiling mutex: */ - case PTHREAD_PRIO_PROTECT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if ((ret == 0) && (add_reference != 0)) - /* Increment the reference count: */ - (*m)->m_refcount++; - - /* Leave the critical region if this is a private mutex. */ - if ((ret == 0) && ((*m)->m_flags & MUTEX_FLAGS_PRIVATE)) - THR_CRITICAL_LEAVE(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (ret); -} - - -/* - * This function is called when a change in base priority occurs for - * a thread that is holding or waiting for a priority protection or - * inheritence mutex. A change in a threads base priority can effect - * changes to active priorities of other threads and to the ordering - * of mutex locking by waiting threads. - * - * This must be called without the target thread's scheduling lock held. - */ -void -_mutex_notify_priochange(struct pthread *curthread, struct pthread *pthread, - int propagate_prio) -{ - struct pthread_mutex *m; - - /* Adjust the priorites of any owned priority mutexes: */ - if (pthread->priority_mutex_count > 0) { - /* - * Rescan the mutexes owned by this thread and correct - * their priorities to account for this threads change - * in priority. This has the side effect of changing - * the threads active priority. - * - * Be sure to lock the first mutex in the list of owned - * mutexes. This acts as a barrier against another - * simultaneous call to change the threads priority - * and from the owning thread releasing the mutex. - */ - m = TAILQ_FIRST(&pthread->mutexq); - if (m != NULL) { - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - /* - * Make sure the thread still owns the lock. - */ - if (m == TAILQ_FIRST(&pthread->mutexq)) - mutex_rescan_owned(curthread, pthread, - /* rescan all owned */ NULL); - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - - /* - * If this thread is waiting on a priority inheritence mutex, - * check for priority adjustments. A change in priority can - * also cause a ceiling violation(*) for a thread waiting on - * a priority protection mutex; we don't perform the check here - * as it is done in pthread_mutex_unlock. - * - * (*) It should be noted that a priority change to a thread - * _after_ taking and owning a priority ceiling mutex - * does not affect ownership of that mutex; the ceiling - * priority is only checked before mutex ownership occurs. - */ - if (propagate_prio != 0) { - /* - * Lock the thread's scheduling queue. This is a bit - * convoluted; the "in synchronization queue flag" can - * only be cleared with both the thread's scheduling and - * mutex locks held. The thread's pointer to the wanted - * mutex is guaranteed to be valid during this time. - */ - THR_SCHED_LOCK(curthread, pthread); - - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) == 0) || - ((m = pthread->data.mutex) == NULL)) - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * This thread is currently waiting on a mutex; unlock - * the scheduling queue lock and lock the mutex. We - * can't hold both at the same time because the locking - * order could cause a deadlock. - */ - THR_SCHED_UNLOCK(curthread, pthread); - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Check to make sure this thread is still in the - * same state (the lock above can yield the CPU to - * another thread or the thread may be running on - * another CPU). - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (pthread->data.mutex == m)) { - /* - * Remove and reinsert this thread into - * the list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - if (m->m_protocol == PTHREAD_PRIO_INHERIT) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, m); - } - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } -} - -/* - * Called when a new thread is added to the mutex waiting queue or - * when a threads priority changes that is already in the mutex - * waiting queue. - * - * This must be called with the mutex locked by the current thread. - */ -static void -mutex_priority_adjust(struct pthread *curthread, pthread_mutex_t mutex) -{ - pthread_mutex_t m = mutex; - struct pthread *pthread_next, *pthread = mutex->m_owner; - int done, temp_prio; - - /* - * Calculate the mutex priority as the maximum of the highest - * active priority of any waiting threads and the owning threads - * active priority(*). - * - * (*) Because the owning threads current active priority may - * reflect priority inherited from this mutex (and the mutex - * priority may have changed) we must recalculate the active - * priority based on the threads saved inherited priority - * and its base priority. - */ - pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, pthread->base_priority)); - - /* See if this mutex really needs adjusting: */ - if (temp_prio == m->m_prio) - /* No need to propagate the priority: */ - return; - - /* Set new priority of the mutex: */ - m->m_prio = temp_prio; - - /* - * Don't unlock the mutex passed in as an argument. It is - * expected to be locked and unlocked by the caller. - */ - done = 1; - do { - /* - * Save the threads priority before rescanning the - * owned mutexes: - */ - temp_prio = pthread->active_priority; - - /* - * Fix the priorities for all mutexes held by the owning - * thread since taking this mutex. This also has a - * potential side-effect of changing the threads priority. - * - * At this point the mutex is locked by the current thread. - * The owning thread can't release the mutex until it is - * unlocked, so we should be able to safely walk its list - * of owned mutexes. - */ - mutex_rescan_owned(curthread, pthread, m); - - /* - * If this isn't the first time through the loop, - * the current mutex needs to be unlocked. - */ - if (done == 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Assume we're done unless told otherwise: */ - done = 1; - - /* - * If the thread is currently waiting on a mutex, check - * to see if the threads new priority has affected the - * priority of the mutex. - */ - if ((temp_prio != pthread->active_priority) && - ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - ((m = pthread->data.mutex) != NULL) && - (m->m_protocol == PTHREAD_PRIO_INHERIT)) { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Make sure the thread is still waiting on the - * mutex: - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (m == pthread->data.mutex)) { - /* - * The priority for this thread has changed. - * Remove and reinsert this thread into the - * list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - /* - * Grab the waiting thread with highest - * priority: - */ - pthread_next = TAILQ_FIRST(&m->m_queue); - - /* - * Calculate the mutex priority as the maximum - * of the highest active priority of any - * waiting threads and the owning threads - * active priority. - */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, - m->m_owner->base_priority)); - - if (temp_prio != m->m_prio) { - /* - * The priority needs to be propagated - * to the mutex this thread is waiting - * on and up to the owner of that mutex. - */ - m->m_prio = temp_prio; - pthread = m->m_owner; - - /* We're not done yet: */ - done = 0; - } - } - /* Only release the mutex if we're done: */ - if (done != 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } while (done == 0); -} - -static void -mutex_rescan_owned(struct pthread *curthread, struct pthread *pthread, - struct pthread_mutex *mutex) -{ - struct pthread_mutex *m; - struct pthread *pthread_next; - int active_prio, inherited_prio; - - /* - * Start walking the mutexes the thread has taken since - * taking this mutex. - */ - if (mutex == NULL) { - /* - * A null mutex means start at the beginning of the owned - * mutex list. - */ - m = TAILQ_FIRST(&pthread->mutexq); - - /* There is no inherited priority yet. */ - inherited_prio = 0; - } else { - /* - * The caller wants to start after a specific mutex. It - * is assumed that this mutex is a priority inheritence - * mutex and that its priority has been correctly - * calculated. - */ - m = TAILQ_NEXT(mutex, m_qe); - - /* Start inheriting priority from the specified mutex. */ - inherited_prio = mutex->m_prio; - } - active_prio = MAX(inherited_prio, pthread->base_priority); - - for (; m != NULL; m = TAILQ_NEXT(m, m_qe)) { - /* - * We only want to deal with priority inheritence - * mutexes. This might be optimized by only placing - * priority inheritence mutexes into the owned mutex - * list, but it may prove to be useful having all - * owned mutexes in this list. Consider a thread - * exiting while holding mutexes... - */ - if (m->m_protocol == PTHREAD_PRIO_INHERIT) { - /* - * Fix the owners saved (inherited) priority to - * reflect the priority of the previous mutex. - */ - m->m_saved_prio = inherited_prio; - - if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL) - /* Recalculate the priority of the mutex: */ - m->m_prio = MAX(active_prio, - pthread_next->active_priority); - else - m->m_prio = active_prio; - - /* Recalculate new inherited and active priorities: */ - inherited_prio = m->m_prio; - active_prio = MAX(m->m_prio, pthread->base_priority); - } - } - - /* - * Fix the threads inherited priority and recalculate its - * active priority. - */ - pthread->inherited_priority = inherited_prio; - active_prio = MAX(inherited_prio, pthread->base_priority); - - if (active_prio != pthread->active_priority) { - /* Lock the thread's scheduling queue: */ - THR_SCHED_LOCK(curthread, pthread); - - if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - /* - * This thread is not in a run queue. Just set - * its active priority. - */ - pthread->active_priority = active_prio; - } - else { - /* - * This thread is in a run queue. Remove it from - * the queue before changing its priority: - */ - THR_RUNQ_REMOVE(pthread); - - /* - * POSIX states that if the priority is being - * lowered, the thread must be inserted at the - * head of the queue for its priority if it owns - * any priority protection or inheritence mutexes. - */ - if ((active_prio < pthread->active_priority) && - (pthread->priority_mutex_count > 0)) { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_HEAD(pthread); - } else { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_TAIL(pthread); - } - } - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -void -_mutex_unlock_private(pthread_t pthread) -{ - struct pthread_mutex *m, *m_next; - - for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) { - m_next = TAILQ_NEXT(m, m_qe); - if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0) - _pthread_mutex_unlock(&m); - } -} - -/* - * This is called by the current thread when it wants to back out of a - * mutex_lock in order to run a signal handler. - */ -static void -mutex_lock_backout(void *arg) -{ - struct pthread *curthread = (struct pthread *)arg; - struct pthread_mutex *m; - - if ((curthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - /* - * Any other thread may clear the "in sync queue flag", - * but only the current thread can clear the pointer - * to the mutex. So if the flag is set, we can - * guarantee that the pointer to the mutex is valid. - * The only problem may be if the mutex is destroyed - * out from under us, but that should be considered - * an application bug. - */ - m = curthread->data.mutex; - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - - /* - * Check to make sure this thread doesn't already own - * the mutex. Since mutexes are unlocked with direct - * handoffs, it is possible the previous owner gave it - * to us after we checked the sync queue flag and before - * we locked the mutex structure. - */ - if (m->m_owner == curthread) { - THR_LOCK_RELEASE(curthread, &m->m_lock); - mutex_unlock_common(&m, /* add_reference */ 0); - } else { - /* - * Remove ourselves from the mutex queue and - * clear the pointer to the mutex. We may no - * longer be in the mutex queue, but the removal - * function will DTRT. - */ - mutex_queue_remove(m, curthread); - curthread->data.mutex = NULL; - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - /* No need to call this again. */ - curthread->sigbackout = NULL; -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - * - * In order to properly dequeue a thread from the mutex queue and - * make it runnable without the possibility of errant wakeups, it - * is necessary to lock the thread's scheduling queue while also - * holding the mutex lock. - */ -static struct kse_mailbox * -mutex_handoff(struct pthread *curthread, struct pthread_mutex *mutex) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - - /* Keep dequeueing until we find a valid thread: */ - mutex->m_owner = NULL; - pthread = TAILQ_FIRST(&mutex->m_queue); - while (pthread != NULL) { - /* Take the thread's scheduling lock: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Remove the thread from the mutex queue: */ - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - switch (mutex->m_protocol) { - case PTHREAD_PRIO_NONE: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - break; - - case PTHREAD_PRIO_INHERIT: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Set the priority of the mutex. Since our waiting - * threads are in descending priority order, the - * priority of the mutex becomes the active priority - * of the thread we just dequeued. - */ - mutex->m_prio = pthread->active_priority; - - /* Save the owning threads inherited priority: */ - mutex->m_saved_prio = pthread->inherited_priority; - - /* - * The owning threads inherited priority now becomes - * his active priority (the priority of the mutex). - */ - pthread->inherited_priority = mutex->m_prio; - break; - - case PTHREAD_PRIO_PROTECT: - if (pthread->active_priority > mutex->m_prio) { - /* - * Either the mutex ceiling priority has - * been lowered and/or this threads priority - * has been raised subsequent to the thread - * being queued on the waiting list. - */ - pthread->error = EINVAL; - } - else { - /* - * Assign the new owner and add the mutex - * to the thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, - mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Save the owning threads inherited - * priority: - */ - mutex->m_saved_prio = - pthread->inherited_priority; - - /* - * The owning thread inherits the ceiling - * priority of the mutex and executes at - * that priority: - */ - pthread->inherited_priority = mutex->m_prio; - pthread->active_priority = mutex->m_prio; - - } - break; - } - - /* Make the thread runnable and unlock the scheduling queue: */ - kmbx = _thr_setrunnable_unlocked(pthread); - - /* Add a preemption point. */ - if ((curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - - if (mutex->m_owner == pthread) { - /* We're done; a valid owner was found. */ - if (mutex->m_flags & MUTEX_FLAGS_PRIVATE) - THR_CRITICAL_ENTER(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - break; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* Get the next thread from the waiting queue: */ - pthread = TAILQ_NEXT(pthread, sqe); - } - - if ((pthread == NULL) && (mutex->m_protocol == PTHREAD_PRIO_INHERIT)) - /* This mutex has no priority: */ - mutex->m_prio = 0; - return (kmbx); -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - */ -static inline pthread_t -mutex_queue_deq(struct pthread_mutex *mutex) -{ - pthread_t pthread; - - while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - if (pthread->interrupted == 0) - break; - } - - return (pthread); -} - -/* - * Remove a waiting thread from a mutex queue in descending priority order. - */ -static inline void -mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread) -{ - if ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - } -} - -/* - * Enqueue a waiting thread to a queue in descending priority order. - */ -static inline void -mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread) -{ - pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head); - - THR_ASSERT_NOT_IN_SYNCQ(pthread); - /* - * For the common case of all threads having equal priority, - * we perform a quick check against the priority of the thread - * at the tail of the queue. - */ - if ((tid == NULL) || (pthread->active_priority <= tid->active_priority)) - TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, sqe); - else { - tid = TAILQ_FIRST(&mutex->m_queue); - while (pthread->active_priority <= tid->active_priority) - tid = TAILQ_NEXT(tid, sqe); - TAILQ_INSERT_BEFORE(tid, pthread, sqe); - } - pthread->sflags |= THR_FLAGS_IN_SYNCQ; -} - -int -_pthread_mutex_isowned_np(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - - return ((*mutex)->m_owner == curthread); -} - diff --git a/lib/libkse/thread/thr_mutex_prioceiling.c b/lib/libkse/thread/thr_mutex_prioceiling.c deleted file mode 100644 index 7f1caf3..0000000 --- a/lib/libkse/thread/thr_mutex_prioceiling.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling); -__weak_reference(_pthread_mutexattr_setprioceiling, pthread_mutexattr_setprioceiling); -__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling); -__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling); - -int -_pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - *prioceiling = (*mattr)->m_ceiling; - - return(ret); -} - -int -_pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - (*mattr)->m_ceiling = prioceiling; - - return(ret); -} - -int -_pthread_mutex_getprioceiling(pthread_mutex_t *mutex, - int *prioceiling) -{ - int ret; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else { - *prioceiling = (*mutex)->m_prio; - ret = 0; - } - return (ret); -} - -int -_pthread_mutex_setprioceiling(pthread_mutex_t *mutex, - int prioceiling, int *old_ceiling) -{ - int ret = 0; - int tmp; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - /* Lock the mutex: */ - else if ((ret = _pthread_mutex_lock(mutex)) == 0) { - tmp = (*mutex)->m_prio; - /* Set the new ceiling: */ - (*mutex)->m_prio = prioceiling; - - /* Unlock the mutex: */ - ret = _pthread_mutex_unlock(mutex); - - /* Return the old ceiling: */ - *old_ceiling = tmp; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_mutex_protocol.c b/lib/libkse/thread/thr_mutex_protocol.c deleted file mode 100644 index 6ec2239..0000000 --- a/lib/libkse/thread/thr_mutex_protocol.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_getprotocol, pthread_mutexattr_getprotocol); -__weak_reference(_pthread_mutexattr_setprotocol, pthread_mutexattr_setprotocol); - -int -_pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else - *protocol = (*mattr)->m_protocol; - - return(ret); -} - -int -_pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL) || - (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT)) - ret = EINVAL; - else { - (*mattr)->m_protocol = protocol; - (*mattr)->m_ceiling = THR_MAX_PRIORITY; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_mutexattr_destroy.c b/lib/libkse/thread/thr_mutexattr_destroy.c deleted file mode 100644 index 8e0537e..0000000 --- a/lib/libkse/thread/thr_mutexattr_destroy.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_destroy, pthread_mutexattr_destroy); - -int -_pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_nanosleep.c b/lib/libkse/thread/thr_nanosleep.c deleted file mode 100644 index b8210af..0000000 --- a/lib/libkse/thread/thr_nanosleep.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdio.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining); - -__weak_reference(__nanosleep, nanosleep); - -int -_nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - struct timespec ts, ts1; - struct timespec remaining_time; - struct timespec wakeup_time; - - /* Check if the time to sleep is legal: */ - if ((time_to_sleep == NULL) || (time_to_sleep->tv_sec < 0) || - (time_to_sleep->tv_nsec < 0) || - (time_to_sleep->tv_nsec >= 1000000000)) { - /* Return an EINVAL error : */ - errno = EINVAL; - ret = -1; - } else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_nanosleep(time_to_sleep, time_remaining)); - - KSE_GET_TOD(curthread->kse, &ts); - - /* Calculate the time for the current thread to wake up: */ - TIMESPEC_ADD(&wakeup_time, &ts, time_to_sleep); - - THR_LOCK_SWITCH(curthread); - curthread->interrupted = 0; - curthread->wakeup_time = wakeup_time; - THR_SET_STATE(curthread, PS_SLEEP_WAIT); - - /* Reschedule the current thread to sleep: */ - _thr_sched_switch_unlocked(curthread); - - /* Calculate the remaining time to sleep: */ - KSE_GET_TOD(curthread->kse, &ts1); - remaining_time.tv_sec = time_to_sleep->tv_sec - + ts.tv_sec - ts1.tv_sec; - remaining_time.tv_nsec = time_to_sleep->tv_nsec - + ts.tv_nsec - ts1.tv_nsec; - - /* Check if the nanosecond field has underflowed: */ - if (remaining_time.tv_nsec < 0) { - /* Handle the underflow: */ - remaining_time.tv_sec -= 1; - remaining_time.tv_nsec += 1000000000; - } - /* Check if the nanosecond field has overflowed: */ - else if (remaining_time.tv_nsec >= 1000000000) { - /* Handle the overflow: */ - remaining_time.tv_sec += 1; - remaining_time.tv_nsec -= 1000000000; - } - - /* Check if the sleep was longer than the required time: */ - if (remaining_time.tv_sec < 0) { - /* Reset the time left: */ - remaining_time.tv_sec = 0; - remaining_time.tv_nsec = 0; - } - - /* Check if the time remaining is to be returned: */ - if (time_remaining != NULL) { - /* Return the actual time slept: */ - time_remaining->tv_sec = remaining_time.tv_sec; - time_remaining->tv_nsec = remaining_time.tv_nsec; - } - - /* Check if the sleep was interrupted: */ - if (curthread->interrupted) { - /* Return an EINTR error : */ - errno = EINTR; - ret = -1; - } - } - return (ret); -} - -int -__nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _nanosleep(time_to_sleep, time_remaining); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_once.c b/lib/libkse/thread/thr_once.c deleted file mode 100644 index eae29ac..0000000 --- a/lib/libkse/thread/thr_once.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_once, pthread_once); - -#define ONCE_NEVER_DONE PTHREAD_NEEDS_INIT -#define ONCE_DONE PTHREAD_DONE_INIT -#define ONCE_IN_PROGRESS 0x02 -#define ONCE_MASK 0x03 - -static pthread_mutex_t once_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER; - -/* - * POSIX: - * The pthread_once() function is not a cancellation point. However, - * if init_routine is a cancellation point and is canceled, the effect - * on once_control shall be as if pthread_once() was never called. - */ - -static void -once_cancel_handler(void *arg) -{ - pthread_once_t *once_control = arg; - - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_NEVER_DONE; - _pthread_mutex_unlock(&once_lock); - _pthread_cond_broadcast(&once_cv); -} - -int -_pthread_once(pthread_once_t *once_control, void (*init_routine) (void)) -{ - struct pthread *curthread; - int wakeup = 0; - - if (once_control->state == ONCE_DONE) - return (0); - _pthread_mutex_lock(&once_lock); - while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS) - _pthread_cond_wait(&once_cv, &once_lock); - /* - * If previous thread was canceled, then the state still - * could be ONCE_NEVER_DONE, we need to check it again. - */ - if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) { - once_control->state = ONCE_IN_PROGRESS; - _pthread_mutex_unlock(&once_lock); - curthread = _get_curthread(); - THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control); - init_routine(); - THR_CLEANUP_POP(curthread, 0); - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_DONE; - wakeup = 1; - } - _pthread_mutex_unlock(&once_lock); - if (wakeup) - _pthread_cond_broadcast(&once_cv); - return (0); -} - diff --git a/lib/libkse/thread/thr_open.c b/lib/libkse/thread/thr_open.c deleted file mode 100644 index d60763b..0000000 --- a/lib/libkse/thread/thr_open.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include "namespace.h" -#include <stdarg.h> -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __open(const char *path, int flags,...); - -__weak_reference(__open, open); - -int -__open(const char *path, int flags,...) -{ - struct pthread *curthread = _get_curthread(); - int ret; - int mode = 0; - va_list ap; - - _thr_cancel_enter(curthread); - - /* Check if the file is being created: */ - if (flags & O_CREAT) { - /* Get the creation mode: */ - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } - - ret = __sys_open(path, flags, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libkse/thread/thr_pause.c b/lib/libkse/thread/thr_pause.c deleted file mode 100644 index fda1e2e..0000000 --- a/lib/libkse/thread/thr_pause.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pause(void); - -extern int __pause(void); - -__weak_reference(_pause, pause); - -int -_pause(void) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pause(); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_poll.c b/lib/libkse/thread/thr_poll.c deleted file mode 100644 index 03f11ce..0000000 --- a/lib/libkse/thread/thr_poll.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <poll.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __poll(struct pollfd *fds, unsigned int nfds, int timeout); - -__weak_reference(__poll, poll); - -int -__poll(struct pollfd *fds, unsigned int nfds, int timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_poll(fds, nfds, timeout); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_printf.c b/lib/libkse/thread/thr_printf.c deleted file mode 100644 index 2a4b12b..0000000 --- a/lib/libkse/thread/thr_printf.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org> - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdarg.h> -#include <string.h> -#include <unistd.h> - -#include "thr_private.h" - -static void pchar(int fd, char c); -static void pstr(int fd, const char *s); - -/* - * Write formatted output to stdout, in a thread-safe manner. - * - * Recognises the following conversions: - * %c -> char - * %d -> signed int (base 10) - * %s -> string - * %u -> unsigned int (base 10) - * %x -> unsigned int (base 16) - * %p -> unsigned int (base 16) - */ -void -_thread_printf(int fd, const char *fmt, ...) -{ - static const char digits[16] = "0123456789abcdef"; - va_list ap; - char buf[20]; - char *s; - unsigned long r, u; - int c; - long d; - int islong; - - va_start(ap, fmt); - while ((c = *fmt++)) { - islong = 0; - if (c == '%') { -next: c = *fmt++; - if (c == '\0') - goto out; - switch (c) { - case 'c': - pchar(fd, va_arg(ap, int)); - continue; - case 's': - pstr(fd, va_arg(ap, char *)); - continue; - case 'l': - islong = 1; - goto next; - case 'p': - islong = 1; - case 'd': - case 'u': - case 'x': - r = ((c == 'u') || (c == 'd')) ? 10 : 16; - if (c == 'd') { - if (islong) - d = va_arg(ap, unsigned long); - else - d = va_arg(ap, unsigned); - if (d < 0) { - pchar(fd, '-'); - u = (unsigned long)(d * -1); - } else - u = (unsigned long)d; - } else { - if (islong) - u = va_arg(ap, unsigned long); - else - u = va_arg(ap, unsigned); - } - s = buf; - do { - *s++ = digits[u % r]; - } while (u /= r); - while (--s >= buf) - pchar(fd, *s); - continue; - } - } - pchar(fd, c); - } -out: - va_end(ap); -} - -/* - * Write a single character to stdout, in a thread-safe manner. - */ -static void -pchar(int fd, char c) -{ - - __sys_write(fd, &c, 1); -} - -/* - * Write a string to stdout, in a thread-safe manner. - */ -static void -pstr(int fd, const char *s) -{ - - __sys_write(fd, s, strlen(s)); -} - diff --git a/lib/libkse/thread/thr_priority_queue.c b/lib/libkse/thread/thr_priority_queue.c deleted file mode 100644 index e7d6f57..0000000 --- a/lib/libkse/thread/thr_priority_queue.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <sys/queue.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Prototypes: */ -static void pq_insert_prio_list(pq_queue_t *pq, int prio); - -#if defined(_PTHREADS_INVARIANTS) - -#define PQ_IN_SCHEDQ (THR_FLAGS_IN_RUNQ | THR_FLAGS_IN_WAITQ) - -#define PQ_SET_ACTIVE(pq) (pq)->pq_flags |= PQF_ACTIVE -#define PQ_CLEAR_ACTIVE(pq) (pq)->pq_flags &= ~PQF_ACTIVE -#define PQ_ASSERT_ACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_INACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) != 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_RUNQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \ - if (((thrd)->flags & PQ_IN_SCHEDQ) != 0) \ - PANIC(msg); \ -} while (0) - -#else - -#define PQ_SET_ACTIVE(pq) -#define PQ_CLEAR_ACTIVE(pq) -#define PQ_ASSERT_ACTIVE(pq, msg) -#define PQ_ASSERT_INACTIVE(pq, msg) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) - -#endif - -int -_pq_alloc(pq_queue_t *pq, int minprio, int maxprio) -{ - int ret = 0; - int prioslots = maxprio - minprio + 1; - - if (pq == NULL) - ret = -1; - - /* Create the priority queue with (maxprio - minprio + 1) slots: */ - else if ((pq->pq_lists = - (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL) - ret = -1; - - else { - /* Remember the queue size: */ - pq->pq_size = prioslots; - ret = _pq_init(pq); - } - return (ret); -} - -void -_pq_free(pq_queue_t *pq) -{ - if ((pq != NULL) && (pq->pq_lists != NULL)) - free(pq->pq_lists); -} - -int -_pq_init(pq_queue_t *pq) -{ - int i, ret = 0; - - if ((pq == NULL) || (pq->pq_lists == NULL)) - ret = -1; - - else { - /* Initialize the queue for each priority slot: */ - for (i = 0; i < pq->pq_size; i++) { - TAILQ_INIT(&pq->pq_lists[i].pl_head); - pq->pq_lists[i].pl_prio = i; - pq->pq_lists[i].pl_queued = 0; - } - /* Initialize the priority queue: */ - TAILQ_INIT(&pq->pq_queue); - pq->pq_flags = 0; - pq->pq_threads = 0; - } - return (ret); -} - -void -_pq_remove(pq_queue_t *pq, pthread_t pthread) -{ - int prio = pthread->active_priority; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_remove: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_IN_RUNQ(pthread, "_pq_remove: Not in priority queue"); - - /* - * Remove this thread from priority list. Note that if - * the priority list becomes empty, it is not removed - * from the priority queue because another thread may be - * added to the priority list (resulting in a needless - * removal/insertion). Priority lists are only removed - * from the priority queue when _pq_first is called. - */ - TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe); - pq->pq_threads--; - /* This thread is now longer in the priority queue. */ - pthread->flags &= ~THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_head(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_head: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_head: Already in priority queue"); - - prio = pthread->active_priority; - TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe); - if (pq->pq_lists[prio].pl_queued == 0) - /* Insert the list into the priority queue: */ - pq_insert_prio_list(pq, prio); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_tail(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_tail: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_tail: Already in priority queue"); - - prio = pthread->active_priority; - TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe); - if (pq->pq_lists[prio].pl_queued == 0) - /* Insert the list into the priority queue: */ - pq_insert_prio_list(pq, prio); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -pthread_t -_pq_first(pq_queue_t *pq) -{ - pq_list_t *pql; - pthread_t pthread = NULL; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) && - (pthread == NULL)) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -/* - * Select a thread which is allowed to run by debugger, we probably - * should merge the function into _pq_first if that function is only - * used by scheduler to select a thread. - */ -pthread_t -_pq_first_debug(pq_queue_t *pq) -{ - pq_list_t *pql, *pqlnext = NULL; - pthread_t pthread = NULL; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - for (pql = TAILQ_FIRST(&pq->pq_queue); - pql != NULL && pthread == NULL; pql = pqlnext) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - pqlnext = TAILQ_NEXT(pql, pl_link); - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } else { - /* - * note there may be a suspension event during this - * test, If TMDF_SUSPEND is set after we tested it, - * we will run the thread, this seems be a problem, - * fortunatly, when we are being debugged, all context - * switch will be done by kse_switchin, that is a - * syscall, kse_switchin will check the flag again, - * the thread will be returned via upcall, so next - * time, UTS won't run the thread. - */ - while (pthread != NULL && !DBG_CAN_RUN(pthread)) { - pthread = TAILQ_NEXT(pthread, pqe); - } - if (pthread == NULL) - pqlnext = TAILQ_NEXT(pql, pl_link); - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -static void -pq_insert_prio_list(pq_queue_t *pq, int prio) -{ - pq_list_t *pql; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_ACTIVE(pq, "pq_insert_prio_list: pq_active"); - - /* - * The priority queue is in descending priority order. Start at - * the beginning of the queue and find the list before which the - * new list should be inserted. - */ - pql = TAILQ_FIRST(&pq->pq_queue); - while ((pql != NULL) && (pql->pl_prio > prio)) - pql = TAILQ_NEXT(pql, pl_link); - - /* Insert the list: */ - if (pql == NULL) - TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link); - else - TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link); - - /* Mark this list as being in the queue: */ - pq->pq_lists[prio].pl_queued = 1; -} diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h deleted file mode 100644 index 46f6e80..0000000 --- a/lib/libkse/thread/thr_private.h +++ /dev/null @@ -1,1294 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. - * - * Private thread definitions for the uthread kernel. - * - * $FreeBSD$ - */ - -#ifndef _THR_PRIVATE_H -#define _THR_PRIVATE_H - -/* - * Include files. - */ -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <sys/queue.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/cdefs.h> -#include <sys/kse.h> -#include <sched.h> -#include <ucontext.h> -#include <unistd.h> -#include <pthread.h> -#include <pthread_np.h> - -#ifndef LIBTHREAD_DB -#include "lock.h" -#include "pthread_md.h" -#endif - - -/* - * Evaluate the storage class specifier. - */ -#ifdef GLOBAL_PTHREAD_PRIVATE -#define SCLASS -#define SCLASS_PRESET(x...) = x -#else -#define SCLASS extern -#define SCLASS_PRESET(x...) -#endif - -/* - * Kernel fatal error handler macro. - */ -#define PANIC(string) _thr_exit(__FILE__, __LINE__, string) - - -/* Output debug messages like this: */ -#ifdef STDOUT_FILENO -#define stdout_debug(...) _thread_printf(STDOUT_FILENO, __VA_ARGS__) -#endif -#ifdef STDERR_FILENO -#define stderr_debug(...) _thread_printf(STDERR_FILENO, __VA_ARGS__) -#endif - -#define DBG_MUTEX 0x0001 -#define DBG_SIG 0x0002 -#define DBG_INFO_DUMP 0x0004 - -#ifdef _PTHREADS_INVARIANTS -#define THR_ASSERT(cond, msg) do { \ - if (!(cond)) \ - PANIC(msg); \ -} while (0) -#else -#define THR_ASSERT(cond, msg) -#endif - -/* - * State change macro without scheduling queue change: - */ -#define THR_SET_STATE(thrd, newstate) do { \ - (thrd)->state = newstate; \ - (thrd)->fname = __FILE__; \ - (thrd)->lineno = __LINE__; \ -} while (0) - - -#define TIMESPEC_ADD(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec + (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \ - if ((dst)->tv_nsec >= 1000000000) { \ - (dst)->tv_sec++; \ - (dst)->tv_nsec -= 1000000000; \ - } \ - } while (0) - -#define TIMESPEC_SUB(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec - (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \ - if ((dst)->tv_nsec < 0) { \ - (dst)->tv_sec--; \ - (dst)->tv_nsec += 1000000000; \ - } \ - } while (0) - -/* - * Priority queues. - * - * XXX It'd be nice if these were contained in uthread_priority_queue.[ch]. - */ -typedef struct pq_list { - TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */ - TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */ - int pl_prio; /* the priority of this list */ - int pl_queued; /* is this in the priority queue */ -} pq_list_t; - -typedef struct pq_queue { - TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */ - pq_list_t *pq_lists; /* array of all priority lists */ - int pq_size; /* number of priority lists */ -#define PQF_ACTIVE 0x0001 - int pq_flags; - int pq_threads; -} pq_queue_t; - -/* - * Each KSEG has a scheduling queue. For now, threads that exist in their - * own KSEG (system scope) will get a full priority queue. In the future - * this can be optimized for the single thread per KSEG case. - */ -struct sched_queue { - pq_queue_t sq_runq; - TAILQ_HEAD(, pthread) sq_waitq; /* waiting in userland */ -}; - -typedef struct kse_thr_mailbox *kse_critical_t; - -struct kse_group; - -#define MAX_KSE_LOCKLEVEL 5 -struct kse { - /* -- location and order specific items for gdb -- */ - struct kcb *k_kcb; - struct pthread *k_curthread; /* current thread */ - struct kse_group *k_kseg; /* parent KSEG */ - struct sched_queue *k_schedq; /* scheduling queue */ - /* -- end of location and order specific items -- */ - TAILQ_ENTRY(kse) k_qe; /* KSE list link entry */ - TAILQ_ENTRY(kse) k_kgqe; /* KSEG's KSE list entry */ - /* - * Items that are only modified by the kse, or that otherwise - * don't need to be locked when accessed - */ - struct lock k_lock; - struct lockuser k_lockusers[MAX_KSE_LOCKLEVEL]; - int k_locklevel; - stack_t k_stack; - int k_flags; -#define KF_STARTED 0x0001 /* kernel kse created */ -#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */ -#define KF_TERMINATED 0x0004 /* kse is terminated */ -#define KF_IDLE 0x0008 /* kse is idle */ -#define KF_SWITCH 0x0010 /* thread switch in UTS */ - int k_error; /* syscall errno in critical */ - int k_cpu; /* CPU ID when bound */ - int k_sigseqno; /* signal buffered count */ -}; - -#define KSE_SET_IDLE(kse) ((kse)->k_flags |= KF_IDLE) -#define KSE_CLEAR_IDLE(kse) ((kse)->k_flags &= ~KF_IDLE) -#define KSE_IS_IDLE(kse) (((kse)->k_flags & KF_IDLE) != 0) -#define KSE_SET_SWITCH(kse) ((kse)->k_flags |= KF_SWITCH) -#define KSE_CLEAR_SWITCH(kse) ((kse)->k_flags &= ~KF_SWITCH) -#define KSE_IS_SWITCH(kse) (((kse)->k_flags & KF_SWITCH) != 0) - -/* - * Each KSE group contains one or more KSEs in which threads can run. - * At least for now, there is one scheduling queue per KSE group; KSEs - * within the same KSE group compete for threads from the same scheduling - * queue. A scope system thread has one KSE in one KSE group; the group - * does not use its scheduling queue. - */ -struct kse_group { - TAILQ_HEAD(, kse) kg_kseq; /* list of KSEs in group */ - TAILQ_HEAD(, pthread) kg_threadq; /* list of threads in group */ - TAILQ_ENTRY(kse_group) kg_qe; /* link entry */ - struct sched_queue kg_schedq; /* scheduling queue */ - struct lock kg_lock; - int kg_threadcount; /* # of assigned threads */ - int kg_ksecount; /* # of assigned KSEs */ - int kg_idle_kses; - int kg_flags; -#define KGF_SINGLE_THREAD 0x0001 /* scope system kse group */ -#define KGF_SCHEDQ_INITED 0x0002 /* has an initialized schedq */ -}; - -/* - * Add/remove threads from a KSE's scheduling queue. - * For now the scheduling queue is hung off the KSEG. - */ -#define KSEG_THRQ_ADD(kseg, thr) \ -do { \ - TAILQ_INSERT_TAIL(&(kseg)->kg_threadq, thr, kle);\ - (kseg)->kg_threadcount++; \ -} while (0) - -#define KSEG_THRQ_REMOVE(kseg, thr) \ -do { \ - TAILQ_REMOVE(&(kseg)->kg_threadq, thr, kle); \ - (kseg)->kg_threadcount--; \ -} while (0) - - -/* - * Lock acquire and release for KSEs. - */ -#define KSE_LOCK_ACQUIRE(kse, lck) \ -do { \ - if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) { \ - (kse)->k_locklevel++; \ - _lock_acquire((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0); \ - } \ - else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define KSE_LOCK_RELEASE(kse, lck) \ -do { \ - if ((kse)->k_locklevel > 0) { \ - _lock_release((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1]); \ - (kse)->k_locklevel--; \ - } \ -} while (0) - -/* - * Lock our own KSEG. - */ -#define KSE_LOCK(curkse) \ - KSE_LOCK_ACQUIRE(curkse, &(curkse)->k_kseg->kg_lock) -#define KSE_UNLOCK(curkse) \ - KSE_LOCK_RELEASE(curkse, &(curkse)->k_kseg->kg_lock) - -/* - * Lock a potentially different KSEG. - */ -#define KSE_SCHED_LOCK(curkse, kseg) \ - KSE_LOCK_ACQUIRE(curkse, &(kseg)->kg_lock) -#define KSE_SCHED_UNLOCK(curkse, kseg) \ - KSE_LOCK_RELEASE(curkse, &(kseg)->kg_lock) - -/* - * Waiting queue manipulation macros (using pqe link): - */ -#define KSE_WAITQ_REMOVE(kse, thrd) \ -do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) != 0) { \ - TAILQ_REMOVE(&(kse)->k_schedq->sq_waitq, thrd, pqe); \ - (thrd)->flags &= ~THR_FLAGS_IN_WAITQ; \ - } \ -} while (0) -#define KSE_WAITQ_INSERT(kse, thrd) kse_waitq_insert(thrd) -#define KSE_WAITQ_FIRST(kse) TAILQ_FIRST(&(kse)->k_schedq->sq_waitq) - -#define KSE_WAKEUP(kse) kse_wakeup(&(kse)->k_kcb->kcb_kmbx) - -/* - * TailQ initialization values. - */ -#define TAILQ_INITIALIZER { NULL, NULL } - -/* - * lock initialization values. - */ -#define LCK_INITIALIZER { NULL, NULL, LCK_DEFAULT } - -struct pthread_mutex { - /* - * Lock for accesses to this structure. - */ - struct lock m_lock; - enum pthread_mutextype m_type; - int m_protocol; - TAILQ_HEAD(mutex_head, pthread) m_queue; - struct pthread *m_owner; - long m_flags; - int m_count; - int m_refcount; - - /* - * Used for priority inheritence and protection. - * - * m_prio - For priority inheritence, the highest active - * priority (threads locking the mutex inherit - * this priority). For priority protection, the - * ceiling priority of this mutex. - * m_saved_prio - mutex owners inherited priority before - * taking the mutex, restored when the owner - * unlocks the mutex. - */ - int m_prio; - int m_saved_prio; - - /* - * Link for list of all mutexes a thread currently owns. - */ - TAILQ_ENTRY(pthread_mutex) m_qe; -}; - -/* - * Flags for mutexes. - */ -#define MUTEX_FLAGS_PRIVATE 0x01 -#define MUTEX_FLAGS_INITED 0x02 -#define MUTEX_FLAGS_BUSY 0x04 - -/* - * Static mutex initialization values. - */ -#define PTHREAD_MUTEX_STATIC_INITIALIZER \ - { LCK_INITIALIZER, PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, \ - TAILQ_INITIALIZER, NULL, MUTEX_FLAGS_PRIVATE, 0, 0, 0, 0, \ - TAILQ_INITIALIZER } - -struct pthread_mutex_attr { - enum pthread_mutextype m_type; - int m_protocol; - int m_ceiling; - long m_flags; -}; - -#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ - { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } - -/* - * Condition variable definitions. - */ -enum pthread_cond_type { - COND_TYPE_FAST, - COND_TYPE_MAX -}; - -struct pthread_cond { - /* - * Lock for accesses to this structure. - */ - struct lock c_lock; - enum pthread_cond_type c_type; - TAILQ_HEAD(cond_head, pthread) c_queue; - struct pthread_mutex *c_mutex; - long c_flags; - long c_seqno; -}; - -struct pthread_cond_attr { - enum pthread_cond_type c_type; - long c_flags; -}; - -struct pthread_barrier { - pthread_mutex_t b_lock; - pthread_cond_t b_cond; - int b_count; - int b_waiters; - int b_generation; -}; - -struct pthread_barrierattr { - int pshared; -}; - -struct pthread_spinlock { - volatile int s_lock; - pthread_t s_owner; -}; - -/* - * Flags for condition variables. - */ -#define COND_FLAGS_PRIVATE 0x01 -#define COND_FLAGS_INITED 0x02 -#define COND_FLAGS_BUSY 0x04 - -/* - * Static cond initialization values. - */ -#define PTHREAD_COND_STATIC_INITIALIZER \ - { LCK_INITIALIZER, COND_TYPE_FAST, TAILQ_INITIALIZER, \ - NULL, NULL, 0, 0 } - -/* - * Cleanup definitions. - */ -struct pthread_cleanup { - struct pthread_cleanup *next; - void (*routine) (void *); - void *routine_arg; - int onstack; -}; - -#define THR_CLEANUP_PUSH(td, func, arg) { \ - struct pthread_cleanup __cup; \ - \ - __cup.routine = func; \ - __cup.routine_arg = arg; \ - __cup.onstack = 1; \ - __cup.next = (td)->cleanup; \ - (td)->cleanup = &__cup; - -#define THR_CLEANUP_POP(td, exec) \ - (td)->cleanup = __cup.next; \ - if ((exec) != 0) \ - __cup.routine(__cup.routine_arg); \ -} - -struct pthread_atfork { - TAILQ_ENTRY(pthread_atfork) qe; - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); -}; - -struct pthread_attr { - int sched_policy; - int sched_inherit; - int sched_interval; - int prio; - int suspend; -#define THR_STACK_USER 0x100 /* 0xFF reserved for <pthread.h> */ -#define THR_SIGNAL_THREAD 0x200 /* This is a signal thread */ - int flags; - void *arg_attr; - void (*cleanup_attr) (void *); - void *stackaddr_attr; - size_t stacksize_attr; - size_t guardsize_attr; -}; - -/* - * Thread creation state attributes. - */ -#define THR_CREATE_RUNNING 0 -#define THR_CREATE_SUSPENDED 1 - -/* - * Miscellaneous definitions. - */ -#define THR_STACK32_DEFAULT (1 * 1024 * 1024) -#define THR_STACK64_DEFAULT (2 * 1024 * 1024) - -/* - * Maximum size of initial thread's stack. This perhaps deserves to be larger - * than the stacks of other threads, since many applications are likely to run - * almost entirely on this stack. - */ -#define THR_STACK32_INITIAL (2 * 1024 * 1024) -#define THR_STACK64_INITIAL (4 * 1024 * 1024) - -/* - * Define the different priority ranges. All applications have thread - * priorities constrained within 0-31. The threads library raises the - * priority when delivering signals in order to ensure that signal - * delivery happens (from the POSIX spec) "as soon as possible". - * In the future, the threads library will also be able to map specific - * threads into real-time (cooperating) processes or kernel threads. - * The RT and SIGNAL priorities will be used internally and added to - * thread base priorities so that the scheduling queue can handle both - * normal and RT priority threads with and without signal handling. - * - * The approach taken is that, within each class, signal delivery - * always has priority over thread execution. - */ -#define THR_DEFAULT_PRIORITY 15 -#define THR_MIN_PRIORITY 0 -#define THR_MAX_PRIORITY 31 /* 0x1F */ -#define THR_SIGNAL_PRIORITY 32 /* 0x20 */ -#define THR_RT_PRIORITY 64 /* 0x40 */ -#define THR_FIRST_PRIORITY THR_MIN_PRIORITY -#define THR_LAST_PRIORITY \ - (THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY) -#define THR_BASE_PRIORITY(prio) ((prio) & THR_MAX_PRIORITY) - -/* - * Clock resolution in microseconds. - */ -#define CLOCK_RES_USEC 10000 - -/* - * Time slice period in microseconds. - */ -#define TIMESLICE_USEC 20000 - -/* - * XXX - Define a thread-safe macro to get the current time of day - * which is updated at regular intervals by something. - * - * For now, we just make the system call to get the time. - */ -#define KSE_GET_TOD(curkse, tsp) \ -do { \ - *tsp = (curkse)->k_kcb->kcb_kmbx.km_timeofday; \ - if ((tsp)->tv_sec == 0) \ - clock_gettime(CLOCK_REALTIME, tsp); \ -} while (0) - -struct pthread_rwlockattr { - int pshared; -}; - -struct pthread_rwlock { - pthread_mutex_t lock; /* monitor lock */ - pthread_cond_t read_signal; - pthread_cond_t write_signal; - int state; /* 0 = idle >0 = # of readers -1 = writer */ - int blocked_writers; -}; - -/* - * Thread states. - */ -enum pthread_state { - PS_RUNNING, - PS_LOCKWAIT, - PS_MUTEX_WAIT, - PS_COND_WAIT, - PS_SLEEP_WAIT, - PS_SIGSUSPEND, - PS_SIGWAIT, - PS_JOIN, - PS_SUSPENDED, - PS_DEAD, - PS_DEADLOCK, - PS_STATE_MAX -}; - -struct sigwait_data { - sigset_t *waitset; - siginfo_t *siginfo; /* used to save siginfo for sigwaitinfo() */ -}; - -union pthread_wait_data { - pthread_mutex_t mutex; - pthread_cond_t cond; - struct lock *lock; - struct sigwait_data *sigwait; -}; - -/* - * Define a continuation routine that can be used to perform a - * transfer of control: - */ -typedef void (*thread_continuation_t) (void *); - -/* - * This stores a thread's state prior to running a signal handler. - * It is used when a signal is delivered to a thread blocked in - * userland. If the signal handler returns normally, the thread's - * state is restored from here. - */ -struct pthread_sigframe { - int psf_valid; - int psf_flags; - int psf_cancelflags; - int psf_interrupted; - int psf_timeout; - int psf_signo; - enum pthread_state psf_state; - union pthread_wait_data psf_wait_data; - struct timespec psf_wakeup_time; - sigset_t psf_sigset; - sigset_t psf_sigmask; - int psf_seqno; - thread_continuation_t psf_continuation; -}; - -struct join_status { - struct pthread *thread; - void *ret; - int error; -}; - -struct pthread_specific_elem { - void *data; - int seqno; -}; - -typedef void (*const_key_destructor_t)(const void *); -typedef void (*key_destructor_t)(void *); - -struct pthread_key { - volatile int allocated; - volatile int count; - int seqno; - key_destructor_t destructor; -}; - -#define MAX_THR_LOCKLEVEL 5 -/* - * Thread structure. - */ -struct pthread { - /* Thread control block */ - struct tcb *tcb; - - /* - * Magic value to help recognize a valid thread structure - * from an invalid one: - */ -#define THR_MAGIC ((u_int32_t) 0xd09ba115) - u_int32_t magic; - char *name; - u_int64_t uniqueid; /* for gdb */ - - /* Queue entry for list of all threads: */ - TAILQ_ENTRY(pthread) tle; /* link for all threads in process */ - TAILQ_ENTRY(pthread) kle; /* link for all threads in KSE/KSEG */ - - /* Queue entry for GC lists: */ - TAILQ_ENTRY(pthread) gcle; - - /* Hash queue entry */ - LIST_ENTRY(pthread) hle; - - /* - * Lock for accesses to this thread structure. - */ - struct lock lock; - struct lockuser lockusers[MAX_THR_LOCKLEVEL]; - int locklevel; - kse_critical_t critical[MAX_KSE_LOCKLEVEL]; - struct kse *kse; - struct kse_group *kseg; - - /* - * Thread start routine, argument, stack pointer and thread - * attributes. - */ - void *(*start_routine)(void *); - void *arg; - struct pthread_attr attr; - - int active; /* thread running */ - int blocked; /* thread blocked in kernel */ - int need_switchout; - - /* - * Used for tracking delivery of signal handlers. - */ - siginfo_t *siginfo; - thread_continuation_t sigbackout; - - /* - * Cancelability flags - the lower 2 bits are used by cancel - * definitions in pthread.h - */ -#define THR_AT_CANCEL_POINT 0x0004 -#define THR_CANCELLING 0x0008 -#define THR_CANCEL_NEEDED 0x0010 - int cancelflags; - - thread_continuation_t continuation; - - /* - * The thread's base and pending signal masks. The active - * signal mask is stored in the thread's context (in mailbox). - */ - sigset_t sigmask; - sigset_t sigpend; - sigset_t *oldsigmask; - volatile int check_pending; - int refcount; - - /* Thread state: */ - enum pthread_state state; - volatile int lock_switch; - - /* - * Number of microseconds accumulated by this thread when - * time slicing is active. - */ - long slice_usec; - - /* - * Time to wake up thread. This is used for sleeping threads and - * for any operation which may time out (such as select). - */ - struct timespec wakeup_time; - - /* TRUE if operation has timed out. */ - int timeout; - - /* - * Error variable used instead of errno. The function __error() - * returns a pointer to this. - */ - int error; - - /* - * The joiner is the thread that is joining to this thread. The - * join status keeps track of a join operation to another thread. - */ - struct pthread *joiner; - struct join_status join_status; - - /* - * The current thread can belong to only one scheduling queue at - * a time (ready or waiting queue). It can also belong to: - * - * o A queue of threads waiting for a mutex - * o A queue of threads waiting for a condition variable - * - * It is possible for a thread to belong to more than one of the - * above queues if it is handling a signal. A thread may only - * enter a mutex or condition variable queue when it is not - * being called from a signal handler. If a thread is a member - * of one of these queues when a signal handler is invoked, it - * must be removed from the queue before invoking the handler - * and then added back to the queue after return from the handler. - * - * Use pqe for the scheduling queue link (both ready and waiting), - * sqe for synchronization (mutex, condition variable, and join) - * queue links, and qe for all other links. - */ - TAILQ_ENTRY(pthread) pqe; /* priority, wait queues link */ - TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */ - - /* Wait data. */ - union pthread_wait_data data; - - /* - * Set to TRUE if a blocking operation was - * interrupted by a signal: - */ - int interrupted; - - /* - * Set to non-zero when this thread has entered a critical - * region. We allow for recursive entries into critical regions. - */ - int critical_count; - - /* - * Set to TRUE if this thread should yield after leaving a - * critical region to check for signals, messages, etc. - */ - int critical_yield; - - int sflags; -#define THR_FLAGS_IN_SYNCQ 0x0001 - - /* Miscellaneous flags; only set with scheduling lock held. */ - int flags; -#define THR_FLAGS_PRIVATE 0x0001 -#define THR_FLAGS_IN_WAITQ 0x0002 /* in waiting queue using pqe link */ -#define THR_FLAGS_IN_RUNQ 0x0004 /* in run queue using pqe link */ -#define THR_FLAGS_EXITING 0x0008 /* thread is exiting */ -#define THR_FLAGS_SUSPENDED 0x0010 /* thread is suspended */ - - /* Thread list flags; only set with thread list lock held. */ -#define TLFLAGS_GC_SAFE 0x0001 /* thread safe for cleaning */ -#define TLFLAGS_IN_TDLIST 0x0002 /* thread in all thread list */ -#define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */ - int tlflags; - - /* - * Base priority is the user setable and retrievable priority - * of the thread. It is only affected by explicit calls to - * set thread priority and upon thread creation via a thread - * attribute or default priority. - */ - char base_priority; - - /* - * Inherited priority is the priority a thread inherits by - * taking a priority inheritence or protection mutex. It - * is not affected by base priority changes. Inherited - * priority defaults to and remains 0 until a mutex is taken - * that is being waited on by any other thread whose priority - * is non-zero. - */ - char inherited_priority; - - /* - * Active priority is always the maximum of the threads base - * priority and inherited priority. When there is a change - * in either the base or inherited priority, the active - * priority must be recalculated. - */ - char active_priority; - - /* Number of priority ceiling or protection mutexes owned. */ - int priority_mutex_count; - - /* Number rwlocks rdlocks held. */ - int rdlock_count; - - /* - * Queue of currently owned mutexes. - */ - TAILQ_HEAD(, pthread_mutex) mutexq; - - void *ret; - struct pthread_specific_elem *specific; - int specific_data_count; - - /* Alternative stack for sigaltstack() */ - stack_t sigstk; - - /* - * Current locks bitmap for rtld. - */ - int rtld_bits; - - /* Cleanup handlers Link List */ - struct pthread_cleanup *cleanup; - const char *fname; /* Ptr to source file name */ - int lineno; /* Source line number. */ -}; - -/* - * Critical regions can also be detected by looking at the threads - * current lock level. Ensure these macros increment and decrement - * the lock levels such that locks can not be held with a lock level - * of 0. - */ -#define THR_IN_CRITICAL(thrd) \ - (((thrd)->locklevel > 0) || \ - ((thrd)->critical_count > 0)) - -#define THR_YIELD_CHECK(thrd) \ -do { \ - if (!THR_IN_CRITICAL(thrd)) { \ - if (__predict_false(_libkse_debug)) \ - _thr_debug_check_yield(thrd); \ - if ((thrd)->critical_yield != 0) \ - _thr_sched_switch(thrd); \ - if ((thrd)->check_pending != 0) \ - _thr_sig_check_pending(thrd); \ - } \ -} while (0) - -#define THR_LOCK_ACQUIRE(thrd, lck) \ -do { \ - if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) { \ - THR_DEACTIVATE_LAST_LOCK(thrd); \ - (thrd)->locklevel++; \ - _lock_acquire((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1], \ - (thrd)->active_priority); \ - } else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define THR_LOCK_RELEASE(thrd, lck) \ -do { \ - if ((thrd)->locklevel > 0) { \ - _lock_release((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1]); \ - (thrd)->locklevel--; \ - THR_ACTIVATE_LAST_LOCK(thrd); \ - if ((thrd)->locklevel == 0) \ - THR_YIELD_CHECK(thrd); \ - } \ -} while (0) - -#define THR_ACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 1); \ -} while (0) - -#define THR_DEACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 0); \ -} while (0) - -/* - * For now, threads will have their own lock separate from their - * KSE scheduling lock. - */ -#define THR_LOCK(thr) THR_LOCK_ACQUIRE(thr, &(thr)->lock) -#define THR_UNLOCK(thr) THR_LOCK_RELEASE(thr, &(thr)->lock) -#define THR_THREAD_LOCK(curthrd, thr) THR_LOCK_ACQUIRE(curthrd, &(thr)->lock) -#define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock) - -/* - * Priority queue manipulation macros (using pqe link). We use - * the thread's kseg link instead of the kse link because a thread - * does not (currently) have a statically assigned kse. - */ -#define THR_RUNQ_INSERT_HEAD(thrd) \ - _pq_insert_head(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_INSERT_TAIL(thrd) \ - _pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_REMOVE(thrd) \ - _pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd) - -/* - * Macros to insert/remove threads to the all thread list and - * the gc list. - */ -#define THR_LIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_list, thrd, tle); \ - _thr_hash_add(thrd); \ - (thrd)->tlflags |= TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_LIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) != 0) { \ - TAILQ_REMOVE(&_thread_list, thrd, tle); \ - _thr_hash_remove(thrd); \ - (thrd)->tlflags &= ~TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_GCLIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\ - (thrd)->tlflags |= TLFLAGS_IN_GCLIST; \ - _gc_count++; \ - } \ -} while (0) -#define THR_GCLIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) != 0) { \ - TAILQ_REMOVE(&_thread_gc_list, thrd, gcle); \ - (thrd)->tlflags &= ~TLFLAGS_IN_GCLIST; \ - _gc_count--; \ - } \ -} while (0) - -#define GC_NEEDED() (atomic_load_acq_int(&_gc_count) >= 5) - -/* - * Locking the scheduling queue for another thread uses that thread's - * KSEG lock. - */ -#define THR_SCHED_LOCK(curthr, thr) do { \ - (curthr)->critical[(curthr)->locklevel] = _kse_critical_enter(); \ - (curthr)->locklevel++; \ - KSE_SCHED_LOCK((curthr)->kse, (thr)->kseg); \ -} while (0) - -#define THR_SCHED_UNLOCK(curthr, thr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (thr)->kseg); \ - (curthr)->locklevel--; \ - _kse_critical_leave((curthr)->critical[(curthr)->locklevel]); \ -} while (0) - -/* Take the scheduling lock with the intent to call the scheduler. */ -#define THR_LOCK_SWITCH(curthr) do { \ - (void)_kse_critical_enter(); \ - KSE_SCHED_LOCK((curthr)->kse, (curthr)->kseg); \ -} while (0) -#define THR_UNLOCK_SWITCH(curthr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (curthr)->kseg);\ -} while (0) - -#define THR_CRITICAL_ENTER(thr) (thr)->critical_count++ -#define THR_CRITICAL_LEAVE(thr) do { \ - (thr)->critical_count--; \ - if (((thr)->critical_yield != 0) && \ - ((thr)->critical_count == 0)) { \ - (thr)->critical_yield = 0; \ - _thr_sched_switch(thr); \ - } \ -} while (0) - -#define THR_IS_ACTIVE(thrd) \ - ((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd)) - -#define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0) - -#define THR_IS_SUSPENDED(thrd) \ - (((thrd)->state == PS_SUSPENDED) || \ - (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) -#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) -#define DBG_CAN_RUN(thrd) (((thrd)->tcb->tcb_tmbx.tm_dflags & \ - TMDF_SUSPEND) == 0) - -extern int __isthreaded; - -static inline int -_kse_isthreaded(void) -{ - return (__isthreaded != 0); -} - -/* - * Global variables for the pthread kernel. - */ - -SCLASS void *_usrstack SCLASS_PRESET(NULL); -SCLASS struct kse *_kse_initial SCLASS_PRESET(NULL); -SCLASS struct pthread *_thr_initial SCLASS_PRESET(NULL); -/* For debugger */ -SCLASS int _libkse_debug SCLASS_PRESET(0); -SCLASS int _thread_activated SCLASS_PRESET(0); -SCLASS int _thread_scope_system SCLASS_PRESET(0); - -/* List of all threads: */ -SCLASS TAILQ_HEAD(, pthread) _thread_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_list)); - -/* List of threads needing GC: */ -SCLASS TAILQ_HEAD(, pthread) _thread_gc_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_gc_list)); - -SCLASS int _thread_active_threads SCLASS_PRESET(1); - -SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _thr_atfork_list; -SCLASS pthread_mutex_t _thr_atfork_mutex; - -/* Default thread attributes: */ -SCLASS struct pthread_attr _pthread_attr_default - SCLASS_PRESET({ - SCHED_RR, 0, TIMESLICE_USEC, THR_DEFAULT_PRIORITY, - THR_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, - NULL, NULL, /* stacksize */0, /* guardsize */0 - }); - -/* Default mutex attributes: */ -SCLASS struct pthread_mutex_attr _pthread_mutexattr_default - SCLASS_PRESET({PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }); - -/* Default condition variable attributes: */ -SCLASS struct pthread_cond_attr _pthread_condattr_default - SCLASS_PRESET({COND_TYPE_FAST, 0}); - -/* Clock resolution in usec. */ -SCLASS int _clock_res_usec SCLASS_PRESET(CLOCK_RES_USEC); - -/* Array of signal actions for this process: */ -SCLASS struct sigaction _thread_sigact[_SIG_MAXSIG]; - -/* - * Lock for above count of dummy handlers and for the process signal - * mask and pending signal sets. - */ -SCLASS struct lock _thread_signal_lock; - -/* Pending signals and mask for this process: */ -SCLASS sigset_t _thr_proc_sigpending; -SCLASS siginfo_t _thr_proc_siginfo[_SIG_MAXSIG]; - -SCLASS pid_t _thr_pid SCLASS_PRESET(0); - -/* Garbage collector lock. */ -SCLASS struct lock _gc_lock; -SCLASS int _gc_check SCLASS_PRESET(0); -SCLASS int _gc_count SCLASS_PRESET(0); - -SCLASS struct lock _mutex_static_lock; -SCLASS struct lock _rwlock_static_lock; -SCLASS struct lock _keytable_lock; -SCLASS struct lock _thread_list_lock; -SCLASS size_t _thr_guard_default; -SCLASS size_t _thr_stack_default; -SCLASS size_t _thr_stack_initial; -SCLASS int _thr_page_size; -SCLASS pthread_t _thr_sig_daemon; -SCLASS int _thr_debug_flags SCLASS_PRESET(0); - -/* Undefine the storage class and preset specifiers: */ -#undef SCLASS -#undef SCLASS_PRESET - - -/* - * Function prototype definitions. - */ -__BEGIN_DECLS -int _cond_reinit(pthread_cond_t *); -struct kse *_kse_alloc(struct pthread *, int sys_scope); -kse_critical_t _kse_critical_enter(void); -void _kse_critical_leave(kse_critical_t); -int _kse_in_critical(void); -void _kse_free(struct pthread *, struct kse *); -void _kse_init(void); -struct kse_group *_kseg_alloc(struct pthread *); -void _kse_lock_wait(struct lock *, struct lockuser *lu); -void _kse_lock_wakeup(struct lock *, struct lockuser *lu); -void _kse_single_thread(struct pthread *); -int _kse_setthreaded(int); -void _kseg_free(struct kse_group *); -int _mutex_cv_lock(pthread_mutex_t *); -int _mutex_cv_unlock(pthread_mutex_t *); -void _mutex_notify_priochange(struct pthread *, struct pthread *, int); -int _mutex_reinit(struct pthread_mutex *); -void _mutex_unlock_private(struct pthread *); -void _libpthread_init(struct pthread *); -int _pq_alloc(struct pq_queue *, int, int); -void _pq_free(struct pq_queue *); -int _pq_init(struct pq_queue *); -void _pq_remove(struct pq_queue *pq, struct pthread *); -void _pq_insert_head(struct pq_queue *pq, struct pthread *); -void _pq_insert_tail(struct pq_queue *pq, struct pthread *); -struct pthread *_pq_first(struct pq_queue *pq); -struct pthread *_pq_first_debug(struct pq_queue *pq); -void *_pthread_getspecific(pthread_key_t); -int _pthread_key_create(pthread_key_t *, void (*) (void *)); -int _pthread_key_delete(pthread_key_t); -int _pthread_mutex_destroy(pthread_mutex_t *); -int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); -int _pthread_mutex_lock(pthread_mutex_t *); -int _pthread_mutex_trylock(pthread_mutex_t *); -int _pthread_mutex_unlock(pthread_mutex_t *); -int _pthread_mutexattr_init(pthread_mutexattr_t *); -int _pthread_mutexattr_destroy(pthread_mutexattr_t *); -int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); -int _pthread_once(pthread_once_t *, void (*) (void)); -int _pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); -int _pthread_rwlock_destroy (pthread_rwlock_t *); -struct pthread *_pthread_self(void); -int _pthread_setspecific(pthread_key_t, const void *); -void _pthread_yield(void); -void _pthread_cleanup_push(void (*routine) (void *), void *routine_arg); -void _pthread_cleanup_pop(int execute); -struct pthread *_thr_alloc(struct pthread *); -void _thr_exit(const char *, int, const char *) __dead2; -void _thr_exit_cleanup(void); -void _thr_lock_wait(struct lock *lock, struct lockuser *lu); -void _thr_lock_wakeup(struct lock *lock, struct lockuser *lu); -void _thr_mutex_reinit(pthread_mutex_t *); -int _thr_ref_add(struct pthread *, struct pthread *, int); -void _thr_ref_delete(struct pthread *, struct pthread *); -void _thr_rtld_init(void); -void _thr_rtld_fini(void); -int _thr_schedule_add(struct pthread *, struct pthread *); -void _thr_schedule_remove(struct pthread *, struct pthread *); -void _thr_setrunnable(struct pthread *curthread, struct pthread *thread); -struct kse_mailbox *_thr_setrunnable_unlocked(struct pthread *thread); -struct kse_mailbox *_thr_sig_add(struct pthread *, int, siginfo_t *); -void _thr_sig_dispatch(struct kse *, int, siginfo_t *); -int _thr_stack_alloc(struct pthread_attr *); -void _thr_stack_free(struct pthread_attr *); -void _thr_exit_cleanup(void); -void _thr_free(struct pthread *, struct pthread *); -void _thr_gc(struct pthread *); -void _thr_panic_exit(char *, int, char *); -void _thread_cleanupspecific(void); -void _thread_dump_info(void); -void _thread_printf(int, const char *, ...); -void _thr_sched_switch(struct pthread *); -void _thr_sched_switch_unlocked(struct pthread *); -void _thr_set_timeout(const struct timespec *); -void _thr_seterrno(struct pthread *, int); -void _thr_sig_handler(int, siginfo_t *, void *); -void _thr_sig_check_pending(struct pthread *); -void _thr_sig_rundown(struct pthread *, ucontext_t *); -void _thr_sig_send(struct pthread *pthread, int sig); -void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf); -void _thr_spinlock_init(void); -void _thr_cancel_enter(struct pthread *); -void _thr_cancel_leave(struct pthread *, int); -int _thr_setconcurrency(int new_level); -int _thr_setmaxconcurrency(void); -void _thr_critical_enter(struct pthread *); -void _thr_critical_leave(struct pthread *); -int _thr_start_sig_daemon(void); -int _thr_getprocsig(int sig, siginfo_t *siginfo); -int _thr_getprocsig_unlocked(int sig, siginfo_t *siginfo); -void _thr_signal_init(void); -void _thr_signal_deinit(void); -void _thr_hash_add(struct pthread *); -void _thr_hash_remove(struct pthread *); -struct pthread *_thr_hash_find(struct pthread *); -void _thr_finish_cancellation(void *arg); -int _thr_sigonstack(void *sp); -void _thr_debug_check_yield(struct pthread *); - -/* - * Aliases for _pthread functions. Should be called instead of - * originals if PLT replocation is unwanted at runtme. - */ -int _thr_cond_broadcast(pthread_cond_t *); -int _thr_cond_signal(pthread_cond_t *); -int _thr_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int _thr_mutex_lock(pthread_mutex_t *); -int _thr_mutex_unlock(pthread_mutex_t *); -int _thr_rwlock_rdlock (pthread_rwlock_t *); -int _thr_rwlock_wrlock (pthread_rwlock_t *); -int _thr_rwlock_unlock (pthread_rwlock_t *); - -/* #include <sys/aio.h> */ -#ifdef _SYS_AIO_H_ -int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); -#endif - -/* #include <fcntl.h> */ -#ifdef _SYS_FCNTL_H_ -int __sys_fcntl(int, int, ...); -int __sys_open(const char *, int, ...); -#endif - -/* #include <sys/ioctl.h> */ -#ifdef _SYS_IOCTL_H_ -int __sys_ioctl(int, unsigned long, ...); -#endif - -/* #inclde <sched.h> */ -#ifdef _SCHED_H_ -int __sys_sched_yield(void); -#endif - -/* #include <signal.h> */ -#ifdef _SIGNAL_H_ -int __sys_kill(pid_t, int); -int __sys_sigaction(int, const struct sigaction *, struct sigaction *); -int __sys_sigpending(sigset_t *); -int __sys_sigprocmask(int, const sigset_t *, sigset_t *); -int __sys_sigsuspend(const sigset_t *); -int __sys_sigreturn(ucontext_t *); -int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); -#endif - -/* #include <sys/socket.h> */ -#ifdef _SYS_SOCKET_H_ -int __sys_accept(int, struct sockaddr *, socklen_t *); -int __sys_connect(int, const struct sockaddr *, socklen_t); -int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, - off_t *, int); -#endif - -/* #include <sys/uio.h> */ -#ifdef _SYS_UIO_H_ -ssize_t __sys_readv(int, const struct iovec *, int); -ssize_t __sys_writev(int, const struct iovec *, int); -#endif - -/* #include <time.h> */ -#ifdef _TIME_H_ -int __sys_nanosleep(const struct timespec *, struct timespec *); -#endif - -/* #include <unistd.h> */ -#ifdef _UNISTD_H_ -int __sys_close(int); -int __sys_execve(const char *, char * const *, char * const *); -int __sys_fork(void); -int __sys_fsync(int); -pid_t __sys_getpid(void); -int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -ssize_t __sys_read(int, void *, size_t); -ssize_t __sys_write(int, const void *, size_t); -void __sys_exit(int); -int __sys_sigwait(const sigset_t *, int *); -int __sys_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *); -#endif - -/* #include <poll.h> */ -#ifdef _SYS_POLL_H_ -int __sys_poll(struct pollfd *, unsigned, int); -#endif - -/* #include <sys/mman.h> */ -#ifdef _SYS_MMAN_H_ -int __sys_msync(void *, size_t, int); -#endif - -static __inline int -_thr_dump_enabled(void) -{ - - return ((_thr_debug_flags & DBG_INFO_DUMP) != 0); -} - -#endif /* !_THR_PRIVATE_H */ diff --git a/lib/libkse/thread/thr_pselect.c b/lib/libkse/thread/thr_pselect.c deleted file mode 100644 index a8cbf13..0000000 --- a/lib/libkse/thread/thr_pselect.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2002 Daniel M. Eischen <deischen@freebsd.org> - * 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <sys/select.h> -#include <sys/time.h> -#include <errno.h> -#include <signal.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask); - -int _pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask); - -__weak_reference(_pselect, pselect); - -int -_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pselect(count, rfds, wfds, efds, timo, mask); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_pspinlock.c b/lib/libkse/thread/thr_pspinlock.c deleted file mode 100644 index 76376be..0000000 --- a/lib/libkse/thread/thr_pspinlock.c +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <stdlib.h> -#include "un-namespace.h" - -#include "atomic_ops.h" -#include "thr_private.h" - -#define SPIN_COUNT 10000 - -__weak_reference(_pthread_spin_init, pthread_spin_init); -__weak_reference(_pthread_spin_destroy, pthread_spin_destroy); -__weak_reference(_pthread_spin_trylock, pthread_spin_trylock); -__weak_reference(_pthread_spin_lock, pthread_spin_lock); -__weak_reference(_pthread_spin_unlock, pthread_spin_unlock); - -int -_pthread_spin_init(pthread_spinlock_t *lock, int pshared) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || pshared != PTHREAD_PROCESS_PRIVATE) - ret = EINVAL; - else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL) - ret = ENOMEM; - else { - lck->s_lock = 0; - lck->s_owner= NULL; - *lock = lck; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_destroy(pthread_spinlock_t *lock) -{ - int ret; - - if (lock == NULL || *lock == NULL) - ret = EINVAL; - else if ((*lock)->s_owner != NULL) - ret = EBUSY; - else { - free(*lock); - *lock = NULL; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_trylock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else if (lck->s_lock != 0) - ret = EBUSY; - else { - atomic_swap_int(&(lck)->s_lock, 1, &oldval); - if (oldval) - ret = EBUSY; - else { - lck->s_owner = _pthread_self(); - ret = 0; - } - } - return (ret); -} - -int -_pthread_spin_lock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int count, oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else { - do { - count = SPIN_COUNT; - while (lck->s_lock) { -#ifdef __i386__ - /* tell cpu we are spinning */ - __asm __volatile("pause"); -#endif - if (--count <= 0) { - count = SPIN_COUNT; - _pthread_yield(); - } - } - atomic_swap_int(&(lck)->s_lock, 1, &oldval); - } while (oldval); - - lck->s_owner = self; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_unlock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else { - if (lck->s_owner != _pthread_self()) - ret = EPERM; - else { - lck->s_owner = NULL; - atomic_swap_int(&lck->s_lock, 0, &ret); - ret = 0; - } - } - - return (ret); -} - diff --git a/lib/libkse/thread/thr_raise.c b/lib/libkse/thread/thr_raise.c deleted file mode 100644 index 707852a..0000000 --- a/lib/libkse/thread/thr_raise.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2003 David Xu<davidxu@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _raise(int sig); - -__weak_reference(_raise, raise); - -int -_raise(int sig) -{ - int ret; - - if (!_kse_isthreaded()) - ret = kill(getpid(), sig); - else { - ret = _pthread_kill(_pthread_self(), sig); - if (ret != 0) { - errno = ret; - ret = -1; - } - } - return (ret); -} diff --git a/lib/libkse/thread/thr_read.c b/lib/libkse/thread/thr_read.c deleted file mode 100644 index 829d069..0000000 --- a/lib/libkse/thread/thr_read.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -ssize_t __read(int fd, void *buf, size_t nbytes); - -__weak_reference(__read, read); - -ssize_t -__read(int fd, void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_read(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_readv.c b/lib/libkse/thread/thr_readv.c deleted file mode 100644 index 660a65a..0000000 --- a/lib/libkse/thread/thr_readv.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -ssize_t __readv(int fd, const struct iovec *iov, int iovcnt); - -__weak_reference(__readv, readv); - -ssize_t -__readv(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_readv(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_resume_np.c b/lib/libkse/thread/thr_resume_np.c deleted file mode 100644 index 685dbf3..0000000 --- a/lib/libkse/thread/thr_resume_np.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_resume_np(pthread_t thread); -void _pthread_resume_all_np(void); - -static struct kse_mailbox *resume_common(struct pthread *); - -__weak_reference(_pthread_resume_np, pthread_resume_np); -__weak_reference(_pthread_resume_all_np, pthread_resume_all_np); - - -/* Resume a thread: */ -int -_pthread_resume_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - int ret; - - /* Add a reference to the thread: */ - if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - return (ret); -} - -void -_pthread_resume_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - struct kse_mailbox *kmbx; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -static struct kse_mailbox * -resume_common(struct pthread *thread) -{ - /* Clear the suspend flag: */ - thread->flags &= ~THR_FLAGS_SUSPENDED; - - /* - * If the thread's state is suspended, that means it is - * now runnable but not in any scheduling queue. Set the - * state to running and insert it into the run queue. - */ - if (thread->state == PS_SUSPENDED) - return (_thr_setrunnable_unlocked(thread)); - else - return (NULL); -} diff --git a/lib/libkse/thread/thr_rtld.c b/lib/libkse/thread/thr_rtld.c deleted file mode 100644 index 9320c48..0000000 --- a/lib/libkse/thread/thr_rtld.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2001 Alexander Kabaev - * 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 - * in this position and unchanged. - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <sys/cdefs.h> -#include <stdlib.h> - -#include "rtld_lock.h" -#include "thr_private.h" - -static int _thr_rtld_clr_flag(int); -static void *_thr_rtld_lock_create(void); -static void _thr_rtld_lock_destroy(void *); -static void _thr_rtld_lock_release(void *); -static void _thr_rtld_rlock_acquire(void *); -static int _thr_rtld_set_flag(int); -static void _thr_rtld_wlock_acquire(void *); - -#ifdef NOTYET -static void * -_thr_rtld_lock_create(void) -{ - pthread_rwlock_t prwlock; - if (_pthread_rwlock_init(&prwlock, NULL)) - return (NULL); - return (prwlock); -} - -static void -_thr_rtld_lock_destroy(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - if (prwlock != NULL) - _pthread_rwlock_destroy(&prwlock); -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_rdlock(&prwlock); -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_wrlock(&prwlock); -} - -static void -_thr_rtld_lock_release(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_unlock(&prwlock); -} - - -static int -_thr_rtld_set_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits |= mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - - return (bits); -} - -static int -_thr_rtld_clr_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits &= ~mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - return (bits); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} -#endif - -struct rtld_kse_lock { - struct lock lck; - struct kse *owner; - kse_critical_t crit; - int count; - int write; -}; - -static void * -_thr_rtld_lock_create(void) -{ - struct rtld_kse_lock *l; - - if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) { - _lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup, calloc); - l->owner = NULL; - l->count = 0; - l->write = 0; - } - return (l); -} - -static void -_thr_rtld_lock_destroy(void *lock __unused) -{ - /* XXX We really can not free memory after a fork() */ -#if 0 - struct rtld_kse_lock *l; - - l = (struct rtld_kse_lock *)lock; - _lock_destroy(&l->lck); - free(l); -#endif - return; -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - l->count++; - _kse_critical_leave(crit); /* probably not necessary */ - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 0; - } -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - _kse_critical_leave(crit); - PANIC("Recursive write lock attempt on rtld lock"); - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 1; - } -} - -static void -_thr_rtld_lock_release(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner != curkse) { - /* - * We might want to forcibly unlock the rtld lock - * and/or disable threaded mode so there is better - * chance that the panic will work. Otherwise, - * we could end up trying to take the rtld lock - * again. - */ - _kse_critical_leave(crit); - PANIC("Attempt to unlock rtld lock when not owner."); - } else { - l->count--; - if (l->count == 0) { - /* - * If there ever is a count associated with - * _kse_critical_leave(), we'll need to add - * another call to it here with the crit - * value from above. - */ - crit = l->crit; - l->owner = NULL; - l->write = 0; - KSE_LOCK_RELEASE(curkse, &l->lck); - } - _kse_critical_leave(crit); - } -} - - -static int -_thr_rtld_set_flag(int mask __unused) -{ - return (0); -} - -static int -_thr_rtld_clr_flag(int mask __unused) -{ - return (0); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} diff --git a/lib/libkse/thread/thr_rwlock.c b/lib/libkse/thread/thr_rwlock.c deleted file mode 100644 index 1c96c3a..0000000 --- a/lib/libkse/thread/thr_rwlock.c +++ /dev/null @@ -1,419 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* maximum number of times a read lock may be obtained */ -#define MAX_READ_LOCKS (INT_MAX - 1) - -__weak_reference(_pthread_rwlock_destroy, pthread_rwlock_destroy); -__weak_reference(_pthread_rwlock_init, pthread_rwlock_init); -__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock); -__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); -__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); -__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); -__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); -__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); -__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); - -/* - * Prototypes - */ -static int init_static(pthread_rwlock_t *rwlock); - - -static int -init_static(pthread_rwlock_t *rwlock) -{ - struct pthread *thread = _get_curthread(); - int ret; - - THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock); - - if (*rwlock == NULL) - ret = _pthread_rwlock_init(rwlock, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_rwlock_static_lock); - return (ret); -} - -int -_pthread_rwlock_destroy (pthread_rwlock_t *rwlock) -{ - int ret; - - if (rwlock == NULL) - ret = EINVAL; - else { - pthread_rwlock_t prwlock; - - prwlock = *rwlock; - - _pthread_mutex_destroy(&prwlock->lock); - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_cond_destroy(&prwlock->write_signal); - free(prwlock); - - *rwlock = NULL; - - ret = 0; - } - return (ret); -} - -int -_pthread_rwlock_init (pthread_rwlock_t *rwlock, - const pthread_rwlockattr_t *attr __unused) -{ - pthread_rwlock_t prwlock; - int ret; - - /* allocate rwlock object */ - prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock)); - - if (prwlock == NULL) - return (ENOMEM); - - /* initialize the lock */ - if ((ret = _pthread_mutex_init(&prwlock->lock, NULL)) != 0) - free(prwlock); - else { - /* initialize the read condition signal */ - ret = _pthread_cond_init(&prwlock->read_signal, NULL); - - if (ret != 0) { - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* initialize the write condition signal */ - ret = _pthread_cond_init(&prwlock->write_signal, NULL); - - if (ret != 0) { - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* success */ - prwlock->state = 0; - prwlock->blocked_writers = 0; - - *rwlock = prwlock; - } - } - } - - return (ret); -} - -static int -rwlock_rdlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - struct pthread *curthread; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - /* check lock count */ - if (prwlock->state == MAX_READ_LOCKS) { - _thr_mutex_unlock(&prwlock->lock); - return (EAGAIN); - } - - curthread = _get_curthread(); - if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* - * To avoid having to track all the rdlocks held by - * a thread or all of the threads that hold a rdlock, - * we keep a simple count of all the rdlocks held by - * a thread. If a thread holds any rdlocks it is - * possible that it is attempting to take a recursive - * rdlock. If there are blocked writers and precedence - * is given to them, then that would result in the thread - * deadlocking. So allowing a thread to take the rdlock - * when it already has one or more rdlocks avoids the - * deadlock. I hope the reader can follow that logic ;-) - */ - ; /* nothing needed */ - } else { - /* give writers priority over readers */ - while (prwlock->blocked_writers || prwlock->state < 0) { - if (abstime) - ret = _pthread_cond_timedwait - (&prwlock->read_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->read_signal, - &prwlock->lock); - if (ret != 0) { - /* can't do a whole lot if this fails */ - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - } - } - - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - - /* - * Something is really wrong if this call fails. Returning - * error won't do because we've already obtained the read - * lock. Decrementing 'state' is no good because we probably - * don't have the monitor lock. - */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_rdlock_common(rwlock, NULL)); -} - -__strong_reference(_pthread_rwlock_rdlock, _thr_rwlock_rdlock); - -int -_pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_rdlock_common(rwlock, abstime)); -} - -int -_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state == MAX_READ_LOCKS) - ret = EAGAIN; - else if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* see comment for pthread_rwlock_rdlock() */ - curthread->rdlock_count++; - prwlock->state++; - } - /* give writers priority over readers */ - else if (prwlock->blocked_writers || prwlock->state < 0) - ret = EBUSY; - else { - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - } - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - if (prwlock->state != 0) - ret = EBUSY; - else - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_unlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - if (prwlock == NULL) - return (EINVAL); - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state > 0) { - curthread->rdlock_count--; - prwlock->state--; - if (prwlock->state == 0 && prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - } else if (prwlock->state < 0) { - prwlock->state = 0; - - if (prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - else - ret = _thr_cond_broadcast(&prwlock->read_signal); - } else - ret = EINVAL; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -__strong_reference(_pthread_rwlock_unlock, _thr_rwlock_unlock); - -static int -rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - while (prwlock->state != 0) { - prwlock->blocked_writers++; - - if (abstime != NULL) - ret = _pthread_cond_timedwait(&prwlock->write_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->write_signal, - &prwlock->lock); - if (ret != 0) { - prwlock->blocked_writers--; - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - - prwlock->blocked_writers--; - } - - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_wrlock_common (rwlock, NULL)); -} -__strong_reference(_pthread_rwlock_wrlock, _thr_rwlock_wrlock); - -int -_pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_wrlock_common (rwlock, abstime)); -} diff --git a/lib/libkse/thread/thr_rwlockattr.c b/lib/libkse/thread/thr_rwlockattr.c deleted file mode 100644 index e5b9c96..0000000 --- a/lib/libkse/thread/thr_rwlockattr.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy); -__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared); -__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init); -__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared); - -int -_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = *rwlockattr; - - if (prwlockattr == NULL) - return(EINVAL); - - free(prwlockattr); - - return(0); -} - -int -_pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *rwlockattr, - int *pshared) -{ - *pshared = (*rwlockattr)->pshared; - - return(0); -} - -int -_pthread_rwlockattr_init(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = (pthread_rwlockattr_t) - malloc(sizeof(struct pthread_rwlockattr)); - - if (prwlockattr == NULL) - return(ENOMEM); - - prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE; - *rwlockattr = prwlockattr; - - return(0); -} - -int -_pthread_rwlockattr_setpshared(pthread_rwlockattr_t *rwlockattr, int pshared) -{ - /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return(EINVAL); - - (*rwlockattr)->pshared = pshared; - - return(0); -} - diff --git a/lib/libkse/thread/thr_select.c b/lib/libkse/thread/thr_select.c deleted file mode 100644 index 6d0219c..0000000 --- a/lib/libkse/thread/thr_select.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <errno.h> -#include <poll.h> -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __select(int numfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - -__weak_reference(__select, select); - -int -__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - int ret; - - if (numfds == 0 && timeout != NULL) { - TIMEVAL_TO_TIMESPEC(timeout, &ts); - ret = _nanosleep(&ts, NULL); - } else { - _thr_cancel_enter(curthread); - ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); - _thr_cancel_leave(curthread, 1); - } - return (ret); -} diff --git a/lib/libkse/thread/thr_sem.c b/lib/libkse/thread/thr_sem.c deleted file mode 100644 index 87d2057b..0000000 --- a/lib/libkse/thread/thr_sem.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/queue.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <stdlib.h> -#include <time.h> -#include <_semaphore.h> -#include "un-namespace.h" -#include "libc_private.h" -#include "thr_private.h" - -__weak_reference(_sem_init, sem_init); -__weak_reference(_sem_wait, sem_wait); -__weak_reference(_sem_timedwait, sem_timedwait); -__weak_reference(_sem_post, sem_post); - - -static inline int -sem_check_validity(sem_t *sem) -{ - - if ((sem != NULL) && ((*sem)->magic == SEM_MAGIC)) - return (0); - else { - errno = EINVAL; - return (-1); - } -} - -static void -decrease_nwaiters(void *arg) -{ - sem_t *sem = (sem_t *)arg; - - (*sem)->nwaiters--; - /* - * this function is called from cancellation point, - * the mutex should already be hold. - */ - _pthread_mutex_unlock(&(*sem)->lock); -} - -static sem_t -sem_alloc(unsigned int value, semid_t semid, int system_sem) -{ - sem_t sem; - - if (value > SEM_VALUE_MAX) { - errno = EINVAL; - return (NULL); - } - - sem = (sem_t)malloc(sizeof(struct sem)); - if (sem == NULL) { - errno = ENOSPC; - return (NULL); - } - - /* - * Initialize the semaphore. - */ - if (_pthread_mutex_init(&sem->lock, NULL) != 0) { - free(sem); - errno = ENOSPC; - return (NULL); - } - - if (_pthread_cond_init(&sem->gtzero, NULL) != 0) { - _pthread_mutex_destroy(&sem->lock); - free(sem); - errno = ENOSPC; - return (NULL); - } - - sem->count = (u_int32_t)value; - sem->nwaiters = 0; - sem->magic = SEM_MAGIC; - sem->semid = semid; - sem->syssem = system_sem; - return (sem); -} - -int -_sem_init(sem_t *sem, int pshared, unsigned int value) -{ - semid_t semid; - - semid = (semid_t)SEM_USER; - if ((pshared != 0) && (ksem_init(&semid, value) != 0)) - return (-1); - - (*sem) = sem_alloc(value, semid, pshared); - if ((*sem) == NULL) { - if (pshared != 0) - ksem_destroy(semid); - return (-1); - } - return (0); -} - -int -_sem_wait(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - curthread = _get_curthread(); - if ((*sem)->syssem != 0) { - _thr_cancel_enter(curthread); - retval = ksem_wait((*sem)->semid); - _thr_cancel_leave(curthread, retval != 0); - } - else { - _pthread_testcancel(); - _pthread_mutex_lock(&(*sem)->lock); - - while ((*sem)->count <= 0) { - (*sem)->nwaiters++; - THR_CLEANUP_PUSH(curthread, decrease_nwaiters, sem); - _pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); - THR_CLEANUP_POP(curthread, 0); - (*sem)->nwaiters--; - } - (*sem)->count--; - - _pthread_mutex_unlock(&(*sem)->lock); - - retval = 0; - } - return (retval); -} - -int -_sem_timedwait(sem_t * __restrict sem, - const struct timespec * __restrict abs_timeout) -{ - struct pthread *curthread; - int retval; - int timeout_invalid; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) { - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - retval = ksem_timedwait((*sem)->semid, abs_timeout); - _thr_cancel_leave(curthread, retval != 0); - } - else { - /* - * The timeout argument is only supposed to - * be checked if the thread would have blocked. - * This is checked outside of the lock so a - * segfault on an invalid address doesn't end - * up leaving the mutex locked. - */ - _pthread_testcancel(); - timeout_invalid = (abs_timeout->tv_nsec >= 1000000000) || - (abs_timeout->tv_nsec < 0); - _pthread_mutex_lock(&(*sem)->lock); - - if ((*sem)->count <= 0) { - if (timeout_invalid) { - _pthread_mutex_unlock(&(*sem)->lock); - errno = EINVAL; - return (-1); - } - (*sem)->nwaiters++; - _pthread_cleanup_push(decrease_nwaiters, sem); - _pthread_cond_timedwait(&(*sem)->gtzero, - &(*sem)->lock, abs_timeout); - _pthread_cleanup_pop(0); - (*sem)->nwaiters--; - } - if ((*sem)->count == 0) { - errno = ETIMEDOUT; - retval = -1; - } - else { - (*sem)->count--; - retval = 0; - } - - _pthread_mutex_unlock(&(*sem)->lock); - } - - return (retval); -} - -int -_sem_post(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) - retval = ksem_post((*sem)->semid); - else { - /* - * sem_post() is required to be safe to call from within - * signal handlers. Thus, we must enter a critical region. - */ - curthread = _get_curthread(); - _thr_critical_enter(curthread); - _pthread_mutex_lock(&(*sem)->lock); - - (*sem)->count++; - if ((*sem)->nwaiters > 0) - _pthread_cond_signal(&(*sem)->gtzero); - - _pthread_mutex_unlock(&(*sem)->lock); - _thr_critical_leave(curthread); - retval = 0; - } - - return (retval); -} diff --git a/lib/libkse/thread/thr_seterrno.c b/lib/libkse/thread/thr_seterrno.c deleted file mode 100644 index f0b5f97..0000000 --- a/lib/libkse/thread/thr_seterrno.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* - * This function needs to reference the global error variable which is - * normally hidden from the user. - */ -#ifdef errno -#undef errno; -#endif -extern int errno; - -void _thread_seterrno(pthread_t thread, int error); - -void -_thread_seterrno(pthread_t thread, int error) -{ - /* Check for the initial thread: */ - if (thread == _thr_initial) - /* The initial thread always uses the global error variable: */ - errno = error; - else - /* - * Threads other than the initial thread always use the error - * field in the thread structureL - */ - thread->error = error; -} diff --git a/lib/libkse/thread/thr_setprio.c b/lib/libkse/thread/thr_setprio.c deleted file mode 100644 index 4ea9962..0000000 --- a/lib/libkse/thread/thr_setprio.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_setprio(pthread_t pthread, int prio); - -__weak_reference(_pthread_setprio, pthread_setprio); - -int -_pthread_setprio(pthread_t pthread, int prio) -{ - int ret, policy; - struct sched_param param; - - if ((ret = _pthread_getschedparam(pthread, &policy, ¶m)) == 0) { - param.sched_priority = prio; - ret = _pthread_setschedparam(pthread, policy, ¶m); - } - - /* Return the error status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_setschedparam.c b/lib/libkse/thread/thr_setschedparam.c deleted file mode 100644 index 4a9354f..0000000 --- a/lib/libkse/thread/thr_setschedparam.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <sys/param.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_setschedparam, pthread_setschedparam); - -int -_pthread_setschedparam(pthread_t pthread, int policy, - const struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int in_syncq; - int in_readyq = 0; - int old_prio; - int ret = 0; - - if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) { - /* Return an invalid argument error: */ - ret = EINVAL; - } else if ((param->sched_priority < THR_MIN_PRIORITY) || - (param->sched_priority > THR_MAX_PRIORITY)) { - /* Return an unsupported value error. */ - ret = ENOTSUP; - - /* Find the thread in the list of active threads: */ - } else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - /* - * Lock the threads scheduling queue while we change - * its priority: - */ - THR_SCHED_LOCK(curthread, pthread); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)) { - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - return (ESRCH); - } - in_syncq = pthread->sflags & THR_FLAGS_IN_SYNCQ; - - /* Set the scheduling policy: */ - pthread->attr.sched_policy = policy; - - if (param->sched_priority == - THR_BASE_PRIORITY(pthread->base_priority)) - /* - * There is nothing to do; unlock the threads - * scheduling queue. - */ - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * Remove the thread from its current priority - * queue before any adjustments are made to its - * active priority: - */ - old_prio = pthread->active_priority; - if ((pthread->flags & THR_FLAGS_IN_RUNQ) != 0) { - in_readyq = 1; - THR_RUNQ_REMOVE(pthread); - } - - /* Set the thread base priority: */ - pthread->base_priority &= - (THR_SIGNAL_PRIORITY | THR_RT_PRIORITY); - pthread->base_priority = param->sched_priority; - - /* Recalculate the active priority: */ - pthread->active_priority = MAX(pthread->base_priority, - pthread->inherited_priority); - - if (in_readyq) { - if ((pthread->priority_mutex_count > 0) && - (old_prio > pthread->active_priority)) { - /* - * POSIX states that if the priority is - * being lowered, the thread must be - * inserted at the head of the queue for - * its priority if it owns any priority - * protection or inheritence mutexes. - */ - THR_RUNQ_INSERT_HEAD(pthread); - } - else - THR_RUNQ_INSERT_TAIL(pthread); - } - - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Check for any mutex priority adjustments. This - * includes checking for a priority mutex on which - * this thread is waiting. - */ - _mutex_notify_priochange(curthread, pthread, in_syncq); - } - _thr_ref_delete(curthread, pthread); - } - return (ret); -} diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c deleted file mode 100644 index e3cf5bb..0000000 --- a/lib/libkse/thread/thr_sig.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Prototypes: */ -static inline void build_siginfo(siginfo_t *info, int signo); -#ifndef SYSTEM_SCOPE_ONLY -static struct pthread *thr_sig_find(struct kse *curkse, int sig, - siginfo_t *info); -#endif -static inline void thr_sigframe_restore(struct pthread *thread, - struct pthread_sigframe *psf); -static inline void thr_sigframe_save(struct pthread *thread, - struct pthread_sigframe *psf); - -#define SA_KILL 0x01 /* terminates process by default */ -#define SA_STOP 0x02 -#define SA_CONT 0x04 - -static int sigproptbl[NSIG] = { - SA_KILL, /* SIGHUP */ - SA_KILL, /* SIGINT */ - SA_KILL, /* SIGQUIT */ - SA_KILL, /* SIGILL */ - SA_KILL, /* SIGTRAP */ - SA_KILL, /* SIGABRT */ - SA_KILL, /* SIGEMT */ - SA_KILL, /* SIGFPE */ - SA_KILL, /* SIGKILL */ - SA_KILL, /* SIGBUS */ - SA_KILL, /* SIGSEGV */ - SA_KILL, /* SIGSYS */ - SA_KILL, /* SIGPIPE */ - SA_KILL, /* SIGALRM */ - SA_KILL, /* SIGTERM */ - 0, /* SIGURG */ - SA_STOP, /* SIGSTOP */ - SA_STOP, /* SIGTSTP */ - SA_CONT, /* SIGCONT */ - 0, /* SIGCHLD */ - SA_STOP, /* SIGTTIN */ - SA_STOP, /* SIGTTOU */ - 0, /* SIGIO */ - SA_KILL, /* SIGXCPU */ - SA_KILL, /* SIGXFSZ */ - SA_KILL, /* SIGVTALRM */ - SA_KILL, /* SIGPROF */ - 0, /* SIGWINCH */ - 0, /* SIGINFO */ - SA_KILL, /* SIGUSR1 */ - SA_KILL /* SIGUSR2 */ -}; - -/* #define DEBUG_SIGNAL */ -#ifdef DEBUG_SIGNAL -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Signal setup and delivery. - * - * 1) Delivering signals to threads in the same KSE. - * These signals are sent by upcall events and are set in the - * km_sigscaught field of the KSE mailbox. Since these signals - * are received while operating on the KSE stack, they can be - * delivered either by using signalcontext() to add a stack frame - * to the target thread's stack, or by adding them in the thread's - * pending set and having the thread run them down after it - * 2) Delivering signals to threads in other KSEs/KSEGs. - * 3) Delivering signals to threads in critical regions. - * 4) Delivering signals to threads after they change their signal masks. - * - * Methods of delivering signals. - * - * 1) Add a signal frame to the thread's saved context. - * 2) Add the signal to the thread structure, mark the thread as - * having signals to handle, and let the thread run them down - * after it resumes from the KSE scheduler. - * - * Problem with 1). You can't do this to a running thread or a - * thread in a critical region. - * - * Problem with 2). You can't do this to a thread that doesn't - * yield in some way (explicitly enters the scheduler). A thread - * blocked in the kernel or a CPU hungry thread will not see the - * signal without entering the scheduler. - * - * The solution is to use both 1) and 2) to deliver signals: - * - * o Thread in critical region - use 2). When the thread - * leaves the critical region it will check to see if it - * has pending signals and run them down. - * - * o Thread enters scheduler explicitly - use 2). The thread - * can check for pending signals after it returns from the - * the scheduler. - * - * o Thread is running and not current thread - use 2). When the - * thread hits a condition specified by one of the other bullets, - * the signal will be delivered. - * - * o Thread is running and is current thread (e.g., the thread - * has just changed its signal mask and now sees that it has - * pending signals) - just run down the pending signals. - * - * o Thread is swapped out due to quantum expiration - use 1) - * - * o Thread is blocked in kernel - kse_thr_wakeup() and then - * use 1) - */ - -/* - * Rules for selecting threads for signals received: - * - * 1) If the signal is a sychronous signal, it is delivered to - * the generating (current thread). If the thread has the - * signal masked, it is added to the threads pending signal - * set until the thread unmasks it. - * - * 2) A thread in sigwait() where the signal is in the thread's - * waitset. - * - * 3) A thread in sigsuspend() where the signal is not in the - * thread's suspended signal mask. - * - * 4) Any thread (first found/easiest to deliver) that has the - * signal unmasked. - */ - -#ifndef SYSTEM_SCOPE_ONLY - -static void * -sig_daemon(void *arg __unused) -{ - int i; - kse_critical_t crit; - struct timespec ts; - sigset_t set; - struct kse *curkse; - struct pthread *curthread = _get_curthread(); - - DBG_MSG("signal daemon started(%p)\n", curthread); - - curthread->name = strdup("signal thread"); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - - /* - * Daemon thread is a bound thread and we must be created with - * all signals masked - */ -#if 0 - SIGFILLSET(set); - __sys_sigprocmask(SIG_SETMASK, &set, NULL); -#endif - __sys_sigpending(&set); - ts.tv_sec = 0; - ts.tv_nsec = 0; - while (1) { - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - _thr_proc_sigpending = set; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(set, i) != 0) - _thr_sig_dispatch(curkse, i, - NULL /* no siginfo */); - } - ts.tv_sec = 30; - ts.tv_nsec = 0; - curkse->k_kcb->kcb_kmbx.km_flags = - KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = 0; - set = curkse->k_kcb->kcb_kmbx.km_sigscaught; - } - return (0); -} - - -/* Utility function to create signal daemon thread */ -int -_thr_start_sig_daemon(void) -{ - pthread_attr_t attr; - sigset_t sigset, oldset; - - SIGFILLSET(sigset); - _pthread_sigmask(SIG_SETMASK, &sigset, &oldset); - _pthread_attr_init(&attr); - _pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - attr->flags |= THR_SIGNAL_THREAD; - /* sigmask will be inherited */ - if (_pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) - PANIC("can not create signal daemon thread!\n"); - _pthread_attr_destroy(&attr); - _pthread_sigmask(SIG_SETMASK, &oldset, NULL); - return (0); -} - -/* - * This signal handler only delivers asynchronous signals. - * This must be called with upcalls disabled and without - * holding any locks. - */ -void -_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) -{ - struct kse_mailbox *kmbx; - struct pthread *thread; - - DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { - /* - * Setup the target thread to receive the signal: - */ - DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); - KSE_SCHED_LOCK(curkse, thread->kseg); - if ((thread->state == PS_DEAD) || - (thread->state == PS_DEADLOCK) || - THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else if (SIGISMEMBER(thread->sigmask, sig)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else { - kmbx = _thr_sig_add(thread, sig, info); - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - break; - } - } - DBG_MSG("<<< _thr_sig_dispatch\n"); -} - -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static __inline int -sigprop(int sig) -{ - - if (sig > 0 && sig < NSIG) - return (sigproptbl[_SIG_IDX(sig)]); - return (0); -} - -typedef void (*ohandler)(int sig, int code, - struct sigcontext *scp, char *addr, __sighandler_t *catcher); - -void -_thr_sig_handler(int sig, siginfo_t *info, void *ucp_arg) -{ - struct pthread_sigframe psf; - __siginfohandler_t *sigfunc; - struct pthread *curthread; - struct kse *curkse; - ucontext_t *ucp; - struct sigaction act; - int sa_flags, err_save; - - err_save = errno; - ucp = (ucontext_t *)ucp_arg; - - DBG_MSG(">>> _thr_sig_handler(%d)\n", sig); - - curthread = _get_curthread(); - if (curthread == NULL) - PANIC("No current thread.\n"); - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - PANIC("Thread is not system scope.\n"); - if (curthread->flags & THR_FLAGS_EXITING) { - errno = err_save; - return; - } - - curkse = _get_curkse(); - /* - * If thread is in critical region or if thread is on - * the way of state transition, then latch signal into buffer. - */ - if (_kse_in_critical() || THR_IN_CRITICAL(curthread) || - curthread->state != PS_RUNNING) { - DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig); - curthread->siginfo[sig-1] = *info; - curthread->check_pending = 1; - curkse->k_sigseqno++; - SIGADDSET(curthread->sigpend, sig); - /* - * If the kse is on the way to idle itself, but - * we have signal ready, we should prevent it - * to sleep, kernel will latch the wakeup request, - * so kse_release will return from kernel immediately. - */ - if (KSE_IS_IDLE(curkse)) - kse_wakeup(&curkse->k_kcb->kcb_kmbx); - errno = err_save; - return; - } - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - thr_sigframe_save(curthread, &psf); - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - - _kse_critical_enter(); - /* Get a fresh copy of signal mask */ - __sys_sigprocmask(SIG_BLOCK, NULL, &curthread->sigmask); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - if (sa_flags & SA_RESETHAND) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Now invoke real handler */ - if (((__sighandler_t *)sigfunc != SIG_DFL) && - ((__sighandler_t *)sigfunc != SIG_IGN) && - (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { - if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) - (*(sigfunc))(sig, info, ucp); - else { - ((ohandler)(*sigfunc))( - sig, info->si_code, (struct sigcontext *)ucp, - info->si_addr, (__sighandler_t *)sigfunc); - } - } else { - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - else - kill(getpid(), sig); - } -#ifdef NOTYET - else if (sigprop(sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); -#endif - } - } - _kse_critical_enter(); - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - thr_sigframe_restore(curthread, &psf); - - DBG_MSG("<<< _thr_sig_handler(%d)\n", sig); - - errno = err_save; -} - -struct sighandle_info { - __siginfohandler_t *sigfunc; - int sa_flags; - int sig; - siginfo_t *info; - ucontext_t *ucp; -}; - -static void handle_signal(struct pthread *curthread, - struct sighandle_info *shi); -static void handle_signal_altstack(struct pthread *curthread, - struct sighandle_info *shi); - -/* Must be called with signal lock and schedule lock held in order */ -static void -thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, - ucontext_t *ucp) -{ - __siginfohandler_t *sigfunc; - sigset_t sigmask; - int sa_flags; - int onstack; - struct sigaction act; - struct kse *curkse; - struct sighandle_info shi; - - /* - * Invoke the signal handler without going through the scheduler: - */ - DBG_MSG("Got signal %d, calling handler for current thread %p\n", - sig, curthread); - - if (!_kse_in_critical()) - PANIC("thr_sig_invoke_handler without in critical\n"); - curkse = curthread->kse; - /* - * Check that a custom handler is installed and if - * the signal is not blocked: - */ - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - sigmask = curthread->sigmask; - SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); - if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) - SIGADDSET(curthread->sigmask, sig); - if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* - * We are processing buffered signals, synchronize working - * signal mask into kernel. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - onstack = _thr_sigonstack(&sigfunc); - ucp->uc_stack = curthread->sigstk; - ucp->uc_stack.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((onstack) ? SS_ONSTACK : 0); - if (curthread->oldsigmask) { - ucp->uc_sigmask = *(curthread->oldsigmask); - curthread->oldsigmask = NULL; - } else - ucp->uc_sigmask = sigmask; - shi.sigfunc = sigfunc; - shi.sig = sig; - shi.sa_flags = sa_flags; - shi.info = info; - shi.ucp = ucp; - if ((curthread->sigstk.ss_flags & SS_DISABLE) == 0) { - /* Deliver signal on alternative stack */ - if (sa_flags & SA_ONSTACK && !onstack) - handle_signal_altstack(curthread, &shi); - else - handle_signal(curthread, &shi); - } else { - handle_signal(curthread, &shi); - } - - _kse_critical_enter(); - /* Don't trust after critical leave/enter */ - curkse = curthread->kse; - - /* - * Restore the thread's signal mask. - */ - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - - DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); -} - -static void -handle_signal(struct pthread *curthread, struct sighandle_info *shi) -{ - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (shi->sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - if (((__sighandler_t *)shi->sigfunc != SIG_DFL) && - ((__sighandler_t *)shi->sigfunc != SIG_IGN)) { - if ((shi->sa_flags & SA_SIGINFO) != 0 || shi->info == NULL) - (*(shi->sigfunc))(shi->sig, shi->info, shi->ucp); - else { - ((ohandler)(*shi->sigfunc))( - shi->sig, shi->info->si_code, - (struct sigcontext *)shi->ucp, - shi->info->si_addr, - (__sighandler_t *)shi->sigfunc); - } - } else { - if ((__sighandler_t *)shi->sigfunc == SIG_DFL) { - if (sigprop(shi->sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, shi->sig); - else - kill(getpid(), shi->sig); - } -#ifdef NOTYET - else if (sigprop(shi->sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, - shi->sig); -#endif - } - } -} - -static void -handle_signal_wrapper(struct pthread *curthread, ucontext_t *ret_uc, - struct sighandle_info *shi) -{ - shi->ucp->uc_stack.ss_flags = SS_ONSTACK; - handle_signal(curthread, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(ret_uc); - else { - /* Work around for ia64, THR_SETCONTEXT does not work */ - _kse_critical_enter(); - curthread->tcb->tcb_tmbx.tm_context = *ret_uc; - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT */ - } -} - -/* - * Jump to stack set by sigaltstack before invoking signal handler - */ -static void -handle_signal_altstack(struct pthread *curthread, struct sighandle_info *shi) -{ - volatile int once; - ucontext_t uc1, *uc2; - - THR_ASSERT(_kse_in_critical(), "Not in critical"); - - once = 0; - THR_GETCONTEXT(&uc1); - if (once == 0) { - once = 1; - /* XXX - * We are still in critical region, it is safe to operate thread - * context - */ - uc2 = &curthread->tcb->tcb_tmbx.tm_context; - uc2->uc_stack = curthread->sigstk; - makecontext(uc2, (void (*)(void))handle_signal_wrapper, - 3, curthread, &uc1, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(uc2); - else { - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT(uc2); */ - } - } -} - -int -_thr_getprocsig(int sig, siginfo_t *siginfo) -{ - kse_critical_t crit; - struct kse *curkse; - int ret; - - DBG_MSG(">>> _thr_getprocsig\n"); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - ret = _thr_getprocsig_unlocked(sig, siginfo); - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(crit); - - DBG_MSG("<<< _thr_getprocsig\n"); - return (ret); -} - -int -_thr_getprocsig_unlocked(int sig, siginfo_t *siginfo) -{ - sigset_t sigset; - struct timespec ts; - - /* try to retrieve signal from kernel */ - SIGEMPTYSET(sigset); - SIGADDSET(sigset, sig); - ts.tv_sec = 0; - ts.tv_nsec = 0; - SIGDELSET(_thr_proc_sigpending, sig); - if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) - return (sig); - return (0); -} - -#ifndef SYSTEM_SCOPE_ONLY -/* - * Find a thread that can handle the signal. This must be called - * with upcalls disabled. - */ -struct pthread * -thr_sig_find(struct kse *curkse, int sig, siginfo_t *info __unused) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - struct pthread *suspended_thread, *signaled_thread; - __siginfohandler_t *sigfunc; - siginfo_t si; - - DBG_MSG("Looking for thread to handle signal %d\n", sig); - - /* - * Enter a loop to look for threads that have the signal - * unmasked. POSIX specifies that a thread in a sigwait - * will get the signal over any other threads. Second - * preference will be threads in a sigsuspend. Third - * preference will be the current thread. If none of the - * above, then the signal is delivered to the first thread - * that is found. Note that if a custom handler is not - * installed, the signal only affects threads in sigwait. - */ - suspended_thread = NULL; - signaled_thread = NULL; - - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread == _thr_sig_daemon) - continue; - /* Signal delivering to bound thread is done by kernel */ - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - continue; - /* Take the scheduling lock. */ - KSE_SCHED_LOCK(curkse, pthread->kseg); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - THR_IS_EXITING(pthread) || - THR_IS_SUSPENDED(pthread)) { - ; /* Skip this thread. */ - } else if (pthread->state == PS_SIGWAIT && - SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* - * retrieve signal from kernel, if it is job control - * signal, and sigaction is SIG_DFL, then we will - * be stopped in kernel, we hold lock here, but that - * does not matter, because that's job control, and - * whole process should be stopped. - */ - if (_thr_getprocsig(sig, &si)) { - DBG_MSG("Waking thread %p in sigwait" - " with signal %d\n", pthread, sig); - /* where to put siginfo ? */ - *(pthread->data.sigwait->siginfo) = si; - kmbx = _thr_setrunnable_unlocked(pthread); - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - /* - * POSIX doesn't doesn't specify which thread - * will get the signal if there are multiple - * waiters, so we give it to the first thread - * we find. - * - * Do not attempt to deliver this signal - * to other threads and do not add the signal - * to the process pending set. - */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (kmbx != NULL) - kse_wakeup(kmbx); - if (suspended_thread != NULL) - _thr_ref_delete(NULL, suspended_thread); - if (signaled_thread != NULL) - _thr_ref_delete(NULL, signaled_thread); - return (NULL); - } else if (!SIGISMEMBER(pthread->sigmask, sig)) { - /* - * If debugger is running, we don't quick exit, - * and give it a chance to check the signal. - */ - if (_libkse_debug == 0) { - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - } - } - if (pthread->state == PS_SIGSUSPEND) { - if (suspended_thread == NULL) { - suspended_thread = pthread; - suspended_thread->refcount++; - } - } else if (signaled_thread == NULL) { - signaled_thread = pthread; - signaled_thread->refcount++; - } - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - if (suspended_thread != NULL) { - pthread = suspended_thread; - if (signaled_thread) - _thr_ref_delete(NULL, signaled_thread); - } else if (signaled_thread) { - pthread = signaled_thread; - } else { - pthread = NULL; - } - return (pthread); -} -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static inline void -build_siginfo(siginfo_t *info, int signo) -{ - bzero(info, sizeof(*info)); - info->si_signo = signo; - info->si_pid = _thr_pid; -} - -/* - * This is called by a thread when it has pending signals to deliver. - * It should only be called from the context of the thread. - */ -void -_thr_sig_rundown(struct pthread *curthread, ucontext_t *ucp) -{ - struct pthread_sigframe psf; - siginfo_t siginfo; - int i, err_save; - kse_critical_t crit; - struct kse *curkse; - sigset_t sigmask; - - err_save = errno; - - DBG_MSG(">>> thr_sig_rundown (%p)\n", curthread); - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - THR_ASSERT((curthread->state == PS_RUNNING), "state is not PS_RUNNING"); - - thr_sigframe_save(curthread, &psf); - /* - * Lower the priority before calling the handler in case - * it never returns (longjmps back): - */ - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - curthread->active_priority &= ~THR_SIGNAL_PRIORITY; - SIGFILLSET(sigmask); - while (1) { - /* - * For bound thread, we mask all signals and get a fresh - * copy of signal mask from kernel - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - } - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i-1]; - break; - } - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - && SIGISMEMBER(_thr_proc_sigpending, i)) { - if (_thr_getprocsig_unlocked(i, &siginfo)) - break; - } - } - if (i <= _SIG_MAXSIG) - thr_sig_invoke_handler(curthread, i, &siginfo, ucp); - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, - &curthread->sigmask, NULL); - } - break; - } - } - - /* Don't trust after signal handling */ - curkse = curthread->kse; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - /* repost masked signal to kernel, it hardly happens in real world */ - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - !SIGISEMPTY(curthread->sigpend)) { /* dirty read */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - if (!_kse_isthreaded()) - kill(getpid(), i); - else - kse_thr_interrupt( - &curthread->tcb->tcb_tmbx, - KSE_INTR_SENDSIG, - i); - } - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - } - DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread); - - thr_sigframe_restore(curthread, &psf); - errno = err_save; -} - -/* - * This checks pending signals for the current thread. It should be - * called whenever a thread changes its signal mask. Note that this - * is called from a thread (using its stack). - * - * XXX - We might want to just check to see if there are pending - * signals for the thread here, but enter the UTS scheduler - * to actually install the signal handler(s). - */ -void -_thr_sig_check_pending(struct pthread *curthread) -{ - ucontext_t uc; - volatile int once; - int errsave; - - /* - * If the thread is in critical region, delay processing signals. - * If the thread state is not PS_RUNNING, it might be switching - * into UTS and but a THR_LOCK_RELEASE saw check_pending, and it - * goes here, in the case we delay processing signals, lets UTS - * process complicated things, normally UTS will call _thr_sig_add - * to resume the thread, so we needn't repeat doing it here. - */ - if (THR_IN_CRITICAL(curthread) || curthread->state != PS_RUNNING) - return; - - errsave = errno; - once = 0; - THR_GETCONTEXT(&uc); - if (once == 0) { - once = 1; - curthread->check_pending = 0; - _thr_sig_rundown(curthread, &uc); - } - errno = errsave; -} - -/* - * Perform thread specific actions in response to a signal. - * This function is only called if there is a handler installed - * for the signal, and if the target thread has the signal - * unmasked. - * - * This must be called with the thread's scheduling lock held. - */ -struct kse_mailbox * -_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) -{ - siginfo_t siginfo; - struct kse *curkse; - struct kse_mailbox *kmbx = NULL; - struct pthread *curthread = _get_curthread(); - int restart; - int suppress_handler = 0; - int fromproc = 0; - __sighandler_t *sigfunc; - - DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig); - - curkse = _get_curkse(); - restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; - sigfunc = _thread_sigact[sig - 1].sa_handler; - fromproc = (curthread == _thr_sig_daemon); - - if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || - pthread->state == PS_STATE_MAX) - return (NULL); /* return false */ - - if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (curthread != pthread)) { - PANIC("Please use _thr_send_sig for bound thread"); - return (NULL); - } - - if (pthread->state != PS_SIGWAIT && - SIGISMEMBER(pthread->sigmask, sig)) { - /* signal is masked, just add signal to thread. */ - if (!fromproc) { - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - } else { - if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) - return (NULL); - SIGADDSET(pthread->sigpend, sig); - } - } - else { - /* if process signal not exists, just return */ - if (fromproc) { - if (!_thr_getprocsig(sig, &siginfo)) - return (NULL); - info = &siginfo; - } - - if (pthread->state != PS_SIGWAIT && sigfunc == SIG_DFL && - (sigprop(sig) & SA_KILL)) { - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - - /* - * Process according to thread state: - */ - switch (pthread->state) { - case PS_DEAD: - case PS_DEADLOCK: - case PS_STATE_MAX: - return (NULL); /* XXX return false */ - case PS_LOCKWAIT: - case PS_SUSPENDED: - /* - * You can't call a signal handler for threads in these - * states. - */ - suppress_handler = 1; - break; - case PS_RUNNING: - if ((pthread->flags & THR_FLAGS_IN_RUNQ)) { - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - THR_RUNQ_INSERT_TAIL(pthread); - } else { - /* Possible not in RUNQ and has curframe ? */ - pthread->active_priority |= THR_SIGNAL_PRIORITY; - } - break; - /* - * States which cannot be interrupted but still require the - * signal handler to run: - */ - case PS_COND_WAIT: - case PS_MUTEX_WAIT: - break; - - case PS_SLEEP_WAIT: - /* - * Unmasked signals always cause sleep to terminate - * early regardless of SA_RESTART: - */ - pthread->interrupted = 1; - break; - - case PS_JOIN: - break; - - case PS_SIGSUSPEND: - pthread->interrupted = 1; - break; - - case PS_SIGWAIT: - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - /* - * The signal handler is not called for threads in - * SIGWAIT. - */ - suppress_handler = 1; - /* Wake up the thread if the signal is not blocked. */ - if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* Return the signal number: */ - *(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1]; - /* Make the thread runnable: */ - kmbx = _thr_setrunnable_unlocked(pthread); - } else { - /* Increment the pending signal count. */ - SIGADDSET(pthread->sigpend, sig); - if (!SIGISMEMBER(pthread->sigmask, sig)) { - if (sigfunc == SIG_DFL && - sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, - sig); - /* Never reach */ - } - pthread->check_pending = 1; - pthread->interrupted = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - return (kmbx); - } - - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, sizeof(*info)); - pthread->check_pending = 1; - if (!(pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (pthread->blocked != 0) && !THR_IN_CRITICAL(pthread)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - if (suppress_handler == 0) { - /* - * Setup a signal frame and save the current threads - * state: - */ - if (pthread->state != PS_RUNNING) { - if (pthread->flags & THR_FLAGS_IN_RUNQ) - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - } - return (kmbx); -} - -/* - * Send a signal to a specific thread (ala pthread_kill): - */ -void -_thr_sig_send(struct pthread *pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, KSE_INTR_SENDSIG, sig); - return; - } - - /* Lock the scheduling queue of the target thread. */ - THR_SCHED_LOCK(curthread, pthread); - if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { - kmbx = _thr_sig_add(pthread, sig, NULL); - /* Add a preemption point. */ - if (kmbx == NULL && (curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - /* XXX - * If thread sent signal to itself, check signals now. - * It is not really needed, _kse_critical_leave should - * have already checked signals. - */ - if (pthread == curthread && curthread->check_pending) - _thr_sig_check_pending(curthread); - - } else { - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -static inline void -thr_sigframe_restore(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - curthread->cancelflags = psf->psf_cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - curthread->flags = psf->psf_flags; - curthread->interrupted = psf->psf_interrupted; - curthread->timeout = psf->psf_timeout; - curthread->data = psf->psf_wait_data; - curthread->wakeup_time = psf->psf_wakeup_time; - curthread->continuation = psf->psf_continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -static inline void -thr_sigframe_save(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - psf->psf_cancelflags = curthread->cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - /* This has to initialize all members of the sigframe. */ - psf->psf_flags = (curthread->flags & (THR_FLAGS_PRIVATE | THR_FLAGS_EXITING)); - psf->psf_interrupted = curthread->interrupted; - psf->psf_timeout = curthread->timeout; - psf->psf_wait_data = curthread->data; - psf->psf_wakeup_time = curthread->wakeup_time; - psf->psf_continuation = curthread->continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -void -_thr_signal_init(void) -{ - struct sigaction act; - __siginfohandler_t *sigfunc; - int i; - sigset_t sigset; - - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Get the signal handler details: */ - if (__sys_sigaction(i, NULL, &_thread_sigact[i - 1]) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot read signal handler info"); - } - /* Intall wrapper if handler was set */ - sigfunc = _thread_sigact[i - 1].sa_sigaction; - if (((__sighandler_t *)sigfunc) != SIG_DFL && - ((__sighandler_t *)sigfunc) != SIG_IGN) { - act = _thread_sigact[i - 1]; - act.sa_flags |= SA_SIGINFO; - act.sa_sigaction = - (__siginfohandler_t *)_thr_sig_handler; - __sys_sigaction(i, &act, NULL); - } - } - if (_thr_dump_enabled()) { - /* - * Install the signal handler for SIGINFO. It isn't - * really needed, but it is nice to have for debugging - * purposes. - */ - _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; - SIGEMPTYSET(act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_RESTART; - act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; - if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - /* - * Abort this process if signal initialisation fails: - */ - PANIC("Cannot initialize signal handler"); - } - } - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); - __sys_sigaltstack(NULL, &_thr_initial->sigstk); -} - -void -_thr_signal_deinit(void) -{ - int i; - struct pthread *curthread = _get_curthread(); - - /* Clear process pending signals. */ - sigemptyset(&_thr_proc_sigpending); - - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Check for signals which cannot be trapped: */ - if (i == SIGKILL || i == SIGSTOP) { - } - - /* Set the signal handler details: */ - else if (__sys_sigaction(i, &_thread_sigact[i - 1], - NULL) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot set signal handler info"); - } - } - __sys_sigaltstack(&curthread->sigstk, NULL); -} - diff --git a/lib/libkse/thread/thr_sigaction.c b/lib/libkse/thread/thr_sigaction.c deleted file mode 100644 index dda1c35..0000000 --- a/lib/libkse/thread/thr_sigaction.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_sigaction, sigaction); - -int -_sigaction(int sig, const struct sigaction * act, struct sigaction * oact) -{ - int ret = 0; - int err = 0; - struct sigaction newact, oldact; - struct pthread *curthread; - kse_critical_t crit; - - /* Check if the signal number is out of range: */ - if (sig < 1 || sig > _SIG_MAXSIG) { - /* Return an invalid argument: */ - errno = EINVAL; - ret = -1; - } else { - if (act) - newact = *act; - - crit = _kse_critical_enter(); - curthread = _get_curthread(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - - oldact = _thread_sigact[sig - 1]; - - /* Check if a signal action was supplied: */ - if (act != NULL) { - /* Set the new signal handler: */ - _thread_sigact[sig - 1] = newact; - } - - /* - * Check if the kernel needs to be advised of a change - * in signal action: - */ - if (act != NULL) { - - newact.sa_flags |= SA_SIGINFO; - - /* - * Check if the signal handler is being set to - * the default or ignore handlers: - */ - if (newact.sa_handler != SIG_DFL && - newact.sa_handler != SIG_IGN) { - /* - * Specify the thread kernel signal - * handler: - */ - newact.sa_sigaction = _thr_sig_handler; - } - /* - * Install libpthread signal handler wrapper - * for SIGINFO signal if threads dump enabled - * even if a user set the signal handler to - * SIG_DFL or SIG_IGN. - */ - if (sig == SIGINFO && _thr_dump_enabled()) { - newact.sa_sigaction = _thr_sig_handler; - } - /* Change the signal action in the kernel: */ - if (__sys_sigaction(sig, &newact, NULL) != 0) { - _thread_sigact[sig - 1] = oldact; - /* errno is in kse, will copy it to thread */ - err = errno; - ret = -1; - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - /* - * Check if the existing signal action structure contents are - * to be returned: - */ - if (oact != NULL) { - /* Return the existing signal action contents: */ - *oact = oldact; - } - if (ret != 0) { - /* Return errno to thread */ - errno = err; - } - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_sigaltstack.c b/lib/libkse/thread/thr_sigaltstack.c deleted file mode 100644 index 629f5b0..0000000 --- a/lib/libkse/thread/thr_sigaltstack.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <errno.h> -#include <signal.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _sigaltstack(stack_t *_ss, stack_t *_oss); - -__weak_reference(_sigaltstack, sigaltstack); - -int -_sigaltstack(stack_t *_ss, stack_t *_oss) -{ - struct pthread *curthread = _get_curthread(); - stack_t ss, oss; - int oonstack, errsave, ret; - kse_critical_t crit; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - crit = _kse_critical_enter(); - ret = __sys_sigaltstack(_ss, _oss); - errsave = errno; - /* Get a copy */ - if (ret == 0 && _ss != NULL) - curthread->sigstk = *_ss; - _kse_critical_leave(crit); - errno = errsave; - return (ret); - } - - if (_ss) - ss = *_ss; - if (_oss) - oss = *_oss; - - /* Should get and set stack in atomic way */ - crit = _kse_critical_enter(); - oonstack = _thr_sigonstack(&ss); - if (_oss != NULL) { - oss = curthread->sigstk; - oss.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((oonstack) ? SS_ONSTACK : 0); - } - - if (_ss != NULL) { - if (oonstack) { - _kse_critical_leave(crit); - errno = EPERM; - return (-1); - } - if ((ss.ss_flags & ~SS_DISABLE) != 0) { - _kse_critical_leave(crit); - errno = EINVAL; - return (-1); - } - if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < MINSIGSTKSZ) { - _kse_critical_leave(crit); - errno = ENOMEM; - return (-1); - } - curthread->sigstk = ss; - } else { - curthread->sigstk.ss_flags |= SS_DISABLE; - } - } - _kse_critical_leave(crit); - if (_oss != NULL) - *_oss = oss; - return (0); -} - -int -_thr_sigonstack(void *sp) -{ - struct pthread *curthread = _get_curthread(); - - return ((curthread->sigstk.ss_flags & SS_DISABLE) == 0 ? - (((size_t)sp - (size_t)curthread->sigstk.ss_sp) < curthread->sigstk.ss_size) - : 0); -} - diff --git a/lib/libkse/thread/thr_sigmask.c b/lib/libkse/thread/thr_sigmask.c deleted file mode 100644 index 4a9fdea..0000000 --- a/lib/libkse/thread/thr_sigmask.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_sigmask, pthread_sigmask); - -int -_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldset, newset; - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - ret = __sys_sigprocmask(how, set, oset); - if (ret != 0) - ret = errno; - /* Get a fresh copy */ - __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); - return (ret); - } - - if (set) - newset = *set; - - THR_SCHED_LOCK(curthread, curthread); - - ret = 0; - if (oset != NULL) - /* Return the current mask: */ - oldset = curthread->sigmask; - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - /* Process according to what to do: */ - switch (how) { - /* Block signals: */ - case SIG_BLOCK: - /* Add signals to the existing mask: */ - SIGSETOR(curthread->sigmask, newset); - break; - - /* Unblock signals: */ - case SIG_UNBLOCK: - /* Clear signals from the existing mask: */ - SIGSETNAND(curthread->sigmask, newset); - break; - - /* Set the signal process mask: */ - case SIG_SETMASK: - /* Set the new mask: */ - curthread->sigmask = newset; - break; - - /* Trap invalid actions: */ - default: - /* Return an invalid argument: */ - ret = EINVAL; - break; - } - SIG_CANTMASK(curthread->sigmask); - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * Run down any pending signals: - */ - if (ret == 0) - _thr_sig_check_pending(curthread); - } else - THR_SCHED_UNLOCK(curthread, curthread); - - if (ret == 0 && oset != NULL) - *oset = oldset; - return (ret); -} diff --git a/lib/libkse/thread/thr_sigpending.c b/lib/libkse/thread/thr_sigpending.c deleted file mode 100644 index f0183e7..0000000 --- a/lib/libkse/thread/thr_sigpending.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _sigpending(sigset_t *set); - -__weak_reference(_sigpending, sigpending); - -int -_sigpending(sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - sigset_t sigset; - int ret = 0; - - /* Check for a null signal set pointer: */ - if (set == NULL) { - /* Return an invalid argument: */ - ret = EINVAL; - } - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigpending(set)); - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - sigset = curthread->sigpend; - KSE_SCHED_UNLOCK(curthread->kse, curthread->kseg); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - SIGSETOR(sigset, _thr_proc_sigpending); - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - *set = sigset; - } - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_sigprocmask.c b/lib/libkse/thread/thr_sigprocmask.c deleted file mode 100644 index 45fa5e2..0000000 --- a/lib/libkse/thread/thr_sigprocmask.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_sigprocmask, sigprocmask); - -int -_sigprocmask(int how, const sigset_t *set, sigset_t *oset) -{ - int ret; - - ret = _pthread_sigmask(how, set, oset); - if (ret) { - errno = ret; - ret = -1; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_sigsuspend.c b/lib/libkse/thread/thr_sigsuspend.c deleted file mode 100644 index a6ef350..0000000 --- a/lib/libkse/thread/thr_sigsuspend.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <string.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __sigsuspend(const sigset_t * set); - -__weak_reference(__sigsuspend, sigsuspend); - -int -_sigsuspend(const sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldmask, newmask, tempset; - int ret = -1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigsuspend(set)); - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - newmask = *set; - SIG_CANTMASK(newmask); - THR_LOCK_SWITCH(curthread); - - /* Save current sigmask: */ - oldmask = curthread->sigmask; - curthread->oldsigmask = &oldmask; - - /* Change the caller's mask: */ - curthread->sigmask = newmask; - tempset = curthread->sigpend; - SIGSETNAND(tempset, newmask); - if (SIGISEMPTY(tempset)) { - THR_SET_STATE(curthread, PS_SIGSUSPEND); - /* Wait for a signal: */ - _thr_sched_switch_unlocked(curthread); - } else { - curthread->check_pending = 1; - THR_UNLOCK_SWITCH(curthread); - /* check pending signal I can handle: */ - _thr_sig_check_pending(curthread); - } - if ((curthread->cancelflags & THR_CANCELLING) != 0) - curthread->oldsigmask = NULL; - else { - THR_ASSERT(curthread->oldsigmask == NULL, - "oldsigmask is not cleared"); - } - - /* Always return an interrupted error: */ - errno = EINTR; - } else { - /* Return an invalid argument error: */ - errno = EINVAL; - } - - /* Return the completion status: */ - return (ret); -} - -int -__sigsuspend(const sigset_t * set) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _sigsuspend(set); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_sigwait.c b/lib/libkse/thread/thr_sigwait.c deleted file mode 100644 index a9cdafa..0000000 --- a/lib/libkse/thread/thr_sigwait.c +++ /dev/null @@ -1,210 +0,0 @@ -//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <signal.h> -#include <sys/param.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout); -int __sigwaitinfo(const sigset_t *set, siginfo_t *info); -int __sigwait(const sigset_t *set, int *sig); -int _sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout); -int _sigwaitinfo(const sigset_t *set, siginfo_t *info); -int _sigwait(const sigset_t *set, int *sig); - -__weak_reference(__sigwait, sigwait); -__weak_reference(__sigtimedwait, sigtimedwait); -__weak_reference(__sigwaitinfo, sigwaitinfo); - -static int -lib_sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - int i; - struct sigwait_data waitdata; - sigset_t waitset; - kse_critical_t crit; - siginfo_t siginfo; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - if (info == NULL) - info = &siginfo; - return (__sys_sigtimedwait(set, info, timeout)); - } - - /* - * Initialize the set of signals that will be waited on: - */ - waitset = *set; - - /* These signals can't be waited on. */ - SIGDELSET(waitset, SIGKILL); - SIGDELSET(waitset, SIGSTOP); - - /* - * POSIX says that the _application_ must explicitly install - * a dummy handler for signals that are SIG_IGN in order - * to sigwait on them. Note that SIG_IGN signals are left in - * the mask because a subsequent sigaction could enable an - * ignored signal. - */ - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(waitset, i) && - SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i - 1]; - KSE_SCHED_UNLOCK(curthread->kse, - curthread->kseg); - _kse_critical_leave(crit); - ret = i; - goto OUT; - } - } - curthread->timeout = 0; - curthread->interrupted = 0; - _thr_set_timeout(timeout); - /* Wait for a signal: */ - siginfo.si_signo = 0; - waitdata.waitset = &waitset; - waitdata.siginfo = &siginfo; - curthread->data.sigwait = &waitdata; - THR_SET_STATE(curthread, PS_SIGWAIT); - _thr_sched_switch_unlocked(curthread); - /* - * Return the signal number to the caller: - */ - if (siginfo.si_signo > 0) { - ret = siginfo.si_signo; - } else { - if (curthread->interrupted) - errno = EINTR; - else if (curthread->timeout) - errno = EAGAIN; - ret = -1; - } - curthread->timeout = 0; - curthread->interrupted = 0; - /* - * Probably unnecessary, but since it's in a union struct - * we don't know how it could be used in the future. - */ - curthread->data.sigwait = NULL; - -OUT: - if (ret > 0 && info != NULL) - *info = siginfo; - - return (ret); -} - -int -__sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, timeout); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int _sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - return lib_sigtimedwait(set, info, timeout); -} - -int -__sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, NULL); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - return lib_sigtimedwait(set, info, NULL); -} - -int -__sigwait(const sigset_t *set, int *sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwait(const sigset_t *set, int *sig) -{ - int ret; - - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - return (ret); -} - diff --git a/lib/libkse/thread/thr_single_np.c b/lib/libkse/thread/thr_single_np.c deleted file mode 100644 index 8f004e9..0000000 --- a/lib/libkse/thread/thr_single_np.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_single_np(void); - -__weak_reference(_pthread_single_np, pthread_single_np); - -int _pthread_single_np(void) -{ - - /* Enter single-threaded (non-POSIX) scheduling mode: */ - _pthread_suspend_all_np(); - /* - * XXX - Do we want to do this? - * __is_threaded = 0; - */ - return (0); -} diff --git a/lib/libkse/thread/thr_sleep.c b/lib/libkse/thread/thr_sleep.c deleted file mode 100644 index ffa76b2..0000000 --- a/lib/libkse/thread/thr_sleep.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -extern unsigned int __sleep(unsigned int); -extern int __usleep(useconds_t); - -unsigned int _sleep(unsigned int seconds); - -__weak_reference(_sleep, sleep); -__weak_reference(_usleep, usleep); - -unsigned int -_sleep(unsigned int seconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __sleep(seconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} - -int -_usleep(useconds_t useconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __usleep(useconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_spec.c b/lib/libkse/thread/thr_spec.c deleted file mode 100644 index 1d4be45..0000000 --- a/lib/libkse/thread/thr_spec.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - - -struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX]; - -__weak_reference(_pthread_key_create, pthread_key_create); -__weak_reference(_pthread_key_delete, pthread_key_delete); -__weak_reference(_pthread_getspecific, pthread_getspecific); -__weak_reference(_pthread_setspecific, pthread_setspecific); - - -int -_pthread_key_create(pthread_key_t *key, void (*destructor) (void *)) -{ - struct pthread *curthread; - int i; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; i < PTHREAD_KEYS_MAX; i++) { - - if (_thread_keytable[i].allocated == 0) { - _thread_keytable[i].allocated = 1; - _thread_keytable[i].destructor = destructor; - _thread_keytable[i].seqno++; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - *key = i; - return (0); - } - - } - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - return (EAGAIN); -} - -int -_pthread_key_delete(pthread_key_t key) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - - if (_thread_keytable[key].allocated) - _thread_keytable[key].allocated = 0; - else - ret = EINVAL; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - } else - ret = EINVAL; - return (ret); -} - -void -_thread_cleanupspecific(void) -{ - struct pthread *curthread = _get_curthread(); - const_key_destructor_t destructor; - const void *data = NULL; - int key; - int i; - - if (curthread->specific == NULL) - return; - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) && - (curthread->specific_data_count > 0); i++) { - for (key = 0; (key < PTHREAD_KEYS_MAX) && - (curthread->specific_data_count > 0); key++) { - destructor = NULL; - - if (_thread_keytable[key].allocated && - (curthread->specific[key].data != NULL)) { - if (curthread->specific[key].seqno == - _thread_keytable[key].seqno) { - data = curthread->specific[key].data; - destructor = (const_key_destructor_t) - _thread_keytable[key].destructor; - } - curthread->specific[key].data = NULL; - curthread->specific_data_count--; - } - - /* - * If there is a destructore, call it - * with the key table entry unlocked: - */ - if (destructor != NULL) { - /* - * Don't hold the lock while calling the - * destructor: - */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - destructor(data); - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - } - } - } - THR_LOCK_RELEASE(curthread, &_keytable_lock); - free(curthread->specific); - curthread->specific = NULL; - if (curthread->specific_data_count > 0) - stderr_debug("Thread %p has exited with leftover " - "thread-specific data after %d destructor iterations\n", - curthread, PTHREAD_DESTRUCTOR_ITERATIONS); -} - -static inline struct pthread_specific_elem * -pthread_key_allocate_data(void) -{ - struct pthread_specific_elem *new_data; - - new_data = (struct pthread_specific_elem *) - malloc(sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - if (new_data != NULL) { - memset((void *) new_data, 0, - sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - } - return (new_data); -} - -int -_pthread_setspecific(pthread_key_t key, const void *value) -{ - struct pthread *pthread; - int ret = 0; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - if ((pthread->specific) || - (pthread->specific = pthread_key_allocate_data())) { - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - if (_thread_keytable[key].allocated) { - if (pthread->specific[key].data == NULL) { - if (value != NULL) - pthread->specific_data_count++; - } else if (value == NULL) - pthread->specific_data_count--; - *(const void **)&pthread->specific[key].data = value; - pthread->specific[key].seqno = - _thread_keytable[key].seqno; - ret = 0; - } else - ret = EINVAL; - } else - ret = EINVAL; - } else - ret = ENOMEM; - return (ret); -} - -void * -_pthread_getspecific(pthread_key_t key) -{ - struct pthread *pthread; - void *data; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - /* Check if there is specific data: */ - if (pthread->specific != NULL && (unsigned int)key < PTHREAD_KEYS_MAX) { - /* Check if this key has been used before: */ - if (_thread_keytable[key].allocated && - (pthread->specific[key].seqno == _thread_keytable[key].seqno)) { - /* Return the value: */ - data = pthread->specific[key].data; - } else { - /* - * This key has not been used before, so return NULL - * instead: - */ - data = NULL; - } - } else - /* No specific data has been created, so just return NULL: */ - data = NULL; - return (data); -} diff --git a/lib/libkse/thread/thr_spinlock.c b/lib/libkse/thread/thr_spinlock.c deleted file mode 100644 index 685301f..0000000 --- a/lib/libkse/thread/thr_spinlock.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <machine/atomic.h> -#include <pthread.h> -#include <libc_private.h> -#include "un-namespace.h" -#include "spinlock.h" -#include "thr_private.h" - -#define MAX_SPINLOCKS 72 - -struct spinlock_extra { - spinlock_t *owner; - pthread_mutex_t lock; -}; - -struct nv_spinlock { - long access_lock; - long lock_owner; - struct spinlock_extra *extra; /* overlays fname in spinlock_t */ - int lineno; -}; -typedef struct nv_spinlock nv_spinlock_t; - -static void init_spinlock(spinlock_t *lck); - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -static pthread_mutex_t spinlock_static_lock; -static struct spinlock_extra extra[MAX_SPINLOCKS]; -static int spinlock_count = 0; -static int initialized = 0; - -/* - * These are for compatability only. Spinlocks of this type - * are deprecated. - */ - -void -_spinunlock(spinlock_t *lck) -{ - struct spinlock_extra *sl_extra; - - sl_extra = ((nv_spinlock_t *)lck)->extra; - _pthread_mutex_unlock(&sl_extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - */ -void -_spinlock(spinlock_t *lck) -{ - struct spinlock_extra *sl_extra; - - if (!__isthreaded) - PANIC("Spinlock called when not threaded."); - if (!initialized) - PANIC("Spinlocks not initialized."); - /* - * Try to grab the lock and loop if another thread grabs - * it before we do. - */ - if (lck->fname == NULL) - init_spinlock(lck); - sl_extra = ((nv_spinlock_t *)lck)->extra; - _pthread_mutex_lock(&sl_extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - * - * This function checks if the running thread has already locked the - * location, warns if this occurs and creates a thread dump before - * returning. - */ -void -_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused) -{ - _spinlock(lck); -} - -static void -init_spinlock(spinlock_t *lck) -{ - _pthread_mutex_lock(&spinlock_static_lock); - if ((lck->fname == NULL) && (spinlock_count < MAX_SPINLOCKS)) { - lck->fname = (char *)&extra[spinlock_count]; - extra[spinlock_count].owner = lck; - spinlock_count++; - } - _pthread_mutex_unlock(&spinlock_static_lock); - if (lck->fname == NULL) - PANIC("Exceeded max spinlocks"); -} - -void -_thr_spinlock_init(void) -{ - int i; - - if (initialized != 0) { - _thr_mutex_reinit(&spinlock_static_lock); - for (i = 0; i < spinlock_count; i++) - _thr_mutex_reinit(&extra[i].lock); - } else { - if (_pthread_mutex_init(&spinlock_static_lock, &static_mattr)) - PANIC("Cannot initialize spinlock_static_lock"); - for (i = 0; i < MAX_SPINLOCKS; i++) { - if (_pthread_mutex_init(&extra[i].lock, &static_mattr)) - PANIC("Cannot initialize spinlock extra"); - } - initialized = 1; - } -} diff --git a/lib/libkse/thread/thr_stack.c b/lib/libkse/thread/thr_stack.c deleted file mode 100644 index 6309e29..0000000 --- a/lib/libkse/thread/thr_stack.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 2000-2001 Jason Evans <jasone@freebsd.org> - * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/queue.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Spare thread stack. */ -struct stack { - LIST_ENTRY(stack) qe; /* Stack queue linkage. */ - size_t stacksize; /* Stack size (rounded up). */ - size_t guardsize; /* Guard size. */ - void *stackaddr; /* Stack address. */ -}; - -/* - * Default sized (stack and guard) spare stack queue. Stacks are cached - * to avoid additional complexity managing mmap()ed stack regions. Spare - * stacks are used in LIFO order to increase cache locality. - */ -static LIST_HEAD(, stack) dstackq = LIST_HEAD_INITIALIZER(dstackq); - -/* - * Miscellaneous sized (non-default stack and/or guard) spare stack queue. - * Stacks are cached to avoid additional complexity managing mmap()ed - * stack regions. This list is unordered, since ordering on both stack - * size and guard size would be more trouble than it's worth. Stacks are - * allocated from this cache on a first size match basis. - */ -static LIST_HEAD(, stack) mstackq = LIST_HEAD_INITIALIZER(mstackq); - -/** - * Base address of the last stack allocated (including its red zone, if - * there is one). Stacks are allocated contiguously, starting beyond the - * top of the main stack. When a new stack is created, a red zone is - * typically created (actually, the red zone is mapped with PROT_NONE) above - * the top of the stack, such that the stack will not be able to grow all - * the way to the bottom of the next stack. This isn't fool-proof. It is - * possible for a stack to grow by a large amount, such that it grows into - * the next stack, and as long as the memory within the red zone is never - * accessed, nothing will prevent one thread stack from trouncing all over - * the next. - * - * low memory - * . . . . . . . . . . . . . . . . . . - * | | - * | stack 3 | start of 3rd thread stack - * +-----------------------------------+ - * | | - * | Red Zone (guard page) | red zone for 2nd thread - * | | - * +-----------------------------------+ - * | stack 2 - PTHREAD_STACK_DEFAULT | top of 2nd thread stack - * | | - * | | - * | | - * | | - * | stack 2 | - * +-----------------------------------+ <-- start of 2nd thread stack - * | | - * | Red Zone | red zone for 1st thread - * | | - * +-----------------------------------+ - * | stack 1 - PTHREAD_STACK_DEFAULT | top of 1st thread stack - * | | - * | | - * | | - * | | - * | stack 1 | - * +-----------------------------------+ <-- start of 1st thread stack - * | | (initial value of last_stack) - * | Red Zone | - * | | red zone for main thread - * +-----------------------------------+ - * | USRSTACK - PTHREAD_STACK_INITIAL | top of main thread stack - * | | ^ - * | | | - * | | | - * | | | stack growth - * | | - * +-----------------------------------+ <-- start of main thread stack - * (USRSTACK) - * high memory - * - */ -static void *last_stack = NULL; - -/* - * Round size up to the nearest multiple of - * _thr_page_size. - */ -static inline size_t -round_up(size_t size) -{ - if (size % _thr_page_size != 0) - size = ((size / _thr_page_size) + 1) * - _thr_page_size; - return (size); -} - -int -_thr_stack_alloc(struct pthread_attr *attr) -{ - struct stack *spare_stack; - struct kse *curkse; - kse_critical_t crit; - size_t stacksize; - size_t guardsize; - char *stackaddr; - - /* - * Round up stack size to nearest multiple of _thr_page_size so - * that mmap() * will work. If the stack size is not an even - * multiple, we end up initializing things such that there is - * unused space above the beginning of the stack, so the stack - * sits snugly against its guard. - */ - stacksize = round_up(attr->stacksize_attr); - guardsize = round_up(attr->guardsize_attr); - - attr->stackaddr_attr = NULL; - attr->flags &= ~THR_STACK_USER; - - /* - * Use the garbage collector lock for synchronization of the - * spare stack lists and allocations from usrstack. - */ - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * If the stack and guard sizes are default, try to allocate a stack - * from the default-size stack cache: - */ - if ((stacksize == _thr_stack_default) && - (guardsize == _thr_guard_default)) { - if ((spare_stack = LIST_FIRST(&dstackq)) != NULL) { - /* Use the spare stack. */ - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - } - } - /* - * The user specified a non-default stack and/or guard size, so try to - * allocate a stack from the non-default size stack cache, using the - * rounded up stack size (stack_size) in the search: - */ - else { - LIST_FOREACH(spare_stack, &mstackq, qe) { - if (spare_stack->stacksize == stacksize && - spare_stack->guardsize == guardsize) { - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - break; - } - } - } - if (attr->stackaddr_attr != NULL) { - /* A cached stack was found. Release the lock. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } - else { - /* Allocate a stack from usrstack. */ - if (last_stack == NULL) - last_stack = (void *)((uintptr_t)_usrstack - - (uintptr_t)_thr_stack_initial - - (uintptr_t)_thr_guard_default); - - /* Allocate a new stack. */ - stackaddr = (void *)((uintptr_t)last_stack - - (uintptr_t)stacksize - (uintptr_t)guardsize); - - /* - * Even if stack allocation fails, we don't want to try to - * use this location again, so unconditionally decrement - * last_stack. Under normal operating conditions, the most - * likely reason for an mmap() error is a stack overflow of - * the adjacent thread stack. - */ - last_stack = (void *)((uintptr_t)last_stack - - (uintptr_t)(stacksize + guardsize)); - - /* Release the lock before mmap'ing it. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Map the stack and guard page together, and split guard - page from allocated space: */ - if ((stackaddr = mmap(stackaddr, stacksize+guardsize, - PROT_READ | PROT_WRITE, MAP_STACK, - -1, 0)) != MAP_FAILED && - (guardsize == 0 || - mprotect(stackaddr, guardsize, PROT_NONE) == 0)) { - stackaddr += guardsize; - } else { - if (stackaddr != MAP_FAILED) - munmap(stackaddr, stacksize + guardsize); - stackaddr = NULL; - } - attr->stackaddr_attr = stackaddr; - } - if (attr->stackaddr_attr != NULL) - return (0); - else - return (-1); -} - -/* This function must be called with _thread_list_lock held. */ -void -_thr_stack_free(struct pthread_attr *attr) -{ - struct stack *spare_stack; - - if ((attr != NULL) && ((attr->flags & THR_STACK_USER) == 0) - && (attr->stackaddr_attr != NULL)) { - spare_stack = (struct stack *)((uintptr_t)attr->stackaddr_attr - + (uintptr_t)attr->stacksize_attr - sizeof(struct stack)); - spare_stack->stacksize = round_up(attr->stacksize_attr); - spare_stack->guardsize = round_up(attr->guardsize_attr); - spare_stack->stackaddr = attr->stackaddr_attr; - - if (spare_stack->stacksize == _thr_stack_default && - spare_stack->guardsize == _thr_guard_default) { - /* Default stack/guard size. */ - LIST_INSERT_HEAD(&dstackq, spare_stack, qe); - } else { - /* Non-default stack/guard size. */ - LIST_INSERT_HEAD(&mstackq, spare_stack, qe); - } - attr->stackaddr_attr = NULL; - } -} diff --git a/lib/libkse/thread/thr_suspend_np.c b/lib/libkse/thread/thr_suspend_np.c deleted file mode 100644 index 99af59c..0000000 --- a/lib/libkse/thread/thr_suspend_np.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_suspend_np(pthread_t thread); -void _pthread_suspend_all_np(void); - -static void suspend_common(struct pthread *thread); - -__weak_reference(_pthread_suspend_np, pthread_suspend_np); -__weak_reference(_pthread_suspend_all_np, pthread_suspend_all_np); - -/* Suspend a thread: */ -int -_pthread_suspend_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Suspending the current thread doesn't make sense. */ - if (thread == _get_curthread()) - ret = EDEADLK; - - /* Add a reference to the thread: */ - else if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) - == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, thread); - - /* Don't forget to remove the reference: */ - _thr_ref_delete(curthread, thread); - } - return (ret); -} - -void -_pthread_suspend_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -suspend_common(struct pthread *thread) -{ - if ((thread->state != PS_DEAD) && - (thread->state != PS_DEADLOCK) && - ((thread->flags & THR_FLAGS_EXITING) == 0)) { - thread->flags |= THR_FLAGS_SUSPENDED; - if ((thread->flags & THR_FLAGS_IN_RUNQ) != 0) { - THR_RUNQ_REMOVE(thread); - THR_SET_STATE(thread, PS_SUSPENDED); - } -#ifdef NOT_YET - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) - /* ??? */ -#endif - } -} diff --git a/lib/libkse/thread/thr_switch_np.c b/lib/libkse/thread/thr_switch_np.c deleted file mode 100644 index 058a3bb..0000000 --- a/lib/libkse/thread/thr_switch_np.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_switch_add_np, pthread_switch_add_np); -__weak_reference(_pthread_switch_delete_np, pthread_switch_delete_np); - -int -_pthread_switch_add_np(pthread_switch_routine_t routine __unused) -{ - return (ENOTSUP); -} - -int -_pthread_switch_delete_np(pthread_switch_routine_t routine __unused) -{ - return (ENOTSUP); -} diff --git a/lib/libkse/thread/thr_symbols.c b/lib/libkse/thread/thr_symbols.c deleted file mode 100644 index f48cc0f..0000000 --- a/lib/libkse/thread/thr_symbols.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004 David Xu <davidxu@freebsd.org> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <stddef.h> -#include <pthread.h> -#include <rtld.h> -#include "un-namespace.h" - -#include "thr_private.h" - -/* A collection of symbols needed by debugger */ - -/* int _libkse_debug */ -int _thread_off_tcb = offsetof(struct pthread, tcb); -int _thread_off_tmbx = offsetof(struct tcb, tcb_tmbx); -int _thread_off_next = offsetof(struct pthread, tle.tqe_next); -int _thread_off_attr_flags = offsetof(struct pthread, attr.flags); -int _thread_off_kse = offsetof(struct pthread, kse); -int _thread_off_kse_locklevel = offsetof(struct kse, k_locklevel); -int _thread_off_thr_locklevel = offsetof(struct pthread, locklevel); -int _thread_off_linkmap = offsetof(Obj_Entry, linkmap); -int _thread_off_tlsindex = offsetof(Obj_Entry, tlsindex); -int _thread_size_key = sizeof(struct pthread_key); -int _thread_off_key_allocated = offsetof(struct pthread_key, allocated); -int _thread_off_key_destructor = offsetof(struct pthread_key, destructor); -int _thread_max_keys = PTHREAD_KEYS_MAX; -int _thread_off_dtv = DTV_OFFSET; -int _thread_off_state = offsetof(struct pthread, state); -int _thread_state_running = PS_RUNNING; -int _thread_state_zoombie = PS_DEAD; -int _thread_off_sigmask = offsetof(struct pthread, sigmask); -int _thread_off_sigpend = offsetof(struct pthread, sigpend); diff --git a/lib/libkse/thread/thr_system.c b/lib/libkse/thread/thr_system.c deleted file mode 100644 index 5dbe426..0000000 --- a/lib/libkse/thread/thr_system.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _system(const char *string); - -extern int __system(const char *); - -__weak_reference(_system, system); - -int -_system(const char *string) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __system(string); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_tcdrain.c b/lib/libkse/thread/thr_tcdrain.c deleted file mode 100644 index 55a403d..0000000 --- a/lib/libkse/thread/thr_tcdrain.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <termios.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _tcdrain(int fd); -extern int __tcdrain(int); - -__weak_reference(_tcdrain, tcdrain); - -int -_tcdrain(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __tcdrain(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_vfork.c b/lib/libkse/thread/thr_vfork.c deleted file mode 100644 index 4b22b1e..0000000 --- a/lib/libkse/thread/thr_vfork.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * $FreeBSD$ - */ - -#include <unistd.h> -#include "thr_private.h" - -int _vfork(void); - -__weak_reference(_vfork, vfork); - -int -_vfork(void) -{ - return (fork()); -} diff --git a/lib/libkse/thread/thr_wait.c b/lib/libkse/thread/thr_wait.c deleted file mode 100644 index e3f40bc..0000000 --- a/lib/libkse/thread/thr_wait.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <pthread.h> -#include "thr_private.h" - -extern int __wait(int *); - -pid_t _wait(int *istat); - -__weak_reference(_wait, wait); - -pid_t -_wait(int *istat) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __wait(istat); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_wait4.c b/lib/libkse/thread/thr_wait4.c deleted file mode 100644 index d92366a..0000000 --- a/lib/libkse/thread/thr_wait4.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <errno.h> -#include <sys/wait.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -pid_t __wait4(pid_t pid, int *istat, int options, struct rusage *rusage); - -__weak_reference(__wait4, wait4); - -pid_t -__wait4(pid_t pid, int *istat, int options, struct rusage *rusage) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = _wait4(pid, istat, options, rusage); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_waitpid.c b/lib/libkse/thread/thr_waitpid.c deleted file mode 100644 index 1f2d4a7..0000000 --- a/lib/libkse/thread/thr_waitpid.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/types.h> -#include <sys/wait.h> -#include <pthread.h> -#include "thr_private.h" - -extern int __waitpid(pid_t, int *, int); - -pid_t _waitpid(pid_t wpid, int *status, int options); - -__weak_reference(_waitpid, waitpid); - -pid_t -_waitpid(pid_t wpid, int *status, int options) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __waitpid(wpid, status, options); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_write.c b/lib/libkse/thread/thr_write.c deleted file mode 100644 index 1bb3bc0..0000000 --- a/lib/libkse/thread/thr_write.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -__ssize_t __write(int fd, const void *buf, size_t nbytes); - -__weak_reference(__write, write); - -ssize_t -__write(int fd, const void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_write(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_writev.c b/lib/libkse/thread/thr_writev.c deleted file mode 100644 index f3f2aaf..0000000 --- a/lib/libkse/thread/thr_writev.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -ssize_t __writev(int fd, const struct iovec *iov, int iovcnt); - -__weak_reference(__writev, writev); - -ssize_t -__writev(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_writev(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_yield.c b/lib/libkse/thread/thr_yield.c deleted file mode 100644 index 7094609..0000000 --- a/lib/libkse/thread/thr_yield.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. - * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <pthread.h> -#include "thr_private.h" - -int _sched_yield(void); - -__weak_reference(_sched_yield, sched_yield); -__weak_reference(_pthread_yield, pthread_yield); - -int -_sched_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sched_yield()); - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - /* Always return no error. */ - return(0); -} - -/* Draft 4 yield */ -void -_pthread_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sched_yield(); - return; - } - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); -} diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile index f21a1bf..4608254 100644 --- a/lib/libkvm/Makefile +++ b/lib/libkvm/Makefile @@ -1,23 +1,36 @@ # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ +.if defined(TARGET_ARCH) && !defined(COMPAT_32BIT) +KVM_XARCH=${TARGET_ARCH} +KVM_XCPUARCH=${KVM_XARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/} +.else +KVM_XARCH=${MACHINE_ARCH} +KVM_XCPUARCH=${MACHINE_CPUARCH} +.endif + +.if ${KVM_XARCH} != ${MACHINE_ARCH} +LIB= kvm-${KVM_XARCH} +CFLAGS+=-DCROSS_LIBKVM +.else LIB= kvm +.endif + SHLIBDIR?= /lib SHLIB_MAJOR= 6 CFLAGS+=-DLIBC_SCCS -I${.CURDIR} -.if exists(${.CURDIR}/kvm_${MACHINE_ARCH}.c) -KVM_ARCH=${MACHINE_ARCH} +.if exists(${.CURDIR}/kvm_${KVM_XARCH}.c) +KVM_ARCH=${KVM_XARCH} .else -KVM_ARCH=${MACHINE_CPUARCH} +KVM_ARCH=${KVM_XCPUARCH} .endif WARNS?= 3 SRCS= kvm.c kvm_${KVM_ARCH}.c kvm_cptime.c kvm_file.c kvm_getloadavg.c \ kvm_getswapinfo.c kvm_pcpu.c kvm_proc.c kvm_vnet.c -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ - ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips" +.if exists(${.CURDIR}/kvm_minidump_${KVM_ARCH}.c) SRCS+= kvm_minidump_${KVM_ARCH}.c .endif INCS= kvm.h diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c index 9181a49..4ff62c9 100644 --- a/lib/libkvm/kvm.c +++ b/lib/libkvm/kvm.c @@ -73,9 +73,44 @@ static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94"; #include "kvm_private.h" +#ifndef CROSS_LIBKVM + /* from src/lib/libc/gen/nlist.c */ int __fdnlist(int, struct nlist *); +#define kvm_fdnlist __fdnlist + +#else + +#include <proc_service.h> + +static int +kvm_fdnlist(int fd, struct nlist *list) +{ + psaddr_t addr; + ps_err_e pserr; + int nfail; + + nfail = 0; + while (list->n_name != NULL && list->n_name[0] != '\0') { + list->n_other = 0; + list->n_desc = 0; + pserr = ps_pglobal_lookup(NULL, NULL, list->n_name, &addr); + if (pserr != PS_OK) { + nfail++; + list->n_value = 0; + list->n_type = 0; + } else { + list->n_value = addr; + list->n_type = N_DATA | N_EXT; + } + list++; + } + return (nfail); +} + +#endif /* CROSS_LIBKVM */ + char * kvm_geterr(kvm_t *kd) { @@ -341,7 +376,7 @@ kvm_fdnlist_prefix(kvm_t *kd, struct nlist *nl, int missing, const char *prefix, /* Do lookup on the reduced list. */ np = n; - unresolved = __fdnlist(kd->nlfd, np); + unresolved = kvm_fdnlist(kd->nlfd, np); /* Check if we could resolve further symbols and update the list. */ if (unresolved >= 0 && unresolved < missing) { @@ -398,7 +433,7 @@ _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize) * slow library call. */ if (!ISALIVE(kd)) { - error = __fdnlist(kd->nlfd, nl); + error = kvm_fdnlist(kd->nlfd, nl); if (error <= 0) /* Hard error or success. */ return (error); diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h index d2ee8fa..d697795 100644 --- a/lib/libkvm/kvm.h +++ b/lib/libkvm/kvm.h @@ -77,6 +77,7 @@ char *kvm_geterr(kvm_t *); char *kvm_getfiles(kvm_t *, int, int, int *); int kvm_getloadavg(kvm_t *, double [], int); int kvm_getmaxcpu(kvm_t *); +int kvm_getncpus(kvm_t *); void *kvm_getpcpu(kvm_t *, int); uint64_t kvm_counter_u64_fetch(kvm_t *, u_long); struct kinfo_proc * @@ -88,7 +89,7 @@ kvm_t *kvm_open kvm_t *kvm_openfiles (const char *, const char *, const char *, int, char *); ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t); -ssize_t kvm_read_zpcpu(kvm_t *, void *, u_long, size_t, int); +ssize_t kvm_read_zpcpu(kvm_t *, unsigned long, void *, size_t, int); ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t); __END_DECLS diff --git a/lib/libkvm/kvm_arm.c b/lib/libkvm/kvm_arm.c index b1274e9..d221f6a 100644 --- a/lib/libkvm/kvm_arm.c +++ b/lib/libkvm/kvm_arm.c @@ -42,11 +42,15 @@ __FBSDID("$FreeBSD$"); #include <sys/elf32.h> #include <sys/mman.h> +#ifndef CROSS_LIBKVM #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> - #include <machine/pmap.h> +#else +#include "../../sys/arm/include/pte.h" +#include "../../sys/arm/include/vmparam.h" +#endif #include <db.h> #include <limits.h> diff --git a/lib/libkvm/kvm_getpcpu.3 b/lib/libkvm/kvm_getpcpu.3 index 4087f1c..13192c2 100644 --- a/lib/libkvm/kvm_getpcpu.3 +++ b/lib/libkvm/kvm_getpcpu.3 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 11, 2013 +.Dd February 12, 2014 .Dt KVM_GETPCPU 3 .Os .Sh NAME @@ -47,10 +47,12 @@ .Fn kvm_dpcpu_setcpu "kvm_t *kd" "u_int cpu" .Ft int .Fn kvm_getmaxcpu "kvm_t *kd" +.Ft int +.Fn kvm_getncpus "kvm_t *kd" .Ft void * .Fn kvm_getpcpu "kvm_t *kd" "int cpu" .Ft ssize_t -.Fn kvm_read_zpcpu "kvm_t *kd" "void *buf" "u_long base" "size_t size" "int cpu" +.Fn kvm_read_zpcpu "kvm_t *kd" "u_long base" "void *buf" "size_t size" "int cpu" .Ft uint64_t .Fn kvm_counter_u64_fetch "kvm_t *kd" "u_long base" .Sh DESCRIPTION @@ -73,6 +75,10 @@ The function returns the maximum number of CPUs supported by the kernel. .Pp The +.Fn kvm_getncpus +function returns the current number of CPUs in the kernel. +.Pp +The .Fn kvm_getpcpu function returns a buffer holding the per-CPU data for a single CPU. This buffer is described by the diff --git a/lib/libkvm/kvm_ia64.c b/lib/libkvm/kvm_ia64.c index 74e2b80..5db7e1e 100644 --- a/lib/libkvm/kvm_ia64.c +++ b/lib/libkvm/kvm_ia64.c @@ -32,12 +32,21 @@ #include <sys/elf64.h> #include <sys/mman.h> +#ifndef CROSS_LIBKVM #include <machine/atomic.h> #include <machine/bootinfo.h> +#include <machine/elf.h> #include <machine/pte.h> +#else +#include "../../sys/ia64/include/atomic.h" +#include "../../sys/ia64/include/bootinfo.h" +#include "../../sys/ia64/include/elf.h" +#include "../../sys/ia64/include/pte.h" +#endif #include <kvm.h> #include <limits.h> +#include <stdint.h> #include <stdlib.h> #include <unistd.h> @@ -55,6 +64,8 @@ #define PBVM_BASE 0x9ffc000000000000UL #define PBVM_PGSZ (64 * 1024) +typedef size_t (a2p_f)(kvm_t *, uint64_t, off_t *); + struct vmstate { void *mmapbase; size_t mmapsize; @@ -62,6 +73,7 @@ struct vmstate { u_long kptdir; u_long *pbvm_pgtbl; u_int pbvm_pgtblsz; + a2p_f *kvatop; }; /* @@ -70,7 +82,7 @@ struct vmstate { * set of headers. */ static int -_kvm_maphdrs(kvm_t *kd, size_t sz) +ia64_maphdrs(kvm_t *kd, size_t sz) { struct vmstate *vm = kd->vmst; @@ -91,38 +103,103 @@ _kvm_maphdrs(kvm_t *kd, size_t sz) } /* - * Translate a physical memory address to a file-offset in the crash-dump. + * Physical core support. */ + static size_t -_kvm_pa2off(kvm_t *kd, uint64_t pa, off_t *ofs, size_t pgsz) +phys_addr2off(kvm_t *kd, uint64_t pa, off_t *ofs, size_t pgsz) { - Elf64_Ehdr *e = kd->vmst->mmapbase; - Elf64_Phdr *p = (Elf64_Phdr*)((char*)e + e->e_phoff); - int n = e->e_phnum; + Elf64_Ehdr *e; + Elf64_Phdr *p; + int n; - if (pa != REGION_ADDR(pa)) { - _kvm_err(kd, kd->program, "internal error"); - return (0); - } + if (pa != REGION_ADDR(pa)) + goto fail; + e = (Elf64_Ehdr *)(kd->vmst->mmapbase); + n = e->e_phnum; + p = (Elf64_Phdr *)(void *)((uintptr_t)(void *)e + e->e_phoff); while (n && (pa < p->p_paddr || pa >= p->p_paddr + p->p_memsz)) p++, n--; if (n == 0) - return (0); + goto fail; *ofs = (pa - p->p_paddr) + p->p_offset; if (pgsz == 0) return (p->p_memsz - (pa - p->p_paddr)); return (pgsz - ((size_t)pa & (pgsz - 1))); + + fail: + _kvm_err(kd, kd->program, "invalid physical address %#jx", + (uintmax_t)pa); + return (0); +} + +static size_t +phys_kvatop(kvm_t *kd, uint64_t va, off_t *ofs) +{ + struct ia64_lpte pte; + uint64_t pa, pgaddr, pt0addr, pt1addr; + size_t pgno, pgsz, pt0no, pt1no; + + if (va >= REGION_BASE(6)) { + /* Regions 6 and 7: direct mapped. */ + pa = REGION_ADDR(va); + return (phys_addr2off(kd, pa, ofs, 0)); + } else if (va >= REGION_BASE(5)) { + /* Region 5: Kernel Virtual Memory. */ + va = REGION_ADDR(va); + pgsz = kd->vmst->pagesize; + pt0no = KPTE_DIR0_INDEX(va, pgsz); + pt1no = KPTE_DIR1_INDEX(va, pgsz); + pgno = KPTE_PTE_INDEX(va, pgsz); + if (pt0no >= NKPTEDIR(pgsz)) + goto fail; + pt0addr = kd->vmst->kptdir + (pt0no << 3); + if (kvm_read(kd, pt0addr, &pt1addr, 8) != 8) + goto fail; + if (pt1addr == 0) + goto fail; + pt1addr += pt1no << 3; + if (kvm_read(kd, pt1addr, &pgaddr, 8) != 8) + goto fail; + if (pgaddr == 0) + goto fail; + pgaddr += pgno * sizeof(pte); + if (kvm_read(kd, pgaddr, &pte, sizeof(pte)) != sizeof(pte)) + goto fail; + if (!(pte.pte & PTE_PRESENT)) + goto fail; + pa = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1)); + return (phys_addr2off(kd, pa, ofs, pgsz)); + } else if (va >= PBVM_BASE) { + /* Region 4: Pre-Boot Virtual Memory (PBVM). */ + va -= PBVM_BASE; + pgsz = PBVM_PGSZ; + pt0no = va / pgsz; + if (pt0no >= (kd->vmst->pbvm_pgtblsz >> 3)) + goto fail; + pt0addr = kd->vmst->pbvm_pgtbl[pt0no]; + if (!(pt0addr & PTE_PRESENT)) + goto fail; + pa = (pt0addr & PTE_PPN_MASK) + va % pgsz; + return (phys_addr2off(kd, pa, ofs, pgsz)); + } + + fail: + _kvm_err(kd, kd->program, "invalid kernel virtual address %#jx", + (uintmax_t)va); + *ofs = -1; + return (0); } static ssize_t -_kvm_read_phys(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz) +phys_read(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz) { off_t ofs; size_t sz; - sz = _kvm_pa2off(kd, pa, &ofs, 0); + sz = phys_addr2off(kd, pa, &ofs, 0); if (sz < bufsz) return ((ssize_t)sz); @@ -131,6 +208,50 @@ _kvm_read_phys(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz) return (read(kd->pmfd, buf, bufsz)); } +/* + * Virtual core support (aka minidump). + */ + +static size_t +virt_addr2off(kvm_t *kd, uint64_t va, off_t *ofs, size_t pgsz) +{ + Elf64_Ehdr *e; + Elf64_Phdr *p; + int n; + + if (va < REGION_BASE(4)) + goto fail; + + e = (Elf64_Ehdr *)(kd->vmst->mmapbase); + n = e->e_phnum; + p = (Elf64_Phdr *)(void *)((uintptr_t)(void *)e + e->e_phoff); + while (n && (va < p->p_vaddr || va >= p->p_vaddr + p->p_memsz)) + p++, n--; + if (n == 0) + goto fail; + + *ofs = (va - p->p_vaddr) + p->p_offset; + if (pgsz == 0) + return (p->p_memsz - (va - p->p_vaddr)); + return (pgsz - ((size_t)va & (pgsz - 1))); + + fail: + _kvm_err(kd, kd->program, "invalid virtual address %#jx", + (uintmax_t)va); + return (0); +} + +static size_t +virt_kvatop(kvm_t *kd, uint64_t va, off_t *ofs) +{ + + return (virt_addr2off(kd, va, ofs, 0)); +} + +/* + * KVM architecture support functions. + */ + void _kvm_freevtop(kvm_t *kd) { @@ -160,27 +281,37 @@ _kvm_initvtop(kvm_t *kd) return (-1); } +#ifndef CROSS_LIBKVM kd->vmst->pagesize = getpagesize(); +#else + kd->vmst->pagesize = 8192; +#endif - if (_kvm_maphdrs(kd, sizeof(Elf64_Ehdr)) == -1) + if (ia64_maphdrs(kd, sizeof(Elf64_Ehdr)) == -1) return (-1); ehdr = kd->vmst->mmapbase; hdrsz = ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum; - if (_kvm_maphdrs(kd, hdrsz) == -1) + if (ia64_maphdrs(kd, hdrsz) == -1) return (-1); + kd->vmst->kvatop = (ehdr->e_flags & EF_IA_64_ABSOLUTE) ? + phys_kvatop : virt_kvatop; + /* * Load the PBVM page table. We need this to resolve PBVM addresses. * The PBVM page table is obtained from the bootinfo structure, of - * which the physical address is given to us in e_entry. If e_entry - * is 0, then this is assumed to be a pre-PBVM kernel. + * which the address is given to us in e_entry. If e_entry is 0, then + * this is assumed to be a pre-PBVM kernel. + * Note that the address of the bootinfo structure is either physical + * or virtual, depending on whether the core is physical or virtual. */ - if (ehdr->e_entry != 0) { - sz = _kvm_read_phys(kd, ehdr->e_entry, &bi, sizeof(bi)); + if (ehdr->e_entry != 0 && (ehdr->e_flags & EF_IA_64_ABSOLUTE) != 0) { + sz = phys_read(kd, ehdr->e_entry, &bi, sizeof(bi)); if (sz != sizeof(bi)) { _kvm_err(kd, kd->program, - "cannot read bootinfo from PA %#lx", ehdr->e_entry); + "cannot read bootinfo at physical address %#jx", + (uintmax_t)ehdr->e_entry); return (-1); } if (bi.bi_magic != BOOTINFO_MAGIC) { @@ -193,12 +324,12 @@ _kvm_initvtop(kvm_t *kd) return (-1); } kd->vmst->pbvm_pgtblsz = bi.bi_pbvm_pgtblsz; - sz = _kvm_read_phys(kd, bi.bi_pbvm_pgtbl, kd->vmst->pbvm_pgtbl, + sz = phys_read(kd, bi.bi_pbvm_pgtbl, kd->vmst->pbvm_pgtbl, bi.bi_pbvm_pgtblsz); if (sz != bi.bi_pbvm_pgtblsz) { _kvm_err(kd, kd->program, - "cannot read page table from PA %#lx", - bi.bi_pbvm_pgtbl); + "cannot read page table at physical address %#jx", + (uintmax_t)bi.bi_pbvm_pgtbl); return (-1); } } else { @@ -225,7 +356,7 @@ _kvm_initvtop(kvm_t *kd) return (-1); } - if (va < REGION_BASE(6)) { + if (va == REGION_BASE(5)) { _kvm_err(kd, kd->program, "kptdir is itself virtual"); return (-1); } @@ -237,56 +368,8 @@ _kvm_initvtop(kvm_t *kd) int _kvm_kvatop(kvm_t *kd, u_long va, off_t *ofs) { - struct ia64_lpte pte; - uint64_t pa, pgaddr, pt0addr, pt1addr; - size_t pgno, pgsz, pt0no, pt1no; - - if (va >= REGION_BASE(6)) { - /* Regions 6 and 7: direct mapped. */ - pa = REGION_ADDR(va); - return (_kvm_pa2off(kd, pa, ofs, 0)); - } else if (va >= REGION_BASE(5)) { - /* Region 5: Kernel Virtual Memory. */ - va = REGION_ADDR(va); - pgsz = kd->vmst->pagesize; - pt0no = KPTE_DIR0_INDEX(va, pgsz); - pt1no = KPTE_DIR1_INDEX(va, pgsz); - pgno = KPTE_PTE_INDEX(va, pgsz); - if (pt0no >= NKPTEDIR(pgsz)) - goto fail; - pt0addr = kd->vmst->kptdir + (pt0no << 3); - if (kvm_read(kd, pt0addr, &pt1addr, 8) != 8) - goto fail; - if (pt1addr == 0) - goto fail; - pt1addr += pt1no << 3; - if (kvm_read(kd, pt1addr, &pgaddr, 8) != 8) - goto fail; - if (pgaddr == 0) - goto fail; - pgaddr += pgno * sizeof(pte); - if (kvm_read(kd, pgaddr, &pte, sizeof(pte)) != sizeof(pte)) - goto fail; - if (!(pte.pte & PTE_PRESENT)) - goto fail; - pa = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1)); - return (_kvm_pa2off(kd, pa, ofs, pgsz)); - } else if (va >= PBVM_BASE) { - /* Region 4: Pre-Boot Virtual Memory (PBVM). */ - va -= PBVM_BASE; - pgsz = PBVM_PGSZ; - pt0no = va / pgsz; - if (pt0no >= (kd->vmst->pbvm_pgtblsz >> 3)) - goto fail; - pt0addr = kd->vmst->pbvm_pgtbl[pt0no]; - if (!(pt0addr & PTE_PRESENT)) - goto fail; - pa = (pt0addr & PTE_PPN_MASK) + va % pgsz; - return (_kvm_pa2off(kd, pa, ofs, pgsz)); - } + size_t sz; - fail: - _kvm_err(kd, kd->program, "invalid kernel virtual address"); - *ofs = ~0UL; - return (0); + sz = kd->vmst->kvatop(kd, va, ofs); + return ((sz > INT_MAX) ? INT_MAX : sz); } diff --git a/lib/libkvm/kvm_minidump_amd64.c b/lib/libkvm/kvm_minidump_amd64.c index 8d31673..779fa97 100644 --- a/lib/libkvm/kvm_minidump_amd64.c +++ b/lib/libkvm/kvm_minidump_amd64.c @@ -214,6 +214,8 @@ _kvm_minidump_vatop_v1(kvm_t *kd, u_long va, off_t *pa) if (va >= vm->hdr.kernbase) { pteindex = (va - vm->hdr.kernbase) >> PAGE_SHIFT; + if (pteindex >= vm->hdr.pmapsize / sizeof(*vm->page_map)) + goto invalid; pte = vm->page_map[pteindex]; if (((u_long)pte & PG_V) == 0) { _kvm_err(kd, kd->program, "_kvm_vatop: pte not valid"); @@ -264,6 +266,8 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa) if (va >= vm->hdr.kernbase) { pdeindex = (va - vm->hdr.kernbase) >> PDRSHIFT; + if (pdeindex >= vm->hdr.pmapsize / sizeof(*vm->page_map)) + goto invalid; pde = vm->page_map[pdeindex]; if (((u_long)pde & PG_V) == 0) { _kvm_err(kd, kd->program, "_kvm_vatop: pde not valid"); diff --git a/lib/libkvm/kvm_minidump_arm.c b/lib/libkvm/kvm_minidump_arm.c index f6147d0..f4ba604 100644 --- a/lib/libkvm/kvm_minidump_arm.c +++ b/lib/libkvm/kvm_minidump_arm.c @@ -34,7 +34,9 @@ __FBSDID("$FreeBSD$"); */ #include <sys/param.h> +#ifndef CROSS_LIBKVM #include <sys/user.h> +#endif #include <sys/proc.h> #include <sys/stat.h> #include <sys/mman.h> @@ -45,12 +47,18 @@ __FBSDID("$FreeBSD$"); #include <nlist.h> #include <kvm.h> +#ifndef CROSS_LIBKVM #include <vm/vm.h> #include <vm/vm_param.h> #include <machine/elf.h> #include <machine/cpufunc.h> #include <machine/minidump.h> +#else +#include "../../sys/arm/include/pte.h" +#include "../../sys/arm/include/vmparam.h" +#include "../../sys/arm/include/minidump.h" +#endif #include <limits.h> diff --git a/lib/libkvm/kvm_pcpu.c b/lib/libkvm/kvm_pcpu.c index 2d7fb41..662566a 100644 --- a/lib/libkvm/kvm_pcpu.c +++ b/lib/libkvm/kvm_pcpu.c @@ -173,6 +173,16 @@ kvm_getmaxcpu(kvm_t *kd) return (maxcpu); } +int +kvm_getncpus(kvm_t *kd) +{ + + if (mp_ncpus == 0) + if (_kvm_pcpu_init(kd) < 0) + return (-1); + return (mp_ncpus); +} + static int _kvm_dpcpu_setcpu(kvm_t *kd, u_int cpu, int report_error) { @@ -306,7 +316,7 @@ kvm_dpcpu_setcpu(kvm_t *kd, u_int cpu) * Obtain a per-CPU copy for given cpu from UMA_ZONE_PCPU allocation. */ ssize_t -kvm_read_zpcpu(kvm_t *kd, void *buf, u_long base, size_t size, int cpu) +kvm_read_zpcpu(kvm_t *kd, u_long base, void *buf, size_t size, int cpu) { return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu), @@ -327,7 +337,7 @@ kvm_counter_u64_fetch(kvm_t *kd, u_long base) r = 0; for (int i = 0; i < mp_ncpus; i++) { - if (kvm_read_zpcpu(kd, &c, base, sizeof(c), i) != sizeof(c)) + if (kvm_read_zpcpu(kd, base, &c, sizeof(c), i) != sizeof(c)) return (0); r += c; } diff --git a/lib/libmandoc/Makefile b/lib/libmandoc/Makefile index 9fca07e..b857b8a 100644 --- a/lib/libmandoc/Makefile +++ b/lib/libmandoc/Makefile @@ -15,6 +15,6 @@ SRCS= arch.c att.c chars.c \ tbl.c tbl_data.c tbl_layout.c tbl_opts.c vol.c WARNS?= 3 -CFLAGS+= -DHAVE_CONFIG_H -DVERSION="\"1.12.1\"" +CFLAGS+= -DHAVE_CONFIG_H .include <bsd.lib.mk> diff --git a/lib/libmemstat/libmemstat.3 b/lib/libmemstat/libmemstat.3 index 9b749f0..3eff156 100644 --- a/lib/libmemstat/libmemstat.3 +++ b/lib/libmemstat/libmemstat.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 25, 2012 +.Dd February 11, 2014 .Dt LIBMEMSTAT 3 .Os .Sh NAME @@ -80,6 +80,8 @@ .Ft uint64_t .Fn memstat_get_size "const struct memory_type *mtp" .Ft uint64_t +.Fn memstat_get_rsize "const struct memory_type *mtp" +.Ft uint64_t .Fn memstat_get_memalloced "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_memfreed "const struct memory_type *mtp" @@ -287,6 +289,11 @@ If the memory type supports variable allocation sizes, return a bitmask of sizes allocated for the memory type. .It Fn memstat_get_size If the memory type supports a fixed allocation size, return that size. +.It Fn memstat_get_rsize +If the memory type supports a fixed allocation size, return real size +of an allocation. +Real size can exceed requested size due to alignment constraints or +implicit padding. .It Fn memstat_get_memalloced Return the total number of bytes allocated for the memory type over its lifetime. diff --git a/lib/libmemstat/memstat.c b/lib/libmemstat/memstat.c index c7957c8..40bdc9d 100644 --- a/lib/libmemstat/memstat.c +++ b/lib/libmemstat/memstat.c @@ -254,6 +254,13 @@ memstat_get_size(const struct memory_type *mtp) } uint64_t +memstat_get_rsize(const struct memory_type *mtp) +{ + + return (mtp->mt_rsize); +} + +uint64_t memstat_get_memalloced(const struct memory_type *mtp) { diff --git a/lib/libmemstat/memstat.h b/lib/libmemstat/memstat.h index cca75b3..8394dc1 100644 --- a/lib/libmemstat/memstat.h +++ b/lib/libmemstat/memstat.h @@ -124,6 +124,7 @@ uint64_t memstat_get_countlimit(const struct memory_type *mtp); uint64_t memstat_get_byteslimit(const struct memory_type *mtp); uint64_t memstat_get_sizemask(const struct memory_type *mtp); uint64_t memstat_get_size(const struct memory_type *mtp); +uint64_t memstat_get_rsize(const struct memory_type *mtp); uint64_t memstat_get_memalloced(const struct memory_type *mtp); uint64_t memstat_get_memfreed(const struct memory_type *mtp); uint64_t memstat_get_numallocs(const struct memory_type *mtp); diff --git a/lib/libmemstat/memstat_internal.h b/lib/libmemstat/memstat_internal.h index 2416e09..9fdc228 100644 --- a/lib/libmemstat/memstat_internal.h +++ b/lib/libmemstat/memstat_internal.h @@ -51,6 +51,7 @@ struct memory_type { uint64_t mt_byteslimit; /* 0, or maximum bytes. */ uint64_t mt_sizemask; /* malloc: allocated size bitmask. */ uint64_t mt_size; /* uma: size of objects. */ + uint64_t mt_rsize; /* uma: real size of objects. */ /* * Zone or type information that includes all caches and any central diff --git a/lib/libmemstat/memstat_uma.c b/lib/libmemstat/memstat_uma.c index b8ff3a1..8e89585 100644 --- a/lib/libmemstat/memstat_uma.c +++ b/lib/libmemstat/memstat_uma.c @@ -212,6 +212,7 @@ retry: } mtp->mt_size = uthp->uth_size; + mtp->mt_rsize = uthp->uth_rsize; mtp->mt_memalloced = mtp->mt_numallocs * uthp->uth_size; mtp->mt_memfreed = mtp->mt_numfrees * uthp->uth_size; mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; @@ -435,6 +436,7 @@ memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle) } skip_percpu: mtp->mt_size = kz.uk_size; + mtp->mt_rsize = kz.uk_rsize; mtp->mt_memalloced = mtp->mt_numallocs * mtp->mt_size; mtp->mt_memfreed = mtp->mt_numfrees * mtp->mt_size; mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; diff --git a/lib/libnetgraph/debug.c b/lib/libnetgraph/debug.c index dfc75f5..6d0579f 100644 --- a/lib/libnetgraph/debug.c +++ b/lib/libnetgraph/debug.c @@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$"); #include <netgraph/ng_eiface.h> #include <netgraph/ng_etf.h> #include <netgraph/ng_ether.h> -#include <netgraph/ng_fec.h> #include <netgraph/ng_frame_relay.h> #include <netgraph/ng_gif.h> #include <netgraph/ng_gif_demux.h> @@ -136,7 +135,6 @@ static const struct ng_cookie cookies[] = { COOKIE(EIFACE), COOKIE(ETF), COOKIE(ETHER), - COOKIE(FEC), COOKIE(FRAMERELAY), COOKIE(GIF), COOKIE(GIF_DEMUX), diff --git a/lib/libnetgraph/netgraph.3 b/lib/libnetgraph/netgraph.3 index d2ef8bd..bd55797 100644 --- a/lib/libnetgraph/netgraph.3 +++ b/lib/libnetgraph/netgraph.3 @@ -35,7 +35,7 @@ .\" $FreeBSD$ .\" $Whistle: netgraph.3,v 1.7 1999/01/25 07:14:06 archie Exp $ .\" -.Dd January 27, 2004 +.Dd November 25, 2013 .Dt NETGRAPH 3 .Os .Sh NAME @@ -57,7 +57,7 @@ .Sh LIBRARY .Lb libnetgraph .Sh SYNOPSIS -.In netgraph.h +.In netgraph/netgraph.h .Ft int .Fn NgMkSockNode "const char *name" "int *csp" "int *dsp" .Ft int diff --git a/lib/libnetgraph/sock.c b/lib/libnetgraph/sock.c index 5f9f563..12603d3 100644 --- a/lib/libnetgraph/sock.c +++ b/lib/libnetgraph/sock.c @@ -111,9 +111,12 @@ gotNode: /* Save node name */ strlcpy(namebuf, name, sizeof(namebuf)); } else if (dsp != NULL) { - u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; - struct ng_mesg *const resp = (struct ng_mesg *) rbuf; - struct nodeinfo *const ni = (struct nodeinfo *) resp->data; + union { + u_char rbuf[sizeof(struct ng_mesg) + + sizeof(struct nodeinfo)]; + struct ng_mesg res; + } res; + struct nodeinfo *const ni = (struct nodeinfo *) res.res.data; /* Find out the node ID */ if (NgSendMsg(cs, ".", NGM_GENERIC_COOKIE, @@ -123,7 +126,7 @@ gotNode: NGLOG("send nodeinfo"); goto errout; } - if (NgRecvMsg(cs, resp, sizeof(rbuf), NULL) < 0) { + if (NgRecvMsg(cs, &res.res, sizeof(res.rbuf), NULL) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("recv nodeinfo"); diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile new file mode 100644 index 0000000..710c295 --- /dev/null +++ b/lib/libnv/Makefile @@ -0,0 +1,161 @@ +# $FreeBSD$ + +LIB= nv +SHLIBDIR?= /lib +SHLIB_MAJOR= 0 + +SRCS= dnvlist.c +SRCS+= msgio.c +SRCS+= nvlist.c +SRCS+= nvpair.c + +INCS= dnv.h +INCS+= nv.h + +MAN+= nv.3 + +MLINKS+=nv.3 libnv.3 \ + nv.3 nvlist.3 +MLINKS+=nv.3 nvlist_create.3 \ + nv.3 nvlist_destroy.3 \ + nv.3 nvlist_error.3 \ + nv.3 nvlist_empty.3 \ + nv.3 nvlist_clone.3 \ + nv.3 nvlist_dump.3 \ + nv.3 nvlist_fdump.3 \ + nv.3 nvlist_size.3 \ + nv.3 nvlist_pack.3 \ + nv.3 nvlist_unpack.3 \ + nv.3 nvlist_send.3 \ + nv.3 nvlist_recv.3 \ + nv.3 nvlist_xfer.3 \ + nv.3 nvlist_next.3 \ + nv.3 nvlist_exists.3 \ + nv.3 nvlist_exists_type.3 \ + nv.3 nvlist_exists_null.3 \ + nv.3 nvlist_exists_bool.3 \ + nv.3 nvlist_exists_number.3 \ + nv.3 nvlist_exists_string.3 \ + nv.3 nvlist_exists_nvlist.3 \ + nv.3 nvlist_exists_descriptor.3 \ + nv.3 nvlist_exists_binary.3 \ + nv.3 nvlist_add_null.3 \ + nv.3 nvlist_add_bool.3 \ + nv.3 nvlist_add_number.3 \ + nv.3 nvlist_add_string.3 \ + nv.3 nvlist_add_stringf.3 \ + nv.3 nvlist_add_stringv.3 \ + nv.3 nvlist_add_nvlist.3 \ + nv.3 nvlist_add_descriptor.3 \ + nv.3 nvlist_add_binary.3 \ + nv.3 nvlist_move_string.3 \ + nv.3 nvlist_move_nvlist.3 \ + nv.3 nvlist_move_descriptor.3 \ + nv.3 nvlist_move_binary.3 \ + nv.3 nvlist_get_bool.3 \ + nv.3 nvlist_get_number.3 \ + nv.3 nvlist_get_string.3 \ + nv.3 nvlist_get_nvlist.3 \ + nv.3 nvlist_get_descriptor.3 \ + nv.3 nvlist_get_binary.3 \ + nv.3 nvlist_take_bool.3 \ + nv.3 nvlist_take_number.3 \ + nv.3 nvlist_take_string.3 \ + nv.3 nvlist_take_nvlist.3 \ + nv.3 nvlist_take_descriptor.3 \ + nv.3 nvlist_take_binary.3 \ + nv.3 nvlist_free.3 \ + nv.3 nvlist_free_type.3 \ + nv.3 nvlist_free_null.3 \ + nv.3 nvlist_free_bool.3 \ + nv.3 nvlist_free_number.3 \ + nv.3 nvlist_free_string.3 \ + nv.3 nvlist_free_nvlist.3 \ + nv.3 nvlist_free_descriptor.3 \ + nv.3 nvlist_free_binary.3 +MLINKS+=nv.3 nvlist_existsf.3 \ + nv.3 nvlist_existsf_type.3 \ + nv.3 nvlist_existsf_null.3 \ + nv.3 nvlist_existsf_bool.3 \ + nv.3 nvlist_existsf_number.3 \ + nv.3 nvlist_existsf_string.3 \ + nv.3 nvlist_existsf_nvlist.3 \ + nv.3 nvlist_existsf_descriptor.3 \ + nv.3 nvlist_existsf_binary.3 \ + nv.3 nvlist_addf_null.3 \ + nv.3 nvlist_addf_bool.3 \ + nv.3 nvlist_addf_number.3 \ + nv.3 nvlist_addf_string.3 \ + nv.3 nvlist_addf_nvlist.3 \ + nv.3 nvlist_addf_descriptor.3 \ + nv.3 nvlist_addf_binary.3 \ + nv.3 nvlist_movef_string.3 \ + nv.3 nvlist_movef_nvlist.3 \ + nv.3 nvlist_movef_descriptor.3 \ + nv.3 nvlist_movef_binary.3 \ + nv.3 nvlist_getf_bool.3 \ + nv.3 nvlist_getf_number.3 \ + nv.3 nvlist_getf_string.3 \ + nv.3 nvlist_getf_nvlist.3 \ + nv.3 nvlist_getf_descriptor.3 \ + nv.3 nvlist_getf_binary.3 \ + nv.3 nvlist_takef_bool.3 \ + nv.3 nvlist_takef_number.3 \ + nv.3 nvlist_takef_string.3 \ + nv.3 nvlist_takef_nvlist.3 \ + nv.3 nvlist_takef_descriptor.3 \ + nv.3 nvlist_takef_binary.3 \ + nv.3 nvlist_freef.3 \ + nv.3 nvlist_freef_type.3 \ + nv.3 nvlist_freef_null.3 \ + nv.3 nvlist_freef_bool.3 \ + nv.3 nvlist_freef_number.3 \ + nv.3 nvlist_freef_string.3 \ + nv.3 nvlist_freef_nvlist.3 \ + nv.3 nvlist_freef_descriptor.3 \ + nv.3 nvlist_freef_binary.3 +MLINKS+=nv.3 nvlist_existsv.3 \ + nv.3 nvlist_existsv_type.3 \ + nv.3 nvlist_existsv_null.3 \ + nv.3 nvlist_existsv_bool.3 \ + nv.3 nvlist_existsv_number.3 \ + nv.3 nvlist_existsv_string.3 \ + nv.3 nvlist_existsv_nvlist.3 \ + nv.3 nvlist_existsv_descriptor.3 \ + nv.3 nvlist_existsv_binary.3 \ + nv.3 nvlist_addv_null.3 \ + nv.3 nvlist_addv_bool.3 \ + nv.3 nvlist_addv_number.3 \ + nv.3 nvlist_addv_string.3 \ + nv.3 nvlist_addv_nvlist.3 \ + nv.3 nvlist_addv_descriptor.3 \ + nv.3 nvlist_addv_binary.3 \ + nv.3 nvlist_movev_string.3 \ + nv.3 nvlist_movev_nvlist.3 \ + nv.3 nvlist_movev_descriptor.3 \ + nv.3 nvlist_movev_binary.3 \ + nv.3 nvlist_getv_bool.3 \ + nv.3 nvlist_getv_number.3 \ + nv.3 nvlist_getv_string.3 \ + nv.3 nvlist_getv_nvlist.3 \ + nv.3 nvlist_getv_descriptor.3 \ + nv.3 nvlist_getv_binary.3 \ + nv.3 nvlist_takev_bool.3 \ + nv.3 nvlist_takev_number.3 \ + nv.3 nvlist_takev_string.3 \ + nv.3 nvlist_takev_nvlist.3 \ + nv.3 nvlist_takev_descriptor.3 \ + nv.3 nvlist_takev_binary.3 \ + nv.3 nvlist_freef.3 \ + nv.3 nvlist_freev_type.3 \ + nv.3 nvlist_freev_null.3 \ + nv.3 nvlist_freev_bool.3 \ + nv.3 nvlist_freev_number.3 \ + nv.3 nvlist_freev_string.3 \ + nv.3 nvlist_freev_nvlist.3 \ + nv.3 nvlist_freev_descriptor.3 \ + nv.3 nvlist_freev_binary.3 + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/lib/libnv/common_impl.h b/lib/libnv/common_impl.h new file mode 100644 index 0000000..5af4db2 --- /dev/null +++ b/lib/libnv/common_impl.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _COMMON_IMPL_H_ +#define _COMMON_IMPL_H_ + +#define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF) + +#endif /* !_COMMON_IMPL_H_ */ diff --git a/lib/libnv/dnv.h b/lib/libnv/dnv.h new file mode 100644 index 0000000..ac1e57c --- /dev/null +++ b/lib/libnv/dnv.h @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DNV_H_ +#define _DNV_H_ + +#include <sys/cdefs.h> + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> + +#ifndef _NVLIST_T_DECLARED +#define _NVLIST_T_DECLARED +struct nvlist; + +typedef struct nvlist nvlist_t; +#endif + +/* + * The dnvlist_get functions returns value associated with the given name. + * If it returns a pointer, the pointer represents internal buffer and should + * not be freed by the caller. + * If no element of the given name and type exists, the function will return + * provided default value. + */ + +bool dnvlist_get_bool(const nvlist_t *nvl, const char *name, bool defval); +uint64_t dnvlist_get_number(const nvlist_t *nvl, const char *name, uint64_t defval); +const char *dnvlist_get_string(const nvlist_t *nvl, const char *name, const char *defval); +const nvlist_t *dnvlist_get_nvlist(const nvlist_t *nvl, const char *name, const nvlist_t *defval); +int dnvlist_get_descriptor(const nvlist_t *nvl, const char *name, int defval); +const void *dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep, const void *defval, size_t defsize); + +bool dnvlist_getf_bool(const nvlist_t *nvl, bool defval, const char *namefmt, ...) __printflike(3, 4); +uint64_t dnvlist_getf_number(const nvlist_t *nvl, uint64_t defval, const char *namefmt, ...) __printflike(3, 4); +const char *dnvlist_getf_string(const nvlist_t *nvl, const char *defval, const char *namefmt, ...) __printflike(3, 4); +const nvlist_t *dnvlist_getf_nvlist(const nvlist_t *nvl, const nvlist_t *defval, const char *namefmt, ...) __printflike(3, 4); +int dnvlist_getf_descriptor(const nvlist_t *nvl, int defval, const char *namefmt, ...) __printflike(3, 4); +const void *dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, size_t defsize, const char *namefmt, ...) __printflike(5, 6); + +bool dnvlist_getv_bool(const nvlist_t *nvl, bool defval, const char *namefmt, va_list nameap) __printflike(3, 0); +uint64_t dnvlist_getv_number(const nvlist_t *nvl, uint64_t defval, const char *namefmt, va_list nameap) __printflike(3, 0); +const char *dnvlist_getv_string(const nvlist_t *nvl, const char *defval, const char *namefmt, va_list nameap) __printflike(3, 0); +const nvlist_t *dnvlist_getv_nvlist(const nvlist_t *nvl, const nvlist_t *defval, const char *namefmt, va_list nameap) __printflike(3, 0); +int dnvlist_getv_descriptor(const nvlist_t *nvl, int defval, const char *namefmt, va_list nameap) __printflike(3, 0); +const void *dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, size_t defsize, const char *namefmt, va_list nameap) __printflike(5, 0); + +/* + * The dnvlist_take functions returns value associated with the given name and + * remove corresponding nvpair. + * If it returns a pointer, the caller has to free it. + * If no element of the given name and type exists, the function will return + * provided default value. + */ + +bool dnvlist_take_bool(nvlist_t *nvl, const char *name, bool defval); +uint64_t dnvlist_take_number(nvlist_t *nvl, const char *name, uint64_t defval); +char *dnvlist_take_string(nvlist_t *nvl, const char *name, char *defval); +nvlist_t *dnvlist_take_nvlist(nvlist_t *nvl, const char *name, nvlist_t *defval); +int dnvlist_take_descriptor(nvlist_t *nvl, const char *name, int defval); +void *dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep, void *defval, size_t defsize); + +bool dnvlist_takef_bool(nvlist_t *nvl, bool defval, const char *namefmt, ...) __printflike(3, 4); +uint64_t dnvlist_takef_number(nvlist_t *nvl, uint64_t defval, const char *namefmt, ...) __printflike(3, 4); +char *dnvlist_takef_string(nvlist_t *nvl, char *defval, const char *namefmt, ...) __printflike(3, 4); +nvlist_t *dnvlist_takef_nvlist(nvlist_t *nvl, nvlist_t *defval, const char *namefmt, ...) __printflike(3, 4); +int dnvlist_takef_descriptor(nvlist_t *nvl, int defval, const char *namefmt, ...) __printflike(3, 4); +void *dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval, size_t defsize, const char *namefmt, ...) __printflike(5, 6); + +bool dnvlist_takev_bool(nvlist_t *nvl, bool defval, const char *namefmt, va_list nameap) __printflike(3, 0); +uint64_t dnvlist_takev_number(nvlist_t *nvl, uint64_t defval, const char *namefmt, va_list nameap) __printflike(3, 0); +char *dnvlist_takev_string(nvlist_t *nvl, char *defval, const char *namefmt, va_list nameap) __printflike(3, 0); +nvlist_t *dnvlist_takev_nvlist(nvlist_t *nvl, nvlist_t *defval, const char *namefmt, va_list nameap) __printflike(3, 0); +int dnvlist_takev_descriptor(nvlist_t *nvl, int defval, const char *namefmt, va_list nameap) __printflike(3, 0); +void *dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval, size_t defsize, const char *namefmt, va_list nameap) __printflike(5, 0); + +#endif /* !_DNV_H_ */ diff --git a/lib/libnv/dnvlist.c b/lib/libnv/dnvlist.c new file mode 100644 index 0000000..b758bbf --- /dev/null +++ b/lib/libnv/dnvlist.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> + +#include "nv.h" +#include "nv_impl.h" + +#include "dnv.h" + +#define DNVLIST_GET(ftype, type) \ +ftype \ +dnvlist_get_##type(const nvlist_t *nvl, const char *name, ftype defval) \ +{ \ + \ + return (dnvlist_getf_##type(nvl, defval, "%s", name)); \ +} + +DNVLIST_GET(bool, bool) +DNVLIST_GET(uint64_t, number) +DNVLIST_GET(const char *, string) +DNVLIST_GET(const nvlist_t *, nvlist) +DNVLIST_GET(int, descriptor) + +#undef DNVLIST_GET + +const void * +dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep, + const void *defval, size_t defsize) +{ + + return (dnvlist_getf_binary(nvl, sizep, defval, defsize, "%s", name)); +} + +#define DNVLIST_GETF(ftype, type) \ +ftype \ +dnvlist_getf_##type(const nvlist_t *nvl, ftype defval, \ + const char *namefmt, ...) \ +{ \ + va_list nameap; \ + ftype value; \ + \ + va_start(nameap, namefmt); \ + value = dnvlist_getv_##type(nvl, defval, namefmt, nameap); \ + va_end(nameap); \ + \ + return (value); \ +} + +DNVLIST_GETF(bool, bool) +DNVLIST_GETF(uint64_t, number) +DNVLIST_GETF(const char *, string) +DNVLIST_GETF(const nvlist_t *, nvlist) +DNVLIST_GETF(int, descriptor) + +#undef DNVLIST_GETF + +const void * +dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, + size_t defsize, const char *namefmt, ...) +{ + va_list nameap; + const void *value; + + va_start(nameap, namefmt); + value = dnvlist_getv_binary(nvl, sizep, defval, defsize, namefmt, + nameap); + va_end(nameap); + + return (value); +} + +#define DNVLIST_GETV(ftype, type) \ +ftype \ +dnvlist_getv_##type(const nvlist_t *nvl, ftype defval, \ + const char *namefmt, va_list nameap) \ +{ \ + va_list cnameap; \ + ftype value; \ + \ + va_copy(cnameap, nameap); \ + if (nvlist_existsv_##type(nvl, namefmt, cnameap)) \ + value = nvlist_getv_##type(nvl, namefmt, nameap); \ + else \ + value = defval; \ + va_end(cnameap); \ + return (value); \ +} + +DNVLIST_GETV(bool, bool) +DNVLIST_GETV(uint64_t, number) +DNVLIST_GETV(const char *, string) +DNVLIST_GETV(const nvlist_t *, nvlist) +DNVLIST_GETV(int, descriptor) + +#undef DNVLIST_GETV + +const void * +dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, + size_t defsize, const char *namefmt, va_list nameap) +{ + va_list cnameap; + const void *value; + + va_copy(cnameap, nameap); + if (nvlist_existsv_binary(nvl, namefmt, cnameap)) { + value = nvlist_getv_binary(nvl, sizep, namefmt, nameap); + } else { + if (sizep != NULL) + *sizep = defsize; + value = defval; + } + va_end(cnameap); + return (value); +} + +#define DNVLIST_TAKE(ftype, type) \ +ftype \ +dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval) \ +{ \ + \ + return (dnvlist_takef_##type(nvl, defval, "%s", name)); \ +} + +DNVLIST_TAKE(bool, bool) +DNVLIST_TAKE(uint64_t, number) +DNVLIST_TAKE(char *, string) +DNVLIST_TAKE(nvlist_t *, nvlist) +DNVLIST_TAKE(int, descriptor) + +#undef DNVLIST_TAKE + +void * +dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep, + void *defval, size_t defsize) +{ + + return (dnvlist_takef_binary(nvl, sizep, defval, defsize, "%s", name)); +} + +#define DNVLIST_TAKEF(ftype, type) \ +ftype \ +dnvlist_takef_##type(nvlist_t *nvl, ftype defval, \ + const char *namefmt, ...) \ +{ \ + va_list nameap; \ + ftype value; \ + \ + va_start(nameap, namefmt); \ + value = dnvlist_takev_##type(nvl, defval, namefmt, nameap); \ + va_end(nameap); \ + \ + return (value); \ +} + +DNVLIST_TAKEF(bool, bool) +DNVLIST_TAKEF(uint64_t, number) +DNVLIST_TAKEF(char *, string) +DNVLIST_TAKEF(nvlist_t *, nvlist) +DNVLIST_TAKEF(int, descriptor) + +#undef DNVLIST_TAKEF + +void * +dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval, + size_t defsize, const char *namefmt, ...) +{ + va_list nameap; + void *value; + + va_start(nameap, namefmt); + value = dnvlist_takev_binary(nvl, sizep, defval, defsize, namefmt, + nameap); + va_end(nameap); + + return (value); +} + +#define DNVLIST_TAKEV(ftype, type) \ +ftype \ +dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt, \ + va_list nameap) \ +{ \ + va_list cnameap; \ + ftype value; \ + \ + va_copy(cnameap, nameap); \ + if (nvlist_existsv_##type(nvl, namefmt, cnameap)) \ + value = nvlist_takev_##type(nvl, namefmt, nameap); \ + else \ + value = defval; \ + va_end(cnameap); \ + return (value); \ +} + +DNVLIST_TAKEV(bool, bool) +DNVLIST_TAKEV(uint64_t, number) +DNVLIST_TAKEV(char *, string) +DNVLIST_TAKEV(nvlist_t *, nvlist) +DNVLIST_TAKEV(int, descriptor) + +#undef DNVLIST_TAKEV + +void * +dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval, + size_t defsize, const char *namefmt, va_list nameap) +{ + va_list cnameap; + void *value; + + va_copy(cnameap, nameap); + if (nvlist_existsv_binary(nvl, namefmt, cnameap)) { + value = nvlist_takev_binary(nvl, sizep, namefmt, nameap); + } else { + if (sizep != NULL) + *sizep = defsize; + value = defval; + } + va_end(cnameap); + return (value); +} diff --git a/lib/libnv/msgio.c b/lib/libnv/msgio.c new file mode 100644 index 0000000..41292aa --- /dev/null +++ b/lib/libnv/msgio.c @@ -0,0 +1,390 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org> + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/socket.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_PJDLOG +#include <pjdlog.h> +#endif + +#include "common_impl.h" +#include "msgio.h" + +#ifndef HAVE_PJDLOG +#include <assert.h> +#define PJDLOG_ASSERT(...) assert(__VA_ARGS__) +#define PJDLOG_RASSERT(expr, ...) assert(expr) +#define PJDLOG_ABORT(...) abort() +#endif + +static int +msghdr_add_fd(struct cmsghdr *cmsg, int fd) +{ + + PJDLOG_ASSERT(fd >= 0); + + if (!fd_is_valid(fd)) { + errno = EBADF; + return (-1); + } + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); + bcopy(&fd, CMSG_DATA(cmsg), sizeof(fd)); + + return (0); +} + +static int +msghdr_get_fd(struct cmsghdr *cmsg) +{ + int fd; + + if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS || + cmsg->cmsg_len != CMSG_LEN(sizeof(fd))) { + errno = EINVAL; + return (-1); + } + + bcopy(CMSG_DATA(cmsg), &fd, sizeof(fd)); +#ifndef MSG_CMSG_CLOEXEC + /* + * If the MSG_CMSG_CLOEXEC flag is not available we cannot set the + * close-on-exec flag atomically, but we still want to set it for + * consistency. + */ + (void) fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif + + return (fd); +} + +static void +fd_wait(int fd, bool doread) +{ + fd_set fds; + + PJDLOG_ASSERT(fd >= 0); + + FD_ZERO(&fds); + FD_SET(fd, &fds); + (void)select(fd + 1, doread ? &fds : NULL, doread ? NULL : &fds, + NULL, NULL); +} + +static int +msg_recv(int sock, struct msghdr *msg) +{ + int flags; + + PJDLOG_ASSERT(sock >= 0); + +#ifdef MSG_CMSG_CLOEXEC + flags = MSG_CMSG_CLOEXEC; +#else + flags = 0; +#endif + + for (;;) { + fd_wait(sock, true); + if (recvmsg(sock, msg, flags) == -1) { + if (errno == EINTR) + continue; + return (-1); + } + break; + } + + return (0); +} + +static int +msg_send(int sock, const struct msghdr *msg) +{ + + PJDLOG_ASSERT(sock >= 0); + + for (;;) { + fd_wait(sock, false); + if (sendmsg(sock, msg, 0) == -1) { + if (errno == EINTR) + continue; + return (-1); + } + break; + } + + return (0); +} + +int +cred_send(int sock) +{ + unsigned char credbuf[CMSG_SPACE(sizeof(struct cmsgcred))]; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov; + uint8_t dummy; + + bzero(credbuf, sizeof(credbuf)); + bzero(&msg, sizeof(msg)); + bzero(&iov, sizeof(iov)); + + /* + * XXX: We send one byte along with the control message, because + * setting msg_iov to NULL only works if this is the first + * packet send over the socket. Once we send some data we + * won't be able to send credentials anymore. This is most + * likely a kernel bug. + */ + dummy = 0; + iov.iov_base = &dummy; + iov.iov_len = sizeof(dummy); + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = credbuf; + msg.msg_controllen = sizeof(credbuf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDS; + + if (msg_send(sock, &msg) == -1) + return (-1); + + return (0); +} + +int +cred_recv(int sock, struct cmsgcred *cred) +{ + unsigned char credbuf[CMSG_SPACE(sizeof(struct cmsgcred))]; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov; + uint8_t dummy; + + bzero(credbuf, sizeof(credbuf)); + bzero(&msg, sizeof(msg)); + bzero(&iov, sizeof(iov)); + + iov.iov_base = &dummy; + iov.iov_len = sizeof(dummy); + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = credbuf; + msg.msg_controllen = sizeof(credbuf); + + if (msg_recv(sock, &msg) == -1) + return (-1); + + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == NULL || + cmsg->cmsg_len != CMSG_LEN(sizeof(struct cmsgcred)) || + cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDS) { + errno = EINVAL; + return (-1); + } + bcopy(CMSG_DATA(cmsg), cred, sizeof(*cred)); + + return (0); +} + +int +fd_send(int sock, const int *fds, size_t nfds) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + unsigned int i; + int serrno, ret; + + if (nfds == 0 || fds == NULL) { + errno = EINVAL; + return (-1); + } + + bzero(&msg, sizeof(msg)); + msg.msg_iov = NULL; + msg.msg_iovlen = 0; + msg.msg_controllen = nfds * CMSG_SPACE(sizeof(int)); + msg.msg_control = calloc(1, msg.msg_controllen); + if (msg.msg_control == NULL) + return (-1); + + ret = -1; + + for (i = 0, cmsg = CMSG_FIRSTHDR(&msg); i < nfds && cmsg != NULL; + i++, cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (msghdr_add_fd(cmsg, fds[i]) == -1) + goto end; + } + + if (msg_send(sock, &msg) == -1) + goto end; + + ret = 0; +end: + serrno = errno; + free(msg.msg_control); + errno = serrno; + return (ret); +} + +int +fd_recv(int sock, int *fds, size_t nfds) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + unsigned int i; + int serrno, ret; + + if (nfds == 0 || fds == NULL) { + errno = EINVAL; + return (-1); + } + + bzero(&msg, sizeof(msg)); + msg.msg_iov = NULL; + msg.msg_iovlen = 0; + msg.msg_controllen = nfds * CMSG_SPACE(sizeof(int)); + msg.msg_control = calloc(1, msg.msg_controllen); + if (msg.msg_control == NULL) + return (-1); + + ret = -1; + + if (msg_recv(sock, &msg) == -1) + goto end; + + for (i = 0, cmsg = CMSG_FIRSTHDR(&msg); i < nfds && cmsg != NULL; + i++, cmsg = CMSG_NXTHDR(&msg, cmsg)) { + fds[i] = msghdr_get_fd(cmsg); + if (fds[i] < 0) + break; + } + + if (cmsg != NULL || i < nfds) { + int fd; + + /* + * We need to close all received descriptors, even if we have + * different control message (eg. SCM_CREDS) in between. + */ + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + fd = msghdr_get_fd(cmsg); + if (fd >= 0) + close(fd); + } + errno = EINVAL; + goto end; + } + + ret = 0; +end: + serrno = errno; + free(msg.msg_control); + errno = serrno; + return (ret); +} + +int +buf_send(int sock, void *buf, size_t size) +{ + ssize_t done; + unsigned char *ptr; + + PJDLOG_ASSERT(sock >= 0); + PJDLOG_ASSERT(size > 0); + PJDLOG_ASSERT(buf != NULL); + + ptr = buf; + do { + fd_wait(sock, false); + done = send(sock, ptr, size, 0); + if (done == -1) { + if (errno == EINTR) + continue; + return (-1); + } else if (done == 0) { + errno = ENOTCONN; + return (-1); + } + size -= done; + ptr += done; + } while (size > 0); + + return (0); +} + +int +buf_recv(int sock, void *buf, size_t size) +{ + ssize_t done; + unsigned char *ptr; + + PJDLOG_ASSERT(sock >= 0); + PJDLOG_ASSERT(buf != NULL); + + ptr = buf; + while (size > 0) { + fd_wait(sock, true); + done = recv(sock, ptr, size, 0); + if (done == -1) { + if (errno == EINTR) + continue; + return (-1); + } else if (done == 0) { + errno = ENOTCONN; + return (-1); + } + size -= done; + ptr += done; + } + + return (0); +} diff --git a/lib/libkse/thread/thr_equal.c b/lib/libnv/msgio.h index ab6f884..fd5e462 100644 --- a/lib/libkse/thread/thr_equal.c +++ b/lib/libnv/msgio.h @@ -1,7 +1,12 @@ -/* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. +/*- + * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org> + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -10,14 +15,11 @@ * 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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) @@ -29,16 +31,20 @@ * $FreeBSD$ */ -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" +#ifndef _MSGIO_H_ +#define _MSGIO_H_ + +struct cmsgcred; +struct iovec; +struct msghdr; + +int cred_send(int sock); +int cred_recv(int sock, struct cmsgcred *cred); + +int fd_send(int sock, const int *fds, size_t nfds); +int fd_recv(int sock, int *fds, size_t nfds); -__weak_reference(_pthread_equal, pthread_equal); +int buf_send(int sock, void *buf, size_t size); +int buf_recv(int sock, void *buf, size_t size); -int -_pthread_equal(pthread_t t1, pthread_t t2) -{ - /* Compare the two thread pointers: */ - return (t1 == t2); -} +#endif /* !_MSGIO_H_ */ diff --git a/lib/libnv/nv.3 b/lib/libnv/nv.3 new file mode 100644 index 0000000..118f5bb --- /dev/null +++ b/lib/libnv/nv.3 @@ -0,0 +1,604 @@ +.\" +.\" Copyright (c) 2013 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 21, 2014 +.Dt NV 3 +.Os +.Sh NAME +.Nm nvlist_create , +.Nm nvlist_destroy , +.Nm nvlist_error , +.Nm nvlist_empty , +.Nm nvlist_exists , +.Nm nvlist_free , +.Nm nvlist_clone , +.Nm nvlist_dump , +.Nm nvlist_fdump , +.Nm nvlist_size , +.Nm nvlist_pack , +.Nm nvlist_unpack , +.Nm nvlist_send , +.Nm nvlist_recv , +.Nm nvlist_xfer , +.Nm nvlist_next , +.Nm nvlist_add , +.Nm nvlist_move , +.Nm nvlist_get , +.Nm nvlist_take +.Nd "library for name/value pairs" +.Sh LIBRARY +.Lb libnv +.Sh SYNOPSIS +.In nv.h +.Ft "nvlist_t *" +.Fn nvlist_create "int flags" +.Ft void +.Fn nvlist_destroy "nvlist_t *nvl" +.Ft int +.Fn nvlist_error "const nvlist_t *nvl" +.Ft bool +.Fn nvlist_empty "const nvlist_t *nvl" +.\" +.Ft "nvlist_t *" +.Fn nvlist_clone "const nvlist_t *nvl" +.\" +.Ft void +.Fn nvlist_dump "const nvlist_t *nvl, int fd" +.Ft void +.Fn nvlist_fdump "const nvlist_t *nvl, FILE *fp" +.\" +.Ft size_t +.Fn nvlist_size "const nvlist_t *nvl" +.Ft "void *" +.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep" +.Ft "nvlist_t *" +.Fn nvlist_unpack "const void *buf" "size_t size" +.\" +.Ft int +.Fn nvlist_send "int sock" "const nvlist_t *nvl" +.Ft "nvlist_t *" +.Fn nvlist_recv "int sock" +.Ft "nvlist_t *" +.Fn nvlist_xfer "int sock" "nvlist_t *nvl" +.\" +.Ft "const char *" +.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep" +.\" +.Ft bool +.Fn nvlist_exists "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type" +.Ft bool +.Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name" +.Ft bool +.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name" +.\" +.Ft void +.Fn nvlist_add_null "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value" +.Ft void +.Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value" +.Ft void +.Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value" +.Ft void +.Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..." +.Ft void +.Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap" +.Ft void +.Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value" +.Ft void +.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value" +.Ft void +.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size" +.\" +.Ft void +.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value" +.Ft void +.Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value" +.Ft void +.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value" +.Ft void +.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size" +.\" +.Ft bool +.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name" +.Ft uint64_t +.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name" +.Ft "const char *" +.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" +.Ft "const nvlist_t *" +.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name" +.Ft int +.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name" +.Ft "const void *" +.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep" +.\" +.Ft bool +.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name" +.Ft uint64_t +.Fn nvlist_take_number "nvlist_t *nvl" "const char *name" +.Ft "char *" +.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" +.Ft "nvlist_t *" +.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" +.Ft int +.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name" +.Ft "void *" +.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep" +.\" +.Ft void +.Fn nvlist_free "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type" +.\" +.Ft void +.Fn nvlist_free_null "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_bool "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_number "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_string "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name" +.Ft void +.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name" +.Sh DESCRIPTION +The +.Nm libnv +library allows to easily manage name value pairs as well as send and receive +them over sockets. +A group (list) of name value pairs is called an +.Nm nvlist . +The API supports the following data types: +.Bl -ohang -offset indent +.It Sy null ( NV_TYPE_NULL ) +There is no data associated with the name. +.It Sy bool ( NV_TYPE_BOLL ) +The value can be either +.Dv true +or +.Dv false . +.It Sy number ( NV_TYPE_NUMBER ) +The value is a number stored as +.Vt uint64_t . +.It Sy string ( NV_TYPE_STRING ) +The value is a C string. +.It Sy nvlist ( NV_TYPE_NVLIST ) +The value is a nested nvlist. +.It Sy descriptor ( NV_TYPE_DESCRIPTOR ) +The value is a file descriptor. +Note that file descriptors can be sent only over +.Xr unix 4 +domain sockets. +.It Sy binary ( NV_TYPE_BINARY ) +The value is a binary buffer. +.El +.Pp +The +.Fn nvlist_create +function allocates memory and initializes an nvlist. +.Pp +The following flag can be provided: +.Pp +.Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent +.It Dv NV_FLAG_IGNORE_CASE +Perform case-insensitive lookups of provided names. +.El +.Pp +The +.Fn nvlist_destroy +function destroys the given nvlist. +Function does nothing if +.Dv NULL +nvlist is provided. +Function never modifies the +.Va errno +global variable. +.Pp +The +.Fn nvlist_error +function returns any error value that the nvlist accumulated. +If the given nvlist is +.Dv NULL +the +.Er ENOMEM +error will be returned. +.Pp +The +.Fn nvlist_empty +functions returns +.Dv true +if the given nvlist is empty and +.Dv false +otherwise. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_clone +functions clones the given nvlist. +The clone shares no resources with its origin. +This also means that all file descriptors that are part of the nvlist will be +duplicated with the +.Xr dup 2 +system call before placing them in the clone. +.Pp +The +.Fn nvlist_dump +dumps nvlist content for debugging purposes to the given file descriptor +.Fa fd . +.Pp +The +.Fn nvlist_fdump +dumps nvlist content for debugging purposes to the given file stream +.Fa fp . +.Pp +The +.Fn nvlist_size +function returns the size of the given nvlist after converting it to binary +buffer with the +.Fn nvlist_pack +function. +.Pp +The +.Fn nvlist_pack +function converts the given nvlist to a binary buffer. +The function allocates memory for the buffer, which should be freed with the +.Xr free 3 +function. +If the +.Fa sizep +argument is not +.Dv NULL , +the size of the buffer will be stored there. +The function returns +.Dv NULL +in case of an error (allocation failure). +If the nvlist contains any file descriptors +.Dv NULL +will be returned. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_unpack +function converts the given buffer to the nvlist. +The function returns +.Dv NULL +in case of an error. +.Pp +The +.Fn nvlist_send +function sends the given nvlist over the socket given by the +.Fa sock +argument. +Note that nvlist that contains file descriptors can only be send over +.Xr unix 4 +domain sockets. +.Pp +The +.Fn nvlist_recv +function receives nvlist over the socket given by the +.Fa sock +argument. +.Pp +The +.Fn nvlist_xfer +function sends the given nvlist over the socket given by the +.Fa sock +argument and receives nvlist over the same socket. +The given nvlist is always destroyed. +.Pp +The +.Fn nvlist_next +function iterates over the given nvlist returning names and types of subsequent +elements. +The +.Fa cookiep +argument allows the function to figure out which element should be returned +next. +The +.Va *cookiep +should be set to +.Dv NULL +for the first call and should not be changed later. +Returning +.Dv NULL +means there are no more elements on the nvlist. +The +.Fa typep +argument can be NULL. +Elements may not be removed from the nvlist while traversing it. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_exists +function returns +.Dv true +if element of the given name exists (besides of its type) or +.Dv false +otherwise. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_exists_type +function returns +.Dv true +if element of the given name and the given type exists or +.Dv false +otherwise. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_exists_null , +.Fn nvlist_exists_bool , +.Fn nvlist_exists_number , +.Fn nvlist_exists_string , +.Fn nvlist_exists_nvlist , +.Fn nvlist_exists_descriptor , +.Fn nvlist_exists_binary +functions return +.Dv true +if element of the given name and the given type determined by the function name +exists or +.Dv false +otherwise. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_add_null , +.Fn nvlist_add_bool , +.Fn nvlist_add_number , +.Fn nvlist_add_string , +.Fn nvlist_add_stringf , +.Fn nvlist_add_stringv , +.Fn nvlist_add_nvlist , +.Fn nvlist_add_descriptor , +.Fn nvlist_add_binary +functions add element to the given nvlist. +When adding string or binary buffor the functions will allocate memory +and copy the data over. +When adding nvlist, the nvlist will be cloned and clone will be added. +When adding descriptor, the descriptor will be duplicated using the +.Xr dup 2 +system call and the new descriptor will be added. +If an error occurs while adding new element, internal error is set which can be +examined using the +.Fn nvlist_error +function. +.Pp +The +.Fn nvlist_move_string , +.Fn nvlist_move_nvlist , +.Fn nvlist_move_descriptor , +.Fn nvlist_move_binary +functions add new element to the given nvlist, but unlike +.Fn nvlist_add_<type> +functions they will consume the given resource. +If an error occurs while adding new element, the resource is destroyed and +internal error is set which can be examined using the +.Fn nvlist_error +function. +.Pp +The +.Fn nvlist_get_bool , +.Fn nvlist_get_number , +.Fn nvlist_get_string , +.Fn nvlist_get_nvlist , +.Fn nvlist_get_descriptor , +.Fn nvlist_get_binary +functions allow to obtain value of the given name. +In case of string, nvlist, descriptor or binary, returned resource should +not be modified - it still belongs to the nvlist. +If element of the given name does not exist, the program will be aborted. +To avoid that the caller should check for existence before trying to obtain +the value or use +.Xr dnvlist 3 +extension, which allows to provide default value for a missing element. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_take_bool , +.Fn nvlist_take_number , +.Fn nvlist_take_string , +.Fn nvlist_take_nvlist , +.Fn nvlist_take_descriptor , +.Fn nvlist_take_binary +functions return value associated with the given name and remove the element +from the nvlist. +In case of string and binary values, the caller is responsible for free returned +memory using the +.Xr free 3 +function. +In case of nvlist, the caller is responsible for destroying returned nvlist +using the +.Fn nvlist_destroy +function. +In case of descriptor, the caller is responsible for closing returned descriptor +using the +.Fn close 2 +system call. +If element of the given name does not exist, the program will be aborted. +To avoid that the caller should check for existence before trying to obtain +the value or use +.Xr dnvlist 3 +extension, which allows to provide default value for a missing element. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_free +function removes element of the given name from the nvlist (besides of its type) +and frees all resources associated with it. +If element of the given name does not exist, the program will be aborted. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_free_type +function removes element of the given name and the given type from the nvlist +and frees all resources associated with it. +If element of the given name and the given type does not exist, the program +will be aborted. +The nvlist must not be in error state. +.Pp +The +.Fn nvlist_free_null , +.Fn nvlist_free_bool , +.Fn nvlist_free_number , +.Fn nvlist_free_string , +.Fn nvlist_free_nvlist , +.Fn nvlist_free_descriptor , +.Fn nvlist_free_binary +functions remove element of the given name and the given type determined by the +function name from the nvlist and free all resources associated with it. +If element of the given name and the given type does not exist, the program +will be aborted. +The nvlist must not be in error state. +.Sh EXAMPLES +The following example demonstrates how to prepare an nvlist and send it over +.Xr unix 4 +domain socket. +.Bd -literal +nvlist_t *nvl; +int fd; + +fd = open("/tmp/foo", O_RDONLY); +if (fd < 0) + err(1, "open(\\"/tmp/foo\\") failed"); + +nvl = nvlist_create(0); +/* + * There is no need to check if nvlist_create() succeeded, + * as the nvlist_add_<type>() functions can cope. + * If it failed, nvlist_send() will fail. + */ +nvlist_add_string(nvl, "filename", "/tmp/foo"); +nvlist_add_number(nvl, "flags", O_RDONLY); +/* + * We just want to send the descriptor, so we can give it + * for the nvlist to consume (that's why we use nvlist_move + * not nvlist_add). + */ +nvlist_move_descriptor(nvl, "fd", fd); +if (nvlist_send(sock, nvl) < 0) { + nvlist_destroy(nvl); + err(1, "nvlist_send() failed"); +} +nvlist_destroy(nvl); +.Ed +.Pp +Receiving nvlist and getting data: +.Bd -literal +nvlist_t *nvl; +const char *command; +char *filename; +int fd; + +nvl = nvlist_recv(sock); +if (nvl == NULL) + err(1, "nvlist_recv() failed"); + +/* For command we take pointer to nvlist's buffer. */ +command = nvlist_get_string(nvl, "command"); +/* + * For filename we remove it from the nvlist and take + * ownership of the buffer. + */ +filename = nvlist_take_string(nvl, "filename"); +/* The same for the descriptor. */ +fd = nvlist_take_descriptor(nvl, "fd"); + +printf("command=%s filename=%s fd=%d\n", command, filename, fd); + +nvlist_destroy(nvl); +free(filename); +close(fd); +/* command was freed by nvlist_destroy() */ +.Ed +.Pp +Iterating over nvlist: +.Bd -literal +nvlist_t *nvl; +const char *name; +void *cookie; +int type; + +nvl = nvlist_recv(sock); +if (nvl == NULL) + err(1, "nvlist_recv() failed"); + +cookie = NULL; +while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { + printf("%s=", name); + switch (type) { + case NV_TYPE_NUMBER: + printf("%ju", (uintmax_t)nvlist_get_number(nvl, name)); + break; + case NV_TYPE_STRING: + printf("%s", nvlist_get_string(nvl, name)); + break; + default: + printf("N/A"); + break; + } + printf("\\n"); +} +.Ed +.Sh SEE ALSO +.Xr close 2 , +.Xr dup 2 , +.Xr open 2 , +.Xr err 3 , +.Xr free 3 , +.Xr printf 3 , +.Xr unix 4 +.Sh HISTORY +The +.Nm libnv +library appeared in +.Fx 11.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm libnv +library was implemented by +.An Pawel Jakub Dawidek Aq pawel@dawidek.net +under sponsorship from the FreeBSD Foundation. diff --git a/lib/libnv/nv.h b/lib/libnv/nv.h new file mode 100644 index 0000000..e2d7030 --- /dev/null +++ b/lib/libnv/nv.h @@ -0,0 +1,273 @@ +/*- + * Copyright (c) 2009-2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NV_H_ +#define _NV_H_ + +#include <sys/cdefs.h> + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#ifndef _NVLIST_T_DECLARED +#define _NVLIST_T_DECLARED +struct nvlist; + +typedef struct nvlist nvlist_t; +#endif + +#define NV_NAME_MAX 2048 + +#define NV_TYPE_NONE 0 + +#define NV_TYPE_NULL 1 +#define NV_TYPE_BOOL 2 +#define NV_TYPE_NUMBER 3 +#define NV_TYPE_STRING 4 +#define NV_TYPE_NVLIST 5 +#define NV_TYPE_DESCRIPTOR 6 +#define NV_TYPE_BINARY 7 + +/* + * Perform case-insensitive lookups of provided names. + */ +#define NV_FLAG_IGNORE_CASE 0x01 + +nvlist_t *nvlist_create(int flags); +void nvlist_destroy(nvlist_t *nvl); +int nvlist_error(const nvlist_t *nvl); +bool nvlist_empty(const nvlist_t *nvl); + +nvlist_t *nvlist_clone(const nvlist_t *nvl); + +void nvlist_dump(const nvlist_t *nvl, int fd); +void nvlist_fdump(const nvlist_t *nvl, FILE *fp); + +size_t nvlist_size(const nvlist_t *nvl); +void *nvlist_pack(const nvlist_t *nvl, size_t *sizep); +nvlist_t *nvlist_unpack(const void *buf, size_t size); + +int nvlist_send(int sock, const nvlist_t *nvl); +nvlist_t *nvlist_recv(int sock); +nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl); + +const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep); + +/* + * The nvlist_exists functions check if the given name (optionally of the given + * type) exists on nvlist. + */ + +bool nvlist_exists(const nvlist_t *nvl, const char *name); +bool nvlist_exists_type(const nvlist_t *nvl, const char *name, int type); + +bool nvlist_exists_null(const nvlist_t *nvl, const char *name); +bool nvlist_exists_bool(const nvlist_t *nvl, const char *name); +bool nvlist_exists_number(const nvlist_t *nvl, const char *name); +bool nvlist_exists_string(const nvlist_t *nvl, const char *name); +bool nvlist_exists_nvlist(const nvlist_t *nvl, const char *name); +bool nvlist_exists_descriptor(const nvlist_t *nvl, const char *name); +bool nvlist_exists_binary(const nvlist_t *nvl, const char *name); + +/* + * The nvlist_add functions add the given name/value pair. + * If a pointer is provided, nvlist_add will internally allocate memory for the + * given data (in other words it won't consume provided buffer). + */ + +void nvlist_add_null(nvlist_t *nvl, const char *name); +void nvlist_add_bool(nvlist_t *nvl, const char *name, bool value); +void nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value); +void nvlist_add_string(nvlist_t *nvl, const char *name, const char *value); +void nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...) __printflike(3, 4); +void nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, va_list valueap) __printflike(3, 0); +void nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value); +void nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value); +void nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, size_t size); + +/* + * The nvlist_move functions add the given name/value pair. + * The functions consumes provided buffer. + */ + +void nvlist_move_string(nvlist_t *nvl, const char *name, char *value); +void nvlist_move_nvlist(nvlist_t *nvl, const char *name, nvlist_t *value); +void nvlist_move_descriptor(nvlist_t *nvl, const char *name, int value); +void nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size); + +/* + * The nvlist_get functions returns value associated with the given name. + * If it returns a pointer, the pointer represents internal buffer and should + * not be freed by the caller. + */ + +bool nvlist_get_bool(const nvlist_t *nvl, const char *name); +uint64_t nvlist_get_number(const nvlist_t *nvl, const char *name); +const char *nvlist_get_string(const nvlist_t *nvl, const char *name); +const nvlist_t *nvlist_get_nvlist(const nvlist_t *nvl, const char *name); +int nvlist_get_descriptor(const nvlist_t *nvl, const char *name); +const void *nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep); + +/* + * The nvlist_take functions returns value associated with the given name and + * remove the given entry from the nvlist. + * The caller is responsible for freeing received data. + */ + +bool nvlist_take_bool(nvlist_t *nvl, const char *name); +uint64_t nvlist_take_number(nvlist_t *nvl, const char *name); +char *nvlist_take_string(nvlist_t *nvl, const char *name); +nvlist_t *nvlist_take_nvlist(nvlist_t *nvl, const char *name); +int nvlist_take_descriptor(nvlist_t *nvl, const char *name); +void *nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep); + +/* + * The nvlist_free functions removes the given name/value pair from the nvlist + * and frees memory associated with it. + */ + +void nvlist_free(nvlist_t *nvl, const char *name); +void nvlist_free_type(nvlist_t *nvl, const char *name, int type); + +void nvlist_free_null(nvlist_t *nvl, const char *name); +void nvlist_free_bool(nvlist_t *nvl, const char *name); +void nvlist_free_number(nvlist_t *nvl, const char *name); +void nvlist_free_string(nvlist_t *nvl, const char *name); +void nvlist_free_nvlist(nvlist_t *nvl, const char *name); +void nvlist_free_descriptor(nvlist_t *nvl, const char *name); +void nvlist_free_binary(nvlist_t *nvl, const char *name); + +/* + * Below are the same functions, but which operate on format strings and + * variable argument lists. + */ + +bool nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4); + +bool nvlist_existsf_null(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +bool nvlist_existsf_binary(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); + +bool nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0); + +bool nvlist_existsv_null(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +bool nvlist_existsv_binary(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); + +void nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, ...) __printflike(4, 5); + +void nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0); + +void nvlist_movef_string(nvlist_t *nvl, char *value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_movef_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_movef_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4); +void nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, ...) __printflike(4, 5); + +void nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0); +void nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0); + +bool nvlist_getf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +uint64_t nvlist_getf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +const char *nvlist_getf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +const nvlist_t *nvlist_getf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +int nvlist_getf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +const void *nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4); + +bool nvlist_getv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +uint64_t nvlist_getv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +const char *nvlist_getv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +const nvlist_t *nvlist_getv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +int nvlist_getv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +const void *nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0); + +bool nvlist_takef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +uint64_t nvlist_takef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +char *nvlist_takef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +nvlist_t *nvlist_takef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +int nvlist_takef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void *nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4); + +bool nvlist_takev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +uint64_t nvlist_takev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +char *nvlist_takev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +nvlist_t *nvlist_takev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +int nvlist_takev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void *nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0); + +void nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4); + +void nvlist_freef_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); +void nvlist_freef_binary(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); + +void nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0); + +void nvlist_freev_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); +void nvlist_freev_binary(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); + +#endif /* !_NV_H_ */ diff --git a/lib/libnv/nv_impl.h b/lib/libnv/nv_impl.h new file mode 100644 index 0000000..3206006 --- /dev/null +++ b/lib/libnv/nv_impl.h @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NV_IMPL_H_ +#define _NV_IMPL_H_ + +#ifndef _NVPAIR_T_DECLARED +#define _NVPAIR_T_DECLARED +struct nvpair; + +typedef struct nvpair nvpair_t; +#endif + +#define NV_TYPE_FIRST NV_TYPE_NULL +#define NV_TYPE_LAST NV_TYPE_BINARY + +#define NV_FLAG_BIG_ENDIAN 0x80 + +int *nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp); +size_t nvlist_ndescriptors(const nvlist_t *nvl); + +nvpair_t *nvlist_first_nvpair(const nvlist_t *nvl); +nvpair_t *nvlist_next_nvpair(const nvlist_t *nvl, const nvpair_t *nvp); +nvpair_t *nvlist_prev_nvpair(const nvlist_t *nvl, const nvpair_t *nvp); + +void nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp); + +void nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp); + +const nvpair_t *nvlist_get_nvpair(const nvlist_t *nvl, const char *name); + +nvpair_t *nvlist_take_nvpair(nvlist_t *nvl, const char *name); + +/* Function removes the given nvpair from the nvlist. */ +void nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp); + +void nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp); + +int nvpair_type(const nvpair_t *nvp); +const char *nvpair_name(const nvpair_t *nvp); + +nvpair_t *nvpair_clone(const nvpair_t *nvp); + +nvpair_t *nvpair_create_null(const char *name); +nvpair_t *nvpair_create_bool(const char *name, bool value); +nvpair_t *nvpair_create_number(const char *name, uint64_t value); +nvpair_t *nvpair_create_string(const char *name, const char *value); +nvpair_t *nvpair_create_stringf(const char *name, const char *valuefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) __printflike(2, 0); +nvpair_t *nvpair_create_nvlist(const char *name, const nvlist_t *value); +nvpair_t *nvpair_create_descriptor(const char *name, int value); +nvpair_t *nvpair_create_binary(const char *name, const void *value, size_t size); + +nvpair_t *nvpair_move_string(const char *name, char *value); +nvpair_t *nvpair_move_nvlist(const char *name, nvlist_t *value); +nvpair_t *nvpair_move_descriptor(const char *name, int value); +nvpair_t *nvpair_move_binary(const char *name, void *value, size_t size); + +bool nvpair_get_bool(const nvpair_t *nvp); +uint64_t nvpair_get_number(const nvpair_t *nvp); +const char *nvpair_get_string(const nvpair_t *nvp); +const nvlist_t *nvpair_get_nvlist(const nvpair_t *nvp); +int nvpair_get_descriptor(const nvpair_t *nvp); +const void *nvpair_get_binary(const nvpair_t *nvp, size_t *sizep); + +void nvpair_free(nvpair_t *nvp); + +const nvpair_t *nvlist_getf_nvpair(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); + +const nvpair_t *nvlist_getv_nvpair(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); + +nvpair_t *nvlist_takef_nvpair(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3); + +nvpair_t *nvlist_takev_nvpair(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0); + +nvpair_t *nvpair_createf_null(const char *namefmt, ...) __printflike(1, 2); +nvpair_t *nvpair_createf_bool(bool value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_createf_number(uint64_t value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_createf_string(const char *value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_createf_descriptor(int value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) __printflike(3, 4); + +nvpair_t *nvpair_createv_null(const char *namefmt, va_list nameap) __printflike(1, 0); +nvpair_t *nvpair_createv_bool(bool value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_createv_binary(const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0); + +nvpair_t *nvpair_movef_string(char *value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_movef_descriptor(int value, const char *namefmt, ...) __printflike(2, 3); +nvpair_t *nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) __printflike(3, 4); + +nvpair_t *nvpair_movev_string(char *value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0); +nvpair_t *nvpair_movev_binary(void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0); + +#endif /* !_NV_IMPL_H_ */ diff --git a/lib/libnv/nvlist.c b/lib/libnv/nvlist.c new file mode 100644 index 0000000..929ba48 --- /dev/null +++ b/lib/libnv/nvlist.c @@ -0,0 +1,1707 @@ +/*- + * Copyright (c) 2009-2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/endian.h> +#include <sys/queue.h> +#include <sys/socket.h> + +#include <errno.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#define _WITH_DPRINTF +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_PJDLOG +#include <pjdlog.h> +#endif + +#include "msgio.h" +#include "nv.h" +#include "nv_impl.h" +#include "nvlist_impl.h" +#include "nvpair_impl.h" + +#ifndef HAVE_PJDLOG +#include <assert.h> +#define PJDLOG_ASSERT(...) assert(__VA_ARGS__) +#define PJDLOG_RASSERT(expr, ...) assert(expr) +#define PJDLOG_ABORT(...) do { \ + fprintf(stderr, "%s:%u: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + abort(); \ +} while (0) +#endif + +#define NV_FLAG_PRIVATE_MASK (NV_FLAG_BIG_ENDIAN) +#define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE) +#define NV_FLAG_ALL_MASK (NV_FLAG_PRIVATE_MASK | NV_FLAG_PUBLIC_MASK) + +#define NVLIST_MAGIC 0x6e766c /* "nvl" */ +struct nvlist { + int nvl_magic; + int nvl_error; + int nvl_flags; + struct nvl_head nvl_head; +}; + +#define NVLIST_ASSERT(nvl) do { \ + PJDLOG_ASSERT((nvl) != NULL); \ + PJDLOG_ASSERT((nvl)->nvl_magic == NVLIST_MAGIC); \ +} while (0) + +#define NVPAIR_ASSERT(nvp) nvpair_assert(nvp) + +#define NVLIST_HEADER_MAGIC 0x6c +#define NVLIST_HEADER_VERSION 0x00 +struct nvlist_header { + uint8_t nvlh_magic; + uint8_t nvlh_version; + uint8_t nvlh_flags; + uint64_t nvlh_descriptors; + uint64_t nvlh_size; +} __packed; + +nvlist_t * +nvlist_create(int flags) +{ + nvlist_t *nvl; + + PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0); + + nvl = malloc(sizeof(*nvl)); + nvl->nvl_error = 0; + nvl->nvl_flags = flags; + TAILQ_INIT(&nvl->nvl_head); + nvl->nvl_magic = NVLIST_MAGIC; + + return (nvl); +} + +void +nvlist_destroy(nvlist_t *nvl) +{ + nvpair_t *nvp; + int serrno; + + if (nvl == NULL) + return; + + serrno = errno; + + NVLIST_ASSERT(nvl); + + while ((nvp = nvlist_first_nvpair(nvl)) != NULL) { + nvlist_remove_nvpair(nvl, nvp); + nvpair_free(nvp); + } + nvl->nvl_magic = 0; + free(nvl); + + errno = serrno; +} + +int +nvlist_error(const nvlist_t *nvl) +{ + + if (nvl == NULL) + return (ENOMEM); + + NVLIST_ASSERT(nvl); + + return (nvl->nvl_error); +} + +bool +nvlist_empty(const nvlist_t *nvl) +{ + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + + return (nvlist_first_nvpair(nvl) == NULL); +} + +static void +nvlist_report_missing(int type, const char *namefmt, va_list nameap) +{ + char *name; + + vasprintf(&name, namefmt, nameap); + PJDLOG_ABORT("Element '%s' of type %s doesn't exist.", + name != NULL ? name : "N/A", nvpair_type_string(type)); +} + +static nvpair_t * +nvlist_findv(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + char *name; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(type == NV_TYPE_NONE || + (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); + + if (vasprintf(&name, namefmt, nameap) < 0) + return (NULL); + + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + if (type != NV_TYPE_NONE && nvpair_type(nvp) != type) + continue; + if ((nvl->nvl_flags & NV_FLAG_IGNORE_CASE) != 0) { + if (strcasecmp(nvpair_name(nvp), name) != 0) + continue; + } else { + if (strcmp(nvpair_name(nvp), name) != 0) + continue; + } + break; + } + + free(name); + + if (nvp == NULL) + errno = ENOENT; + + return (nvp); +} + +bool +nvlist_exists_type(const nvlist_t *nvl, const char *name, int type) +{ + + return (nvlist_existsf_type(nvl, type, "%s", name)); +} + +bool +nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) +{ + va_list nameap; + bool ret; + + va_start(nameap, namefmt); + ret = nvlist_existsv_type(nvl, type, namefmt, nameap); + va_end(nameap); + + return (ret); +} + +bool +nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, + va_list nameap) +{ + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(type == NV_TYPE_NONE || + (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); + + return (nvlist_findv(nvl, type, namefmt, nameap) != NULL); +} + +void +nvlist_free_type(nvlist_t *nvl, const char *name, int type) +{ + + nvlist_freef_type(nvl, type, "%s", name); +} + +void +nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_freev_type(nvl, type, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) +{ + va_list cnameap; + nvpair_t *nvp; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(type == NV_TYPE_NONE || + (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); + + va_copy(cnameap, nameap); + nvp = nvlist_findv(nvl, type, namefmt, cnameap); + va_end(cnameap); + if (nvp != NULL) + nvlist_free_nvpair(nvl, nvp); + else + nvlist_report_missing(type, namefmt, nameap); +} + +nvlist_t * +nvlist_clone(const nvlist_t *nvl) +{ + nvlist_t *newnvl; + nvpair_t *nvp, *newnvp; + + NVLIST_ASSERT(nvl); + + if (nvl->nvl_error != 0) { + errno = nvl->nvl_error; + return (NULL); + } + + newnvl = nvlist_create(nvl->nvl_flags & NV_FLAG_PUBLIC_MASK); + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + newnvp = nvpair_clone(nvp); + if (newnvp == NULL) + break; + nvlist_move_nvpair(newnvl, newnvp); + } + if (nvp != NULL) { + nvlist_destroy(newnvl); + return (NULL); + } + return (newnvl); +} + +/* + * Dump content of nvlist. + */ +static void +nvlist_xdump(const nvlist_t *nvl, int fd, int level) +{ + nvpair_t *nvp; + + PJDLOG_ASSERT(level < 3); + + if (nvlist_error(nvl) != 0) { + dprintf(fd, "%*serror: %d\n", level * 4, "", + nvlist_error(nvl)); + return; + } + + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp), + nvpair_type_string(nvpair_type(nvp))); + switch (nvpair_type(nvp)) { + case NV_TYPE_NULL: + dprintf(fd, " null\n"); + break; + case NV_TYPE_BOOL: + dprintf(fd, " %s\n", nvpair_get_bool(nvp) ? + "TRUE" : "FALSE"); + break; + case NV_TYPE_NUMBER: + dprintf(fd, " %ju (%jd) (0x%jx)\n", + (uintmax_t)nvpair_get_number(nvp), + (intmax_t)nvpair_get_number(nvp), + (uintmax_t)nvpair_get_number(nvp)); + break; + case NV_TYPE_STRING: + dprintf(fd, " [%s]\n", nvpair_get_string(nvp)); + break; + case NV_TYPE_NVLIST: + dprintf(fd, "\n"); + nvlist_xdump(nvpair_get_nvlist(nvp), fd, level + 1); + break; + case NV_TYPE_DESCRIPTOR: + dprintf(fd, " %d\n", nvpair_get_descriptor(nvp)); + break; + case NV_TYPE_BINARY: + { + const unsigned char *binary; + unsigned int ii; + size_t size; + + binary = nvpair_get_binary(nvp, &size); + dprintf(fd, " %zu ", size); + for (ii = 0; ii < size; ii++) + dprintf(fd, "%02hhx", binary[ii]); + dprintf(fd, "\n"); + break; + } + default: + PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp)); + } + } +} + +void +nvlist_dump(const nvlist_t *nvl, int fd) +{ + + nvlist_xdump(nvl, fd, 0); +} + +void +nvlist_fdump(const nvlist_t *nvl, FILE *fp) +{ + + fflush(fp); + nvlist_dump(nvl, fileno(fp)); +} + +/* + * The function obtains size of the nvlist after nvlist_pack(). + * Additional argument 'level' allows to track how deep are we as we obtain + * size of the NV_TYPE_NVLIST elements using recursion. We allow at most + * three levels of recursion. + */ +static size_t +nvlist_xsize(const nvlist_t *nvl, int level) +{ + const nvpair_t *nvp; + size_t size; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(level < 3); + + size = sizeof(struct nvlist_header); + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + size += nvpair_header_size(); + size += strlen(nvpair_name(nvp)) + 1; + if (nvpair_type(nvp) == NV_TYPE_NVLIST) + size += nvlist_xsize(nvpair_get_nvlist(nvp), level + 1); + else + size += nvpair_size(nvp); + } + + return (size); +} + +size_t +nvlist_size(const nvlist_t *nvl) +{ + + return (nvlist_xsize(nvl, 0)); +} + +static int * +nvlist_xdescriptors(const nvlist_t *nvl, int *descs, int level) +{ + const nvpair_t *nvp; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(level < 3); + + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + switch (nvpair_type(nvp)) { + case NV_TYPE_DESCRIPTOR: + *descs = nvpair_get_descriptor(nvp); + descs++; + break; + case NV_TYPE_NVLIST: + descs = nvlist_xdescriptors(nvpair_get_nvlist(nvp), + descs, level + 1); + break; + } + } + + return (descs); +} + +int * +nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp) +{ + size_t nitems; + int *fds; + + nitems = nvlist_ndescriptors(nvl); + fds = malloc(sizeof(fds[0]) * (nitems + 1)); + if (fds == NULL) + return (NULL); + if (nitems > 0) + nvlist_xdescriptors(nvl, fds, 0); + fds[nitems] = -1; + if (nitemsp != NULL) + *nitemsp = nitems; + return (fds); +} + +static size_t +nvlist_xndescriptors(const nvlist_t *nvl, int level) +{ + const nvpair_t *nvp; + size_t ndescs; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(nvl->nvl_error == 0); + PJDLOG_ASSERT(level < 3); + + ndescs = 0; + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + switch (nvpair_type(nvp)) { + case NV_TYPE_DESCRIPTOR: + ndescs++; + break; + case NV_TYPE_NVLIST: + ndescs += nvlist_xndescriptors(nvpair_get_nvlist(nvp), + level + 1); + break; + } + } + + return (ndescs); +} + +size_t +nvlist_ndescriptors(const nvlist_t *nvl) +{ + + return (nvlist_xndescriptors(nvl, 0)); +} + +static unsigned char * +nvlist_pack_header(const nvlist_t *nvl, unsigned char *ptr, size_t *leftp) +{ + struct nvlist_header nvlhdr; + + NVLIST_ASSERT(nvl); + + nvlhdr.nvlh_magic = NVLIST_HEADER_MAGIC; + nvlhdr.nvlh_version = NVLIST_HEADER_VERSION; + nvlhdr.nvlh_flags = nvl->nvl_flags; +#if BYTE_ORDER == BIG_ENDIAN + nvlhdr.nvlh_flags |= NV_FLAG_BIG_ENDIAN; +#endif + nvlhdr.nvlh_descriptors = nvlist_ndescriptors(nvl); + nvlhdr.nvlh_size = *leftp - sizeof(nvlhdr); + PJDLOG_ASSERT(*leftp >= sizeof(nvlhdr)); + memcpy(ptr, &nvlhdr, sizeof(nvlhdr)); + ptr += sizeof(nvlhdr); + *leftp -= sizeof(nvlhdr); + + return (ptr); +} + +void * +nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) +{ + unsigned char *buf, *ptr; + size_t left, size; + nvpair_t *nvp; + + NVLIST_ASSERT(nvl); + + if (nvl->nvl_error != 0) { + errno = nvl->nvl_error; + return (NULL); + } + + size = nvlist_size(nvl); + buf = malloc(size); + if (buf == NULL) + return (NULL); + + ptr = buf; + left = size; + + ptr = nvlist_pack_header(nvl, ptr, &left); + + for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + ptr = nvpair_pack(nvp, ptr, fdidxp, &left); + if (ptr == NULL) { + free(buf); + return (NULL); + } + } + + if (sizep != NULL) + *sizep = size; + return (buf); +} + +void * +nvlist_pack(const nvlist_t *nvl, size_t *sizep) +{ + + NVLIST_ASSERT(nvl); + + if (nvl->nvl_error != 0) { + errno = nvl->nvl_error; + return (NULL); + } + + if (nvlist_ndescriptors(nvl) > 0) { + errno = EOPNOTSUPP; + return (NULL); + } + + return (nvlist_xpack(nvl, NULL, sizep)); +} + +static bool +nvlist_check_header(struct nvlist_header *nvlhdrp) +{ + + if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) { + errno = EINVAL; + return (false); + } + if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) { + errno = EINVAL; + return (false); + } +#if BYTE_ORDER == BIG_ENDIAN + if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) == 0) { + nvlhdrp->nvlh_size = le64toh(nvlhdrp->nvlh_size); + nvlhdrp->nvlh_descriptors = le64toh(nvlhdrp->nvlh_descriptors); + } +#else + if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0) { + nvlhdrp->nvlh_size = be64toh(nvlhdrp->nvlh_size); + nvlhdrp->nvlh_descriptors = be64toh(nvlhdrp->nvlh_descriptors); + } +#endif + return (true); +} + +static const unsigned char * +nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds, + int *flagsp, size_t *leftp) +{ + struct nvlist_header nvlhdr; + + if (*leftp < sizeof(nvlhdr)) + goto failed; + + memcpy(&nvlhdr, ptr, sizeof(nvlhdr)); + + if (!nvlist_check_header(&nvlhdr)) + goto failed; + + if (nvlhdr.nvlh_size != *leftp - sizeof(nvlhdr)) + goto failed; + + /* + * nvlh_descriptors might be smaller than nfds in embedded nvlists. + */ + if (nvlhdr.nvlh_descriptors > nfds) + goto failed; + + if ((nvlhdr.nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) + goto failed; + + nvl->nvl_flags = (nvlhdr.nvlh_flags & NV_FLAG_PUBLIC_MASK); + + ptr += sizeof(nvlhdr); + *flagsp = (int)nvlhdr.nvlh_flags; + *leftp -= sizeof(nvlhdr); + + return (ptr); +failed: + errno = EINVAL; + return (NULL); +} + +nvlist_t * +nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds) +{ + const unsigned char *ptr; + nvlist_t *nvl; + nvpair_t *nvp; + size_t left; + int flags; + + left = size; + ptr = buf; + + nvl = nvlist_create(0); + if (nvl == NULL) + goto failed; + + ptr = nvlist_unpack_header(nvl, ptr, nfds, &flags, &left); + if (ptr == NULL) + goto failed; + + while (left > 0) { + ptr = nvpair_unpack(flags, ptr, &left, fds, nfds, &nvp); + if (ptr == NULL) + goto failed; + nvlist_move_nvpair(nvl, nvp); + } + + return (nvl); +failed: + nvlist_destroy(nvl); + return (NULL); +} + +nvlist_t * +nvlist_unpack(const void *buf, size_t size) +{ + + return (nvlist_xunpack(buf, size, NULL, 0)); +} + +int +nvlist_send(int sock, const nvlist_t *nvl) +{ + size_t datasize, nfds; + int *fds; + void *data; + int64_t fdidx; + int serrno, ret; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return (-1); + } + + fds = nvlist_descriptors(nvl, &nfds); + if (fds == NULL) + return (-1); + + ret = -1; + data = NULL; + fdidx = 0; + + data = nvlist_xpack(nvl, &fdidx, &datasize); + if (data == NULL) + goto out; + + if (buf_send(sock, data, datasize) == -1) + goto out; + + if (nfds > 0) { + if (fd_send(sock, fds, nfds) == -1) + goto out; + } + + ret = 0; +out: + serrno = errno; + free(fds); + free(data); + errno = serrno; + return (ret); +} + +nvlist_t * +nvlist_recv(int sock) +{ + struct nvlist_header nvlhdr; + nvlist_t *nvl, *ret; + unsigned char *buf; + size_t nfds, size; + int serrno, *fds; + + if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) + return (NULL); + + if (!nvlist_check_header(&nvlhdr)) + return (NULL); + + nfds = (size_t)nvlhdr.nvlh_descriptors; + size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; + + buf = malloc(size); + if (buf == NULL) + return (NULL); + + memcpy(buf, &nvlhdr, sizeof(nvlhdr)); + + ret = NULL; + fds = NULL; + + if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) + goto out; + + if (nfds > 0) { + fds = malloc(nfds * sizeof(fds[0])); + if (fds == NULL) + goto out; + if (fd_recv(sock, fds, nfds) == -1) + goto out; + } + + nvl = nvlist_xunpack(buf, size, fds, nfds); + if (nvl == NULL) + goto out; + + ret = nvl; +out: + serrno = errno; + free(buf); + free(fds); + errno = serrno; + + return (ret); +} + +nvlist_t * +nvlist_xfer(int sock, nvlist_t *nvl) +{ + + if (nvlist_send(sock, nvl) < 0) { + nvlist_destroy(nvl); + return (NULL); + } + nvlist_destroy(nvl); + return (nvlist_recv(sock)); +} + +nvpair_t * +nvlist_first_nvpair(const nvlist_t *nvl) +{ + + NVLIST_ASSERT(nvl); + + return (TAILQ_FIRST(&nvl->nvl_head)); +} + +nvpair_t * +nvlist_next_nvpair(const nvlist_t *nvl, const nvpair_t *nvp) +{ + nvpair_t *retnvp; + + NVLIST_ASSERT(nvl); + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); + + retnvp = nvpair_next(nvp); + PJDLOG_ASSERT(retnvp == NULL || nvpair_nvlist(retnvp) == nvl); + + return (retnvp); + +} + +nvpair_t * +nvlist_prev_nvpair(const nvlist_t *nvl, const nvpair_t *nvp) +{ + nvpair_t *retnvp; + + NVLIST_ASSERT(nvl); + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); + + retnvp = nvpair_prev(nvp); + PJDLOG_ASSERT(nvpair_nvlist(retnvp) == nvl); + + return (retnvp); +} + +const char * +nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep) +{ + nvpair_t *nvp; + + NVLIST_ASSERT(nvl); + PJDLOG_ASSERT(cookiep != NULL); + + if (*cookiep == NULL) + nvp = nvlist_first_nvpair(nvl); + else + nvp = nvlist_next_nvpair(nvl, *cookiep); + if (nvp == NULL) + return (NULL); + if (typep != NULL) + *typep = nvpair_type(nvp); + *cookiep = nvp; + return (nvpair_name(nvp)); +} + +bool +nvlist_exists(const nvlist_t *nvl, const char *name) +{ + + return (nvlist_existsf(nvl, "%s", name)); +} + +#define NVLIST_EXISTS(type) \ +bool \ +nvlist_exists_##type(const nvlist_t *nvl, const char *name) \ +{ \ + \ + return (nvlist_existsf_##type(nvl, "%s", name)); \ +} + +NVLIST_EXISTS(null) +NVLIST_EXISTS(bool) +NVLIST_EXISTS(number) +NVLIST_EXISTS(string) +NVLIST_EXISTS(nvlist) +NVLIST_EXISTS(descriptor) +NVLIST_EXISTS(binary) + +#undef NVLIST_EXISTS + +bool +nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) +{ + va_list nameap; + bool ret; + + va_start(nameap, namefmt); + ret = nvlist_existsv(nvl, namefmt, nameap); + va_end(nameap); + return (ret); +} + +#define NVLIST_EXISTSF(type) \ +bool \ +nvlist_existsf_##type(const nvlist_t *nvl, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + bool ret; \ + \ + va_start(nameap, namefmt); \ + ret = nvlist_existsv_##type(nvl, namefmt, nameap); \ + va_end(nameap); \ + return (ret); \ +} + +NVLIST_EXISTSF(null) +NVLIST_EXISTSF(bool) +NVLIST_EXISTSF(number) +NVLIST_EXISTSF(string) +NVLIST_EXISTSF(nvlist) +NVLIST_EXISTSF(descriptor) +NVLIST_EXISTSF(binary) + +#undef NVLIST_EXISTSF + +bool +nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) +{ + + return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap) != NULL); +} + +#define NVLIST_EXISTSV(type, TYPE) \ +bool \ +nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \ + va_list nameap) \ +{ \ + \ + return (nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, nameap) != \ + NULL); \ +} + +NVLIST_EXISTSV(null, NULL) +NVLIST_EXISTSV(bool, BOOL) +NVLIST_EXISTSV(number, NUMBER) +NVLIST_EXISTSV(string, STRING) +NVLIST_EXISTSV(nvlist, NVLIST) +NVLIST_EXISTSV(descriptor, DESCRIPTOR) +NVLIST_EXISTSV(binary, BINARY) + +#undef NVLIST_EXISTSV + +void +nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp) +{ + nvpair_t *newnvp; + + NVPAIR_ASSERT(nvp); + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + if (nvlist_exists(nvl, nvpair_name(nvp))) { + nvl->nvl_error = errno = EEXIST; + return; + } + + newnvp = nvpair_clone(nvp); + if (newnvp == NULL) { + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + return; + } + + nvpair_insert(&nvl->nvl_head, newnvp, nvl); +} + +void +nvlist_add_null(nvlist_t *nvl, const char *name) +{ + + nvlist_addf_null(nvl, "%s", name); +} + +void +nvlist_add_bool(nvlist_t *nvl, const char *name, bool value) +{ + + nvlist_addf_bool(nvl, value, "%s", name); +} + +void +nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value) +{ + + nvlist_addf_number(nvl, value, "%s", name); +} + +void +nvlist_add_string(nvlist_t *nvl, const char *name, const char *value) +{ + + nvlist_addf_string(nvl, value, "%s", name); +} + +void +nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...) +{ + va_list valueap; + + va_start(valueap, valuefmt); + nvlist_add_stringv(nvl, name, valuefmt, valueap); + va_end(valueap); +} + +void +nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, + va_list valueap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_create_stringv(name, valuefmt, valueap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value) +{ + + nvlist_addf_nvlist(nvl, value, "%s", name); +} + +void +nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value) +{ + + nvlist_addf_descriptor(nvl, value, "%s", name); +} + +void +nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, + size_t size) +{ + + nvlist_addf_binary(nvl, value, size, "%s", name); +} + +void +nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_null(nvl, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_bool(nvl, value, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_number(nvl, value, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_string(nvl, value, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, + ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_nvlist(nvl, value, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_descriptor(nvl, value, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, + const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_addv_binary(nvl, value, size, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_null(namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_bool(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_number(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_string(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_nvlist(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_descriptor(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, + const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_createv_binary(value, size, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvpair_nvlist(nvp) == NULL); + + if (nvlist_error(nvl) != 0) { + nvpair_free(nvp); + errno = nvlist_error(nvl); + return; + } + if (nvlist_exists(nvl, nvpair_name(nvp))) { + nvpair_free(nvp); + nvl->nvl_error = errno = EEXIST; + return; + } + + nvpair_insert(&nvl->nvl_head, nvp, nvl); +} + +#define NVLIST_MOVE(vtype, type) \ +void \ +nvlist_move_##type(nvlist_t *nvl, const char *name, vtype value) \ +{ \ + \ + nvlist_movef_##type(nvl, value, "%s", name); \ +} + +NVLIST_MOVE(char *, string) +NVLIST_MOVE(nvlist_t *, nvlist) +NVLIST_MOVE(int, descriptor) + +#undef NVLIST_MOVE + +void +nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size) +{ + + nvlist_movef_binary(nvl, value, size, "%s", name); +} + +#define NVLIST_MOVEF(vtype, type) \ +void \ +nvlist_movef_##type(nvlist_t *nvl, vtype value, const char *namefmt, \ + ...) \ +{ \ + va_list nameap; \ + \ + va_start(nameap, namefmt); \ + nvlist_movev_##type(nvl, value, namefmt, nameap); \ + va_end(nameap); \ +} + +NVLIST_MOVEF(char *, string) +NVLIST_MOVEF(nvlist_t *, nvlist) +NVLIST_MOVEF(int, descriptor) + +#undef NVLIST_MOVEF + +void +nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, + const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_movev_binary(nvl, value, size, namefmt, nameap); + va_end(nameap); +} + +void +nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + free(value); + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_movev_string(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + nvlist_destroy(value); + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_movev_nvlist(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + close(value); + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_movev_descriptor(value, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +void +nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, + const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (nvlist_error(nvl) != 0) { + free(value); + errno = nvlist_error(nvl); + return; + } + + nvp = nvpair_movev_binary(value, size, namefmt, nameap); + if (nvp == NULL) + nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); + else + nvlist_move_nvpair(nvl, nvp); +} + +#define NVLIST_GET(ftype, type) \ +ftype \ +nvlist_get_##type(const nvlist_t *nvl, const char *name) \ +{ \ + \ + return (nvlist_getf_##type(nvl, "%s", name)); \ +} + +NVLIST_GET(const nvpair_t *, nvpair) +NVLIST_GET(bool, bool) +NVLIST_GET(uint64_t, number) +NVLIST_GET(const char *, string) +NVLIST_GET(const nvlist_t *, nvlist) +NVLIST_GET(int, descriptor) + +#undef NVLIST_GET + +const void * +nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep) +{ + + return (nvlist_getf_binary(nvl, sizep, "%s", name)); +} + +#define NVLIST_GETF(ftype, type) \ +ftype \ +nvlist_getf_##type(const nvlist_t *nvl, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + ftype value; \ + \ + va_start(nameap, namefmt); \ + value = nvlist_getv_##type(nvl, namefmt, nameap); \ + va_end(nameap); \ + \ + return (value); \ +} + +NVLIST_GETF(const nvpair_t *, nvpair) +NVLIST_GETF(bool, bool) +NVLIST_GETF(uint64_t, number) +NVLIST_GETF(const char *, string) +NVLIST_GETF(const nvlist_t *, nvlist) +NVLIST_GETF(int, descriptor) + +#undef NVLIST_GETF + +const void * +nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) +{ + va_list nameap; + const void *value; + + va_start(nameap, namefmt); + value = nvlist_getv_binary(nvl, sizep, namefmt, nameap); + va_end(nameap); + + return (value); +} + +const nvpair_t * +nvlist_getv_nvpair(const nvlist_t *nvl, const char *namefmt, va_list nameap) +{ + + return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap)); +} + +#define NVLIST_GETV(ftype, type, TYPE) \ +ftype \ +nvlist_getv_##type(const nvlist_t *nvl, const char *namefmt, \ + va_list nameap) \ +{ \ + va_list cnameap; \ + const nvpair_t *nvp; \ + \ + va_copy(cnameap, nameap); \ + nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \ + va_end(cnameap); \ + if (nvp == NULL) \ + nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \ + return (nvpair_get_##type(nvp)); \ +} + +NVLIST_GETV(bool, bool, BOOL) +NVLIST_GETV(uint64_t, number, NUMBER) +NVLIST_GETV(const char *, string, STRING) +NVLIST_GETV(const nvlist_t *, nvlist, NVLIST) +NVLIST_GETV(int, descriptor, DESCRIPTOR) + +#undef NVLIST_GETV + +const void * +nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, + va_list nameap) +{ + va_list cnameap; + const nvpair_t *nvp; + + va_copy(cnameap, nameap); + nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap); + va_end(cnameap); + if (nvp == NULL) + nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap); + + return (nvpair_get_binary(nvp, sizep)); +} + +#define NVLIST_TAKE(ftype, type) \ +ftype \ +nvlist_take_##type(nvlist_t *nvl, const char *name) \ +{ \ + \ + return (nvlist_takef_##type(nvl, "%s", name)); \ +} + +NVLIST_TAKE(nvpair_t *, nvpair) +NVLIST_TAKE(bool, bool) +NVLIST_TAKE(uint64_t, number) +NVLIST_TAKE(char *, string) +NVLIST_TAKE(nvlist_t *, nvlist) +NVLIST_TAKE(int, descriptor) + +#undef NVLIST_TAKE + +void * +nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep) +{ + + return (nvlist_takef_binary(nvl, sizep, "%s", name)); +} + +#define NVLIST_TAKEF(ftype, type) \ +ftype \ +nvlist_takef_##type(nvlist_t *nvl, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + ftype value; \ + \ + va_start(nameap, namefmt); \ + value = nvlist_takev_##type(nvl, namefmt, nameap); \ + va_end(nameap); \ + \ + return (value); \ +} + +NVLIST_TAKEF(nvpair_t *, nvpair) +NVLIST_TAKEF(bool, bool) +NVLIST_TAKEF(uint64_t, number) +NVLIST_TAKEF(char *, string) +NVLIST_TAKEF(nvlist_t *, nvlist) +NVLIST_TAKEF(int, descriptor) + +#undef NVLIST_TAKEF + +void * +nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) +{ + va_list nameap; + void *value; + + va_start(nameap, namefmt); + value = nvlist_takev_binary(nvl, sizep, namefmt, nameap); + va_end(nameap); + + return (value); +} + +nvpair_t * +nvlist_takev_nvpair(nvlist_t *nvl, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + nvp = nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap); + if (nvp != NULL) + nvlist_remove_nvpair(nvl, nvp); + return (nvp); +} + +#define NVLIST_TAKEV(ftype, type, TYPE) \ +ftype \ +nvlist_takev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \ +{ \ + va_list cnameap; \ + nvpair_t *nvp; \ + ftype value; \ + \ + va_copy(cnameap, nameap); \ + nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \ + va_end(cnameap); \ + if (nvp == NULL) \ + nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \ + value = (ftype)(intptr_t)nvpair_get_##type(nvp); \ + nvlist_remove_nvpair(nvl, nvp); \ + nvpair_free_structure(nvp); \ + return (value); \ +} + +NVLIST_TAKEV(bool, bool, BOOL) +NVLIST_TAKEV(uint64_t, number, NUMBER) +NVLIST_TAKEV(char *, string, STRING) +NVLIST_TAKEV(nvlist_t *, nvlist, NVLIST) +NVLIST_TAKEV(int, descriptor, DESCRIPTOR) + +#undef NVLIST_TAKEV + +void * +nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, + va_list nameap) +{ + va_list cnameap; + nvpair_t *nvp; + void *value; + + va_copy(cnameap, nameap); + nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap); + va_end(cnameap); + if (nvp == NULL) + nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap); + + value = (void *)(intptr_t)nvpair_get_binary(nvp, sizep); + nvlist_remove_nvpair(nvl, nvp); + nvpair_free_structure(nvp); + return (value); +} + +void +nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp) +{ + + NVLIST_ASSERT(nvl); + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); + + nvpair_remove(&nvl->nvl_head, nvp, nvl); +} + +void +nvlist_free(nvlist_t *nvl, const char *name) +{ + + nvlist_freef(nvl, "%s", name); +} + +#define NVLIST_FREE(type) \ +void \ +nvlist_free_##type(nvlist_t *nvl, const char *name) \ +{ \ + \ + nvlist_freef_##type(nvl, "%s", name); \ +} + +NVLIST_FREE(null) +NVLIST_FREE(bool) +NVLIST_FREE(number) +NVLIST_FREE(string) +NVLIST_FREE(nvlist) +NVLIST_FREE(descriptor) +NVLIST_FREE(binary) + +#undef NVLIST_FREE + +void +nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) +{ + va_list nameap; + + va_start(nameap, namefmt); + nvlist_freev(nvl, namefmt, nameap); + va_end(nameap); +} + +#define NVLIST_FREEF(type) \ +void \ +nvlist_freef_##type(nvlist_t *nvl, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + \ + va_start(nameap, namefmt); \ + nvlist_freev_##type(nvl, namefmt, nameap); \ + va_end(nameap); \ +} + +NVLIST_FREEF(null) +NVLIST_FREEF(bool) +NVLIST_FREEF(number) +NVLIST_FREEF(string) +NVLIST_FREEF(nvlist) +NVLIST_FREEF(descriptor) +NVLIST_FREEF(binary) + +#undef NVLIST_FREEF + +void +nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap) +{ + + nvlist_freev_type(nvl, NV_TYPE_NONE, namefmt, nameap); +} + +#define NVLIST_FREEV(type, TYPE) \ +void \ +nvlist_freev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \ +{ \ + \ + nvlist_freev_type(nvl, NV_TYPE_##TYPE, namefmt, nameap); \ +} + +NVLIST_FREEV(null, NULL) +NVLIST_FREEV(bool, BOOL) +NVLIST_FREEV(number, NUMBER) +NVLIST_FREEV(string, STRING) +NVLIST_FREEV(nvlist, NVLIST) +NVLIST_FREEV(descriptor, DESCRIPTOR) +NVLIST_FREEV(binary, BINARY) +#undef NVLIST_FREEV + +void +nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp) +{ + + NVLIST_ASSERT(nvl); + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); + + nvlist_remove_nvpair(nvl, nvp); + nvpair_free(nvp); +} diff --git a/lib/libnv/nvlist_impl.h b/lib/libnv/nvlist_impl.h new file mode 100644 index 0000000..43a7bb0 --- /dev/null +++ b/lib/libnv/nvlist_impl.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NVLIST_IMPL_H_ +#define _NVLIST_IMPL_H_ + +#include <stdint.h> + +#include "nv.h" + +void *nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep); +nvlist_t *nvlist_xunpack(const void *buf, size_t size, const int *fds, + size_t nfds); + +#endif /* !_NVLIST_IMPL_H_ */ diff --git a/lib/libnv/nvpair.c b/lib/libnv/nvpair.c new file mode 100644 index 0000000..916444f --- /dev/null +++ b/lib/libnv/nvpair.c @@ -0,0 +1,1333 @@ +/*- + * Copyright (c) 2009-2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/endian.h> +#include <sys/queue.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_PJDLOG +#include <pjdlog.h> +#endif + +#include "common_impl.h" +#include "nv.h" +#include "nv_impl.h" +#include "nvlist_impl.h" +#include "nvpair_impl.h" + +#ifndef HAVE_PJDLOG +#include <assert.h> +#define PJDLOG_ASSERT(...) assert(__VA_ARGS__) +#define PJDLOG_RASSERT(expr, ...) assert(expr) +#define PJDLOG_ABORT(...) abort() +#endif + +#define NVPAIR_MAGIC 0x6e7670 /* "nvp" */ +struct nvpair { + int nvp_magic; + char *nvp_name; + int nvp_type; + uint64_t nvp_data; + size_t nvp_datasize; + nvlist_t *nvp_list; /* Used for sanity checks. */ + TAILQ_ENTRY(nvpair) nvp_next; +}; + +#define NVPAIR_ASSERT(nvp) do { \ + PJDLOG_ASSERT((nvp) != NULL); \ + PJDLOG_ASSERT((nvp)->nvp_magic == NVPAIR_MAGIC); \ +} while (0) + +struct nvpair_header { + uint8_t nvph_type; + uint16_t nvph_namesize; + uint64_t nvph_datasize; +} __packed; + + +void +nvpair_assert(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); +} + +const nvlist_t * +nvpair_nvlist(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_list); +} + +nvpair_t * +nvpair_next(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list != NULL); + + return (TAILQ_NEXT(nvp, nvp_next)); +} + +nvpair_t * +nvpair_prev(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list != NULL); + + return (TAILQ_PREV(nvp, nvl_head, nvp_next)); +} + +void +nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list == NULL); + PJDLOG_ASSERT(!nvlist_exists(nvl, nvpair_name(nvp))); + + TAILQ_INSERT_TAIL(head, nvp, nvp_next); + nvp->nvp_list = nvl; +} + +void +nvpair_remove(struct nvl_head *head, nvpair_t *nvp, const nvlist_t *nvl) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list == nvl); + + TAILQ_REMOVE(head, nvp, nvp_next); + nvp->nvp_list = NULL; +} + +nvpair_t * +nvpair_clone(const nvpair_t *nvp) +{ + nvpair_t *newnvp; + const char *name; + const void *data; + size_t datasize; + + NVPAIR_ASSERT(nvp); + + name = nvpair_name(nvp); + + switch (nvpair_type(nvp)) { + case NV_TYPE_NULL: + newnvp = nvpair_create_null(name); + break; + case NV_TYPE_BOOL: + newnvp = nvpair_create_bool(name, nvpair_get_bool(nvp)); + break; + case NV_TYPE_NUMBER: + newnvp = nvpair_create_number(name, nvpair_get_number(nvp)); + break; + case NV_TYPE_STRING: + newnvp = nvpair_create_string(name, nvpair_get_string(nvp)); + break; + case NV_TYPE_NVLIST: + newnvp = nvpair_create_nvlist(name, nvpair_get_nvlist(nvp)); + break; + case NV_TYPE_DESCRIPTOR: + newnvp = nvpair_create_descriptor(name, + nvpair_get_descriptor(nvp)); + break; + case NV_TYPE_BINARY: + data = nvpair_get_binary(nvp, &datasize); + newnvp = nvpair_create_binary(name, data, datasize); + break; + default: + PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp)); + } + + return (newnvp); +} + +size_t +nvpair_header_size(void) +{ + + return (sizeof(struct nvpair_header)); +} + +size_t +nvpair_size(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_datasize); +} + +static unsigned char * +nvpair_pack_header(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) +{ + struct nvpair_header nvphdr; + size_t namesize; + + NVPAIR_ASSERT(nvp); + + nvphdr.nvph_type = nvp->nvp_type; + namesize = strlen(nvp->nvp_name) + 1; + PJDLOG_ASSERT(namesize > 0 && namesize <= UINT16_MAX); + nvphdr.nvph_namesize = namesize; + nvphdr.nvph_datasize = nvp->nvp_datasize; + PJDLOG_ASSERT(*leftp >= sizeof(nvphdr)); + memcpy(ptr, &nvphdr, sizeof(nvphdr)); + ptr += sizeof(nvphdr); + *leftp -= sizeof(nvphdr); + + PJDLOG_ASSERT(*leftp >= namesize); + memcpy(ptr, nvp->nvp_name, namesize); + ptr += namesize; + *leftp -= namesize; + + return (ptr); +} + +static unsigned char * +nvpair_pack_null(const nvpair_t *nvp, unsigned char *ptr, + size_t *leftp __unused) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL); + + return (ptr); +} + +static unsigned char * +nvpair_pack_bool(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) +{ + uint8_t value; + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL); + + value = (uint8_t)nvp->nvp_data; + + PJDLOG_ASSERT(*leftp >= sizeof(value)); + memcpy(ptr, &value, sizeof(value)); + ptr += sizeof(value); + *leftp -= sizeof(value); + + return (ptr); +} + +static unsigned char * +nvpair_pack_number(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) +{ + uint64_t value; + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER); + + value = (uint64_t)nvp->nvp_data; + + PJDLOG_ASSERT(*leftp >= sizeof(value)); + memcpy(ptr, &value, sizeof(value)); + ptr += sizeof(value); + *leftp -= sizeof(value); + + return (ptr); +} + +static unsigned char * +nvpair_pack_string(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING); + + PJDLOG_ASSERT(*leftp >= nvp->nvp_datasize); + memcpy(ptr, (const void *)(intptr_t)nvp->nvp_data, nvp->nvp_datasize); + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + return (ptr); +} + +static unsigned char * +nvpair_pack_nvlist(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, + size_t *leftp) +{ + unsigned char *data; + size_t size; + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); + + if (nvp->nvp_datasize == 0) + return (ptr); + + data = nvlist_xpack((const nvlist_t *)(intptr_t)nvp->nvp_data, fdidxp, + &size); + if (data == NULL) + return (NULL); + + PJDLOG_ASSERT(size == nvp->nvp_datasize); + PJDLOG_ASSERT(*leftp >= nvp->nvp_datasize); + + memcpy(ptr, data, nvp->nvp_datasize); + free(data); + + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + return (ptr); +} + +static unsigned char * +nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, + size_t *leftp) +{ + int64_t value; + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); + + value = (int64_t)nvp->nvp_data; + if (value != -1) { + /* + * If there is a real descriptor here, we change its number + * to position in the array of descriptors send via control + * message. + */ + PJDLOG_ASSERT(fdidxp != NULL); + + value = *fdidxp; + (*fdidxp)++; + } + + PJDLOG_ASSERT(*leftp >= sizeof(value)); + memcpy(ptr, &value, sizeof(value)); + ptr += sizeof(value); + *leftp -= sizeof(value); + + return (ptr); +} + +static unsigned char * +nvpair_pack_binary(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); + + PJDLOG_ASSERT(*leftp >= nvp->nvp_datasize); + memcpy(ptr, (const void *)(intptr_t)nvp->nvp_data, nvp->nvp_datasize); + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + return (ptr); +} + +unsigned char * +nvpair_pack(nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, size_t *leftp) +{ + + NVPAIR_ASSERT(nvp); + + /* + * We have to update datasize for NV_TYPE_NVLIST on every pack, + * so that proper datasize is placed into nvpair_header + * during the nvpair_pack_header() call below. + */ + if (nvp->nvp_type == NV_TYPE_NVLIST) { + if (nvp->nvp_data == 0) { + nvp->nvp_datasize = 0; + } else { + nvp->nvp_datasize = + nvlist_size((const nvlist_t *)(intptr_t)nvp->nvp_data); + } + } + + ptr = nvpair_pack_header(nvp, ptr, leftp); + if (ptr == NULL) + return (NULL); + + switch (nvp->nvp_type) { + case NV_TYPE_NULL: + ptr = nvpair_pack_null(nvp, ptr, leftp); + break; + case NV_TYPE_BOOL: + ptr = nvpair_pack_bool(nvp, ptr, leftp); + break; + case NV_TYPE_NUMBER: + ptr = nvpair_pack_number(nvp, ptr, leftp); + break; + case NV_TYPE_STRING: + ptr = nvpair_pack_string(nvp, ptr, leftp); + break; + case NV_TYPE_NVLIST: + ptr = nvpair_pack_nvlist(nvp, ptr, fdidxp, leftp); + break; + case NV_TYPE_DESCRIPTOR: + ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, leftp); + break; + case NV_TYPE_BINARY: + ptr = nvpair_pack_binary(nvp, ptr, leftp); + break; + default: + PJDLOG_ABORT("Invalid type (%d).", nvp->nvp_type); + } + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_header(int flags, nvpair_t *nvp, const unsigned char *ptr, + size_t *leftp) +{ + struct nvpair_header nvphdr; + + if (*leftp < sizeof(nvphdr)) + goto failed; + + memcpy(&nvphdr, ptr, sizeof(nvphdr)); + ptr += sizeof(nvphdr); + *leftp -= sizeof(nvphdr); + +#if NV_TYPE_FIRST > 0 + if (nvphdr.nvph_type < NV_TYPE_FIRST) + goto failed; +#endif + if (nvphdr.nvph_type > NV_TYPE_LAST) + goto failed; + +#if BYTE_ORDER == BIG_ENDIAN + if ((flags & NV_FLAG_BIG_ENDIAN) == 0) { + nvphdr.nvph_namesize = le16toh(nvphdr.nvph_namesize); + nvphdr.nvph_datasize = le64toh(nvphdr.nvph_datasize); + } +#else + if ((flags & NV_FLAG_BIG_ENDIAN) != 0) { + nvphdr.nvph_namesize = be16toh(nvphdr.nvph_namesize); + nvphdr.nvph_datasize = be64toh(nvphdr.nvph_datasize); + } +#endif + + if (nvphdr.nvph_namesize > NV_NAME_MAX) + goto failed; + if (*leftp < nvphdr.nvph_namesize) + goto failed; + if (nvphdr.nvph_namesize < 1) + goto failed; + if (strnlen((const char *)ptr, nvphdr.nvph_namesize) != + (size_t)(nvphdr.nvph_namesize - 1)) { + goto failed; + } + + memcpy(nvp->nvp_name, ptr, nvphdr.nvph_namesize); + ptr += nvphdr.nvph_namesize; + *leftp -= nvphdr.nvph_namesize; + + if (*leftp < nvphdr.nvph_datasize) + goto failed; + + nvp->nvp_type = nvphdr.nvph_type; + nvp->nvp_data = 0; + nvp->nvp_datasize = nvphdr.nvph_datasize; + + return (ptr); +failed: + errno = EINVAL; + return (NULL); +} + +static const unsigned char * +nvpair_unpack_null(int flags __unused, nvpair_t *nvp, const unsigned char *ptr, + size_t *leftp __unused) +{ + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL); + + if (nvp->nvp_datasize != 0) { + errno = EINVAL; + return (NULL); + } + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_bool(int flags __unused, nvpair_t *nvp, const unsigned char *ptr, + size_t *leftp) +{ + uint8_t value; + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL); + + if (nvp->nvp_datasize != sizeof(value)) { + errno = EINVAL; + return (NULL); + } + if (*leftp < sizeof(value)) { + errno = EINVAL; + return (NULL); + } + + memcpy(&value, ptr, sizeof(value)); + ptr += sizeof(value); + *leftp -= sizeof(value); + + if (value != 0 && value != 1) { + errno = EINVAL; + return (NULL); + } + + nvp->nvp_data = (uint64_t)value; + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_number(int flags, nvpair_t *nvp, const unsigned char *ptr, + size_t *leftp) +{ + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER); + + if (nvp->nvp_datasize != sizeof(uint64_t)) { + errno = EINVAL; + return (NULL); + } + if (*leftp < sizeof(uint64_t)) { + errno = EINVAL; + return (NULL); + } + + if ((flags & NV_FLAG_BIG_ENDIAN) != 0) + nvp->nvp_data = be64dec(ptr); + else + nvp->nvp_data = le64dec(ptr); + ptr += sizeof(uint64_t); + *leftp -= sizeof(uint64_t); + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_string(int flags __unused, nvpair_t *nvp, + const unsigned char *ptr, size_t *leftp) +{ + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING); + + if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { + errno = EINVAL; + return (NULL); + } + + if (strnlen((const char *)ptr, nvp->nvp_datasize) != + nvp->nvp_datasize - 1) { + errno = EINVAL; + return (NULL); + } + + nvp->nvp_data = (uint64_t)(uintptr_t)strdup((const char *)ptr); + if (nvp->nvp_data == 0) + return (NULL); + + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_nvlist(int flags __unused, nvpair_t *nvp, + const unsigned char *ptr, size_t *leftp, const int *fds, size_t nfds) +{ + nvlist_t *value; + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); + + if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { + errno = EINVAL; + return (NULL); + } + + value = nvlist_xunpack(ptr, nvp->nvp_datasize, fds, nfds); + if (value == NULL) + return (NULL); + + nvp->nvp_data = (uint64_t)(uintptr_t)value; + + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_descriptor(int flags, nvpair_t *nvp, const unsigned char *ptr, + size_t *leftp, const int *fds, size_t nfds) +{ + int64_t idx; + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); + + if (nvp->nvp_datasize != sizeof(idx)) { + errno = EINVAL; + return (NULL); + } + if (*leftp < sizeof(idx)) { + errno = EINVAL; + return (NULL); + } + + if ((flags & NV_FLAG_BIG_ENDIAN) != 0) + idx = be64dec(ptr); + else + idx = le64dec(ptr); + + if (idx < 0) { + errno = EINVAL; + return (NULL); + } + + if ((size_t)idx >= nfds) { + errno = EINVAL; + return (NULL); + } + + nvp->nvp_data = (uint64_t)fds[idx]; + + ptr += sizeof(idx); + *leftp -= sizeof(idx); + + return (ptr); +} + +static const unsigned char * +nvpair_unpack_binary(int flags __unused, nvpair_t *nvp, + const unsigned char *ptr, size_t *leftp) +{ + void *value; + + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); + + if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { + errno = EINVAL; + return (NULL); + } + + value = malloc(nvp->nvp_datasize); + if (value == NULL) + return (NULL); + + memcpy(value, ptr, nvp->nvp_datasize); + ptr += nvp->nvp_datasize; + *leftp -= nvp->nvp_datasize; + + nvp->nvp_data = (uint64_t)(uintptr_t)value; + + return (ptr); +} + +const unsigned char * +nvpair_unpack(int flags, const unsigned char *ptr, size_t *leftp, + const int *fds, size_t nfds, nvpair_t **nvpp) +{ + nvpair_t *nvp, *tmp; + + nvp = calloc(1, sizeof(*nvp) + NV_NAME_MAX); + if (nvp == NULL) + return (NULL); + nvp->nvp_name = (char *)(nvp + 1); + + ptr = nvpair_unpack_header(flags, nvp, ptr, leftp); + if (ptr == NULL) + goto failed; + tmp = realloc(nvp, sizeof(*nvp) + strlen(nvp->nvp_name) + 1); + if (tmp == NULL) + goto failed; + nvp = tmp; + /* Update nvp_name after realloc(). */ + nvp->nvp_name = (char *)(nvp + 1); + + switch (nvp->nvp_type) { + case NV_TYPE_NULL: + ptr = nvpair_unpack_null(flags, nvp, ptr, leftp); + break; + case NV_TYPE_BOOL: + ptr = nvpair_unpack_bool(flags, nvp, ptr, leftp); + break; + case NV_TYPE_NUMBER: + ptr = nvpair_unpack_number(flags, nvp, ptr, leftp); + break; + case NV_TYPE_STRING: + ptr = nvpair_unpack_string(flags, nvp, ptr, leftp); + break; + case NV_TYPE_NVLIST: + ptr = nvpair_unpack_nvlist(flags, nvp, ptr, leftp, fds, + nfds); + break; + case NV_TYPE_DESCRIPTOR: + ptr = nvpair_unpack_descriptor(flags, nvp, ptr, leftp, fds, + nfds); + break; + case NV_TYPE_BINARY: + ptr = nvpair_unpack_binary(flags, nvp, ptr, leftp); + break; + default: + PJDLOG_ABORT("Invalid type (%d).", nvp->nvp_type); + } + + if (ptr == NULL) + goto failed; + + nvp->nvp_magic = NVPAIR_MAGIC; + *nvpp = nvp; + return (ptr); +failed: + free(nvp); + return (NULL); +} + +int +nvpair_type(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_type); +} + +const char * +nvpair_name(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_name); +} + +static nvpair_t * +nvpair_allocv(int type, uint64_t data, size_t datasize, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + char *name; + int namelen; + + PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST); + + namelen = vasprintf(&name, namefmt, nameap); + if (namelen < 0) + return (NULL); + + PJDLOG_ASSERT(namelen > 0); + if (namelen >= NV_NAME_MAX) { + free(name); + errno = ENAMETOOLONG; + return (NULL); + } + + nvp = calloc(1, sizeof(*nvp) + namelen + 1); + if (nvp != NULL) { + nvp->nvp_name = (char *)(nvp + 1); + memcpy(nvp->nvp_name, name, namelen + 1); + nvp->nvp_type = type; + nvp->nvp_data = data; + nvp->nvp_datasize = datasize; + nvp->nvp_magic = NVPAIR_MAGIC; + } + free(name); + + return (nvp); +}; + +nvpair_t * +nvpair_create_null(const char *name) +{ + + return (nvpair_createf_null("%s", name)); +} + +nvpair_t * +nvpair_create_bool(const char *name, bool value) +{ + + return (nvpair_createf_bool(value, "%s", name)); +} + +nvpair_t * +nvpair_create_number(const char *name, uint64_t value) +{ + + return (nvpair_createf_number(value, "%s", name)); +} + +nvpair_t * +nvpair_create_string(const char *name, const char *value) +{ + + return (nvpair_createf_string(value, "%s", name)); +} + +nvpair_t * +nvpair_create_stringf(const char *name, const char *valuefmt, ...) +{ + va_list valueap; + nvpair_t *nvp; + + va_start(valueap, valuefmt); + nvp = nvpair_create_stringv(name, valuefmt, valueap); + va_end(valueap); + + return (nvp); +} + +nvpair_t * +nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) +{ + nvpair_t *nvp; + char *str; + int len; + + len = vasprintf(&str, valuefmt, valueap); + if (len < 0) + return (NULL); + nvp = nvpair_create_string(name, str); + if (nvp == NULL) + free(str); + return (nvp); +} + +nvpair_t * +nvpair_create_nvlist(const char *name, const nvlist_t *value) +{ + + return (nvpair_createf_nvlist(value, "%s", name)); +} + +nvpair_t * +nvpair_create_descriptor(const char *name, int value) +{ + + return (nvpair_createf_descriptor(value, "%s", name)); +} + +nvpair_t * +nvpair_create_binary(const char *name, const void *value, size_t size) +{ + + return (nvpair_createf_binary(value, size, "%s", name)); +} + +nvpair_t * +nvpair_createf_null(const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_null(namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_bool(bool value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_bool(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_number(uint64_t value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_number(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_string(const char *value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_string(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_nvlist(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_descriptor(int value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_descriptor(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_createv_binary(value, size, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_createv_null(const char *namefmt, va_list nameap) +{ + + return (nvpair_allocv(NV_TYPE_NULL, 0, 0, namefmt, nameap)); +} + +nvpair_t * +nvpair_createv_bool(bool value, const char *namefmt, va_list nameap) +{ + + return (nvpair_allocv(NV_TYPE_BOOL, value ? 1 : 0, sizeof(uint8_t), + namefmt, nameap)); +} + +nvpair_t * +nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap) +{ + + return (nvpair_allocv(NV_TYPE_NUMBER, value, sizeof(value), namefmt, + nameap)); +} + +nvpair_t * +nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + size_t size; + char *data; + + if (value == NULL) { + errno = EINVAL; + return (NULL); + } + + data = strdup(value); + if (data == NULL) + return (NULL); + size = strlen(value) + 1; + + nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)data, size, + namefmt, nameap); + if (nvp == NULL) + free(data); + + return (nvp); +} + +nvpair_t * +nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, + va_list nameap) +{ + nvlist_t *nvl; + nvpair_t *nvp; + + if (value == NULL) { + errno = EINVAL; + return (NULL); + } + + nvl = nvlist_clone(value); + if (nvl == NULL) + return (NULL); + + nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0, + namefmt, nameap); + if (nvp == NULL) + nvlist_destroy(nvl); + + return (nvp); +} + +nvpair_t * +nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (value < 0 || !fd_is_valid(value)) { + errno = EBADF; + return (NULL); + } + + value = fcntl(value, F_DUPFD_CLOEXEC, 0); + if (value < 0) + return (NULL); + + nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, + sizeof(int64_t), namefmt, nameap); + if (nvp == NULL) + close(value); + + return (nvp); +} + +nvpair_t * +nvpair_createv_binary(const void *value, size_t size, const char *namefmt, + va_list nameap) +{ + nvpair_t *nvp; + void *data; + + if (value == NULL || size == 0) { + errno = EINVAL; + return (NULL); + } + + data = malloc(size); + if (data == NULL) + return (NULL); + memcpy(data, value, size); + + nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)data, size, + namefmt, nameap); + if (nvp == NULL) + free(data); + + return (nvp); +} + +nvpair_t * +nvpair_move_string(const char *name, char *value) +{ + + return (nvpair_movef_string(value, "%s", name)); +} + +nvpair_t * +nvpair_move_nvlist(const char *name, nvlist_t *value) +{ + + return (nvpair_movef_nvlist(value, "%s", name)); +} + +nvpair_t * +nvpair_move_descriptor(const char *name, int value) +{ + + return (nvpair_movef_descriptor(value, "%s", name)); +} + +nvpair_t * +nvpair_move_binary(const char *name, void *value, size_t size) +{ + + return (nvpair_movef_binary(value, size, "%s", name)); +} + +nvpair_t * +nvpair_movef_string(char *value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_movev_string(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_movev_nvlist(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_movef_descriptor(int value, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_movev_descriptor(value, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) +{ + va_list nameap; + nvpair_t *nvp; + + va_start(nameap, namefmt); + nvp = nvpair_movev_binary(value, size, namefmt, nameap); + va_end(nameap); + + return (nvp); +} + +nvpair_t * +nvpair_movev_string(char *value, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (value == NULL) { + errno = EINVAL; + return (NULL); + } + + nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value, + strlen(value) + 1, namefmt, nameap); + if (nvp == NULL) + free(value); + + return (nvp); +} + +nvpair_t * +nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) +{ + nvpair_t *nvp; + + if (value == NULL) { + errno = EINVAL; + return (NULL); + } + + nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0, + namefmt, nameap); + if (nvp == NULL) + nvlist_destroy(value); + + return (nvp); +} + +nvpair_t * +nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) +{ + + if (value < 0 || !fd_is_valid(value)) { + errno = EBADF; + return (NULL); + } + + return (nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, + sizeof(int64_t), namefmt, nameap)); +} + +nvpair_t * +nvpair_movev_binary(void *value, size_t size, const char *namefmt, + va_list nameap) +{ + + if (value == NULL || size == 0) { + errno = EINVAL; + return (NULL); + } + + return (nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size, + namefmt, nameap)); +} + +bool +nvpair_get_bool(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_data == 1); +} + +uint64_t +nvpair_get_number(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + + return (nvp->nvp_data); +} + +const char * +nvpair_get_string(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING); + + return ((const char *)(intptr_t)nvp->nvp_data); +} + +const nvlist_t * +nvpair_get_nvlist(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); + + return ((const nvlist_t *)(intptr_t)nvp->nvp_data); +} + +int +nvpair_get_descriptor(const nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); + + return ((int)nvp->nvp_data); +} + +const void * +nvpair_get_binary(const nvpair_t *nvp, size_t *sizep) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); + + if (sizep != NULL) + *sizep = nvp->nvp_datasize; + return ((const void *)(intptr_t)nvp->nvp_data); +} + +void +nvpair_free(nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list == NULL); + + nvp->nvp_magic = 0; + switch (nvp->nvp_type) { + case NV_TYPE_DESCRIPTOR: + close((int)nvp->nvp_data); + break; + case NV_TYPE_NVLIST: + nvlist_destroy((nvlist_t *)(intptr_t)nvp->nvp_data); + break; + case NV_TYPE_STRING: + free((char *)(intptr_t)nvp->nvp_data); + break; + case NV_TYPE_BINARY: + free((void *)(intptr_t)nvp->nvp_data); + break; + } + free(nvp); +} + +void +nvpair_free_structure(nvpair_t *nvp) +{ + + NVPAIR_ASSERT(nvp); + PJDLOG_ASSERT(nvp->nvp_list == NULL); + + nvp->nvp_magic = 0; + free(nvp); +} + +const char * +nvpair_type_string(int type) +{ + + switch (type) { + case NV_TYPE_NULL: + return ("NULL"); + case NV_TYPE_BOOL: + return ("BOOL"); + case NV_TYPE_NUMBER: + return ("NUMBER"); + case NV_TYPE_STRING: + return ("STRING"); + case NV_TYPE_NVLIST: + return ("NVLIST"); + case NV_TYPE_DESCRIPTOR: + return ("DESCRIPTOR"); + case NV_TYPE_BINARY: + return ("BINARY"); + default: + return ("<UNKNOWN>"); + } +} diff --git a/lib/libnv/nvpair_impl.h b/lib/libnv/nvpair_impl.h new file mode 100644 index 0000000..aa4046c --- /dev/null +++ b/lib/libnv/nvpair_impl.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2009-2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NVPAIR_IMPL_H_ +#define _NVPAIR_IMPL_H_ + +#include <sys/queue.h> + +#include <stdint.h> + +#include "nv.h" + +TAILQ_HEAD(nvl_head, nvpair); + +void nvpair_assert(const nvpair_t *nvp); +const nvlist_t *nvpair_nvlist(const nvpair_t *nvp); +nvpair_t *nvpair_next(const nvpair_t *nvp); +nvpair_t *nvpair_prev(const nvpair_t *nvp); +void nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl); +void nvpair_remove(struct nvl_head *head, nvpair_t *nvp, const nvlist_t *nvl); +size_t nvpair_header_size(void); +size_t nvpair_size(const nvpair_t *nvp); +unsigned char *nvpair_pack(nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, + size_t *leftp); +const unsigned char *nvpair_unpack(int flags, const unsigned char *ptr, + size_t *leftp, const int *fds, size_t nfds, nvpair_t **nvpp); +void nvpair_free_structure(nvpair_t *nvp); +const char *nvpair_type_string(int type); + +#endif /* !_NVPAIR_IMPL_H_ */ diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile index fb2be14..a654cf7 100644 --- a/lib/libpam/libpam/Makefile +++ b/lib/libpam/libpam/Makefile @@ -39,7 +39,7 @@ OPENPAM= ${.CURDIR}/../../../contrib/openpam .PATH: ${OPENPAM}/include ${OPENPAM}/lib/libpam ${OPENPAM}/doc/man LIB= pam -NO_PROFILE= +MK_PROFILE=no SRCS= openpam_asprintf.c \ openpam_borrow_cred.c \ @@ -154,7 +154,7 @@ MLINKS= pam.conf.5 pam.d.5 CSTD?= c99 CFLAGS+= -I${.CURDIR} -I${OPENPAM}/include CFLAGS+= -DLIB_MAJ=${SHLIB_MAJOR} -CFLAGS+= -DOPENPAM_MODULES_DIR='"${PAM_MOD_DIR:C/\/*$//}/"' +CFLAGS+= -DOPENPAM_MODULES_DIRECTORY='"${PAM_MOD_DIR:C/\/*$//}/"' CFLAGS+= -DHAVE_DLFUNC=1 CFLAGS+= -DHAVE_FDLOPEN=1 CFLAGS+= -DHAVE_FPURGE=1 diff --git a/lib/libpam/modules/Makefile.inc b/lib/libpam/modules/Makefile.inc index 8ff6ca6..085ab58 100644 --- a/lib/libpam/modules/Makefile.inc +++ b/lib/libpam/modules/Makefile.inc @@ -2,8 +2,8 @@ PAMDIR= ${.CURDIR}/../../../../contrib/openpam -NO_INSTALLLIB= -NO_PROFILE= +MK_INSTALLLIB= no +MK_PROFILE= no CFLAGS+= -I${PAMDIR}/include -I${.CURDIR}/../../libpam diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8 index 25e7312..da36b7f 100644 --- a/lib/libpam/modules/pam_radius/pam_radius.8 +++ b/lib/libpam/modules/pam_radius/pam_radius.8 @@ -16,11 +16,7 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" diff --git a/lib/libpam/modules/pam_tacplus/pam_tacplus.8 b/lib/libpam/modules/pam_tacplus/pam_tacplus.8 index 03faf0c..a1fe9ba 100644 --- a/lib/libpam/modules/pam_tacplus/pam_tacplus.8 +++ b/lib/libpam/modules/pam_tacplus/pam_tacplus.8 @@ -16,11 +16,7 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" diff --git a/lib/libpjdlog/Makefile b/lib/libpjdlog/Makefile new file mode 100644 index 0000000..a80b629 --- /dev/null +++ b/lib/libpjdlog/Makefile @@ -0,0 +1,21 @@ +# +# $FreeBSD$ +# + +SHLIBDIR?= /lib + +.include <bsd.own.mk> + +LIB= pjdlog +SRCS= pjdlog.c + +SHLIB_MAJOR= 0 + +CFLAGS+=-I${.CURDIR} + +DPADD= ${LIBUTIL} +LDADD= -lutil + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/lib/libpjdlog/pjdlog.c b/lib/libpjdlog/pjdlog.c new file mode 100644 index 0000000..84615fa --- /dev/null +++ b/lib/libpjdlog/pjdlog.c @@ -0,0 +1,809 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * Copyright (c) 2011 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <assert.h> +#include <errno.h> +#include <libutil.h> +#include <limits.h> +#include <printf.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#ifdef notyet +#include <robustio.h> +#endif + +#include "pjdlog.h" + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define PJDLOG_MAX_MSGSIZE 4096 + +#define PJDLOG_PREFIX_STACK 4 +#define PJDLOG_PREFIX_MAXSIZE 128 + +#define PJDLOG_NEVER_INITIALIZED 0 +#define PJDLOG_NOT_INITIALIZED 1 +#define PJDLOG_INITIALIZED 2 + +static int pjdlog_initialized = PJDLOG_NEVER_INITIALIZED; +static int pjdlog_mode, pjdlog_debug_level, pjdlog_sock; +static int pjdlog_prefix_current; +static char pjdlog_prefix[PJDLOG_PREFIX_STACK][PJDLOG_PREFIX_MAXSIZE]; + +static int +pjdlog_printf_arginfo_humanized_number(const struct printf_info *pi __unused, + size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_INT | PA_FLAG_INTMAX; + return (1); +} + +static int +pjdlog_printf_render_humanized_number(struct __printf_io *io, + const struct printf_info *pi, const void * const *arg) +{ + char buf[5]; + intmax_t num; + int ret; + + num = *(const intmax_t *)arg[0]; + humanize_number(buf, sizeof(buf), (int64_t)num, "", HN_AUTOSCALE, + HN_NOSPACE | HN_DECIMAL); + ret = __printf_out(io, pi, buf, strlen(buf)); + __printf_flush(io); + return (ret); +} + +static int +pjdlog_printf_arginfo_sockaddr(const struct printf_info *pi __unused, + size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} + +static int +pjdlog_printf_render_sockaddr_ip(struct __printf_io *io, + const struct printf_info *pi, const void * const *arg) +{ + const struct sockaddr_storage *ss; + char addr[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; + int ret; + + ss = *(const struct sockaddr_storage * const *)arg[0]; + switch (ss->ss_family) { + case AF_INET: + { + const struct sockaddr_in *sin; + + sin = (const struct sockaddr_in *)ss; + if (inet_ntop(ss->ss_family, &sin->sin_addr, addr, + sizeof(addr)) == NULL) { + PJDLOG_ABORT("inet_ntop(AF_INET) failed: %s.", + strerror(errno)); + } + break; + } + case AF_INET6: + { + const struct sockaddr_in6 *sin; + + sin = (const struct sockaddr_in6 *)ss; + if (inet_ntop(ss->ss_family, &sin->sin6_addr, addr, + sizeof(addr)) == NULL) { + PJDLOG_ABORT("inet_ntop(AF_INET6) failed: %s.", + strerror(errno)); + } + break; + } + default: + snprintf(addr, sizeof(addr), "[unsupported family %hhu]", + ss->ss_family); + break; + } + ret = __printf_out(io, pi, addr, strlen(addr)); + __printf_flush(io); + return (ret); +} + +static int +pjdlog_printf_render_sockaddr(struct __printf_io *io, + const struct printf_info *pi, const void * const *arg) +{ + const struct sockaddr_storage *ss; + char buf[PATH_MAX]; + int ret; + + ss = *(const struct sockaddr_storage * const *)arg[0]; + switch (ss->ss_family) { + case AF_UNIX: + { + const struct sockaddr_un *sun; + + sun = (const struct sockaddr_un *)ss; + if (sun->sun_path[0] == '\0') + snprintf(buf, sizeof(buf), "N/A"); + else + snprintf(buf, sizeof(buf), "%s", sun->sun_path); + break; + } + case AF_INET: + { + char addr[INET_ADDRSTRLEN]; + const struct sockaddr_in *sin; + unsigned int port; + + sin = (const struct sockaddr_in *)ss; + port = ntohs(sin->sin_port); + if (inet_ntop(ss->ss_family, &sin->sin_addr, addr, + sizeof(addr)) == NULL) { + PJDLOG_ABORT("inet_ntop(AF_INET) failed: %s.", + strerror(errno)); + } + snprintf(buf, sizeof(buf), "%s:%u", addr, port); + break; + } + case AF_INET6: + { + char addr[INET6_ADDRSTRLEN]; + const struct sockaddr_in6 *sin; + unsigned int port; + + sin = (const struct sockaddr_in6 *)ss; + port = ntohs(sin->sin6_port); + if (inet_ntop(ss->ss_family, &sin->sin6_addr, addr, + sizeof(addr)) == NULL) { + PJDLOG_ABORT("inet_ntop(AF_INET6) failed: %s.", + strerror(errno)); + } + snprintf(buf, sizeof(buf), "[%s]:%u", addr, port); + break; + } + default: + snprintf(buf, sizeof(buf), "[unsupported family %hhu]", + ss->ss_family); + break; + } + ret = __printf_out(io, pi, buf, strlen(buf)); + __printf_flush(io); + return (ret); +} + +void +pjdlog_init(int mode) +{ + int saved_errno; + + assert(pjdlog_initialized == PJDLOG_NEVER_INITIALIZED || + pjdlog_initialized == PJDLOG_NOT_INITIALIZED); +#ifdef notyet + assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG || + mode == PJDLOG_MODE_SOCK); +#else + assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); +#endif + + saved_errno = errno; + + if (pjdlog_initialized == PJDLOG_NEVER_INITIALIZED) { + __use_xprintf = 1; + register_printf_render_std("T"); + register_printf_render('N', + pjdlog_printf_render_humanized_number, + pjdlog_printf_arginfo_humanized_number); + register_printf_render('I', + pjdlog_printf_render_sockaddr_ip, + pjdlog_printf_arginfo_sockaddr); + register_printf_render('S', + pjdlog_printf_render_sockaddr, + pjdlog_printf_arginfo_sockaddr); + } + + if (mode == PJDLOG_MODE_SYSLOG) + openlog(NULL, LOG_PID | LOG_NDELAY, LOG_LOCAL0); + pjdlog_mode = mode; + pjdlog_debug_level = 0; + pjdlog_prefix_current = 0; + pjdlog_prefix[0][0] = '\0'; + + pjdlog_initialized = PJDLOG_INITIALIZED; + pjdlog_sock = -1; + + errno = saved_errno; +} + +void +pjdlog_fini(void) +{ + int saved_errno; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + saved_errno = errno; + + if (pjdlog_mode == PJDLOG_MODE_SYSLOG) + closelog(); + + pjdlog_initialized = PJDLOG_NOT_INITIALIZED; + pjdlog_sock = -1; + + errno = saved_errno; +} + +/* + * Configure where the logs should go. + * By default they are send to stdout/stderr, but after going into background + * (eg. by calling daemon(3)) application is responsible for changing mode to + * PJDLOG_MODE_SYSLOG, so logs will be send to syslog. + */ +void +pjdlog_mode_set(int mode) +{ + int saved_errno; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); +#ifdef notyet + assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG || + mode == PJDLOG_MODE_SOCK); +#else + assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); +#endif + + if (pjdlog_mode == mode) + return; + + saved_errno = errno; + + if (mode == PJDLOG_MODE_SYSLOG) + openlog(NULL, LOG_PID | LOG_NDELAY, LOG_DAEMON); + else if (mode == PJDLOG_MODE_STD) + closelog(); + + if (mode != PJDLOG_MODE_SOCK) + pjdlog_sock = -1; + + pjdlog_mode = mode; + + errno = saved_errno; +} + + +/* + * Return current mode. + */ +int +pjdlog_mode_get(void) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + return (pjdlog_mode); +} + +#ifdef notyet +/* + * Sets socket number to use for PJDLOG_MODE_SOCK mode. + */ +void +pjdlog_sock_set(int sock) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(pjdlog_mode == PJDLOG_MODE_SOCK); + assert(sock >= 0); + + pjdlog_sock = sock; +} +#endif + +#ifdef notyet +/* + * Returns socket number used for PJDLOG_MODE_SOCK mode. + */ +int +pjdlog_sock_get(void) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(pjdlog_mode == PJDLOG_MODE_SOCK); + assert(pjdlog_sock >= 0); + + return (pjdlog_sock); +} +#endif + +/* + * Set debug level. All the logs above the level specified here will be + * ignored. + */ +void +pjdlog_debug_set(int level) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(level >= 0); + assert(level <= 127); + + pjdlog_debug_level = level; +} + +/* + * Return current debug level. + */ +int +pjdlog_debug_get(void) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + return (pjdlog_debug_level); +} + +/* + * Set prefix that will be used before each log. + */ +void +pjdlog_prefix_set(const char *fmt, ...) +{ + va_list ap; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + va_start(ap, fmt); + pjdlogv_prefix_set(fmt, ap); + va_end(ap); +} + +/* + * Set prefix that will be used before each log. + */ +void +pjdlogv_prefix_set(const char *fmt, va_list ap) +{ + int saved_errno; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(fmt != NULL); + + saved_errno = errno; + + vsnprintf(pjdlog_prefix[pjdlog_prefix_current], + sizeof(pjdlog_prefix[pjdlog_prefix_current]), fmt, ap); + + errno = saved_errno; +} + +/* + * Get current prefix. + */ +const char * +pjdlog_prefix_get(void) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + return (pjdlog_prefix[pjdlog_prefix_current]); +} + +/* + * Set new prefix and put the current one on the stack. + */ +void +pjdlog_prefix_push(const char *fmt, ...) +{ + va_list ap; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + va_start(ap, fmt); + pjdlogv_prefix_push(fmt, ap); + va_end(ap); +} + +/* + * Set new prefix and put the current one on the stack. + */ +void +pjdlogv_prefix_push(const char *fmt, va_list ap) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(pjdlog_prefix_current < PJDLOG_PREFIX_STACK - 1); + + pjdlog_prefix_current++; + + pjdlogv_prefix_set(fmt, ap); +} + +/* + * Removes current prefix and recovers previous one from the stack. + */ +void +pjdlog_prefix_pop(void) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(pjdlog_prefix_current > 0); + + pjdlog_prefix_current--; +} + +/* + * Convert log level into string. + */ +static const char * +pjdlog_level_to_string(int loglevel) +{ + + switch (loglevel) { + case LOG_EMERG: + return ("EMERG"); + case LOG_ALERT: + return ("ALERT"); + case LOG_CRIT: + return ("CRIT"); + case LOG_ERR: + return ("ERROR"); + case LOG_WARNING: + return ("WARNING"); + case LOG_NOTICE: + return ("NOTICE"); + case LOG_INFO: + return ("INFO"); + case LOG_DEBUG: + return ("DEBUG"); + } + assert(!"Invalid log level."); + abort(); /* XXX: gcc */ +} + +static int +vsnprlcat(char *str, size_t size, const char *fmt, va_list ap) +{ + size_t len; + + len = strlen(str); + assert(len < size); + return (vsnprintf(str + len, size - len, fmt, ap)); +} + +static int +snprlcat(char *str, size_t size, const char *fmt, ...) +{ + va_list ap; + int result; + + va_start(ap, fmt); + result = vsnprlcat(str, size, fmt, ap); + va_end(ap); + return (result); +} + +static void +pjdlogv_common_single_line(const char *func, const char *file, int line, + int loglevel, int debuglevel, int error, const char *msg) +{ + static char log[2 * PJDLOG_MAX_MSGSIZE]; + char *logp; + size_t logs; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); +#ifdef notyet + assert(pjdlog_mode == PJDLOG_MODE_STD || + pjdlog_mode == PJDLOG_MODE_SYSLOG || + pjdlog_mode == PJDLOG_MODE_SOCK); +#else + assert(pjdlog_mode == PJDLOG_MODE_STD || + pjdlog_mode == PJDLOG_MODE_SYSLOG); +#endif + assert(pjdlog_mode != PJDLOG_MODE_SOCK || pjdlog_sock >= 0); + assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || + loglevel == LOG_CRIT || loglevel == LOG_ERR || + loglevel == LOG_WARNING || loglevel == LOG_NOTICE || + loglevel == LOG_INFO || loglevel == LOG_DEBUG); + assert(loglevel != LOG_DEBUG || debuglevel > 0); + assert(loglevel != LOG_DEBUG || debuglevel <= pjdlog_debug_level); + assert(debuglevel <= 127); + assert(error >= -1); + assert((file != NULL && line > 0) || + (func == NULL && file == NULL && line == 0)); + + switch (pjdlog_mode) { + case PJDLOG_MODE_STD: + case PJDLOG_MODE_SYSLOG: + logp = log; + logs = sizeof(log); + break; + case PJDLOG_MODE_SOCK: + logp = log + 4; + logs = sizeof(log) - 4; + break; + default: + assert(!"Invalid mode."); + } + + *logp = '\0'; + + if (pjdlog_mode != PJDLOG_MODE_SOCK) { + if (loglevel == LOG_DEBUG) { + /* Attach debuglevel if this is debug log. */ + snprlcat(logp, logs, "[%s%d] ", + pjdlog_level_to_string(loglevel), debuglevel); + } else { + snprlcat(logp, logs, "[%s] ", + pjdlog_level_to_string(loglevel)); + } + if (pjdlog_mode != PJDLOG_MODE_SYSLOG && + pjdlog_debug_level >= 1) { + snprlcat(logp, logs, "(pid=%d) ", getpid()); + } + } + /* Attach file, func, line if debuglevel is 2 or more. */ + if (pjdlog_debug_level >= 2 && file != NULL) { + if (func == NULL) + snprlcat(logp, logs, "(%s:%d) ", file, line); + else + snprlcat(logp, logs, "(%s:%d:%s) ", file, line, func); + } + + if (pjdlog_mode != PJDLOG_MODE_SOCK) { + snprlcat(logp, logs, "%s", + pjdlog_prefix[pjdlog_prefix_current]); + } + + strlcat(logp, msg, logs); + + /* Attach error description. */ + if (error != -1) + snprlcat(logp, logs, ": %s.", strerror(error)); + + switch (pjdlog_mode) { + case PJDLOG_MODE_STD: + fprintf(stderr, "%s\n", logp); + fflush(stderr); + break; + case PJDLOG_MODE_SYSLOG: + syslog(loglevel, "%s", logp); + break; +#ifdef notyet + case PJDLOG_MODE_SOCK: + { + char ack[2]; + uint16_t dlen; + + log[2] = loglevel; + log[3] = debuglevel; + dlen = strlen(logp) + 3; /* +3 = loglevel, debuglevel and terminating \0 */ + bcopy(&dlen, log, sizeof(dlen)); + if (robust_send(pjdlog_sock, log, (size_t)dlen + 2) == -1) /* +2 for size */ + assert(!"Unable to send log."); + if (robust_recv(pjdlog_sock, ack, sizeof(ack)) == -1) + assert(!"Unable to send log."); + break; + } +#endif + default: + assert(!"Invalid mode."); + } +} + +/* + * Common log routine, which can handle regular log level as well as debug + * level. We decide here where to send the logs (stdout/stderr or syslog). + */ +void +_pjdlogv_common(const char *func, const char *file, int line, int loglevel, + int debuglevel, int error, const char *fmt, va_list ap) +{ + char log[PJDLOG_MAX_MSGSIZE]; + char *logp, *curline; + const char *prvline; + int saved_errno; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + assert(pjdlog_mode == PJDLOG_MODE_STD || + pjdlog_mode == PJDLOG_MODE_SYSLOG || + pjdlog_mode == PJDLOG_MODE_SOCK); + assert(pjdlog_mode != PJDLOG_MODE_SOCK || pjdlog_sock >= 0); + assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || + loglevel == LOG_CRIT || loglevel == LOG_ERR || + loglevel == LOG_WARNING || loglevel == LOG_NOTICE || + loglevel == LOG_INFO || loglevel == LOG_DEBUG); + assert(loglevel != LOG_DEBUG || debuglevel > 0); + assert(debuglevel <= 127); + assert(error >= -1); + + /* Ignore debug above configured level. */ + if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level) + return; + + saved_errno = errno; + + vsnprintf(log, sizeof(log), fmt, ap); + logp = log; + prvline = NULL; + + while ((curline = strsep(&logp, "\n")) != NULL) { + if (*curline == '\0') + continue; + if (prvline != NULL) { + pjdlogv_common_single_line(func, file, line, loglevel, + debuglevel, -1, prvline); + } + prvline = curline; + } + if (prvline == NULL) + prvline = ""; + pjdlogv_common_single_line(func, file, line, loglevel, debuglevel, + error, prvline); + + errno = saved_errno; +} + +/* + * Common log routine. + */ +void +_pjdlog_common(const char *func, const char *file, int line, int loglevel, + int debuglevel, int error, const char *fmt, ...) +{ + va_list ap; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + va_start(ap, fmt); + _pjdlogv_common(func, file, line, loglevel, debuglevel, error, fmt, ap); + va_end(ap); +} + +/* + * Log error, errno and exit. + */ +void +_pjdlogv_exit(const char *func, const char *file, int line, int exitcode, + int error, const char *fmt, va_list ap) +{ + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + _pjdlogv_common(func, file, line, exitcode == 0 ? LOG_INFO : LOG_ERR, 0, + error, fmt, ap); + exit(exitcode); + /* NOTREACHED */ +} + +/* + * Log error, errno and exit. + */ +void +_pjdlog_exit(const char *func, const char *file, int line, int exitcode, + int error, const char *fmt, ...) +{ + va_list ap; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + va_start(ap, fmt); + _pjdlogv_exit(func, file, line, exitcode, error, fmt, ap); + /* NOTREACHED */ + va_end(ap); +} + +/* + * Log failure message and exit. + */ +void +_pjdlog_abort(const char *func, const char *file, int line, + int error, const char *failedexpr, const char *fmt, ...) +{ + va_list ap; + + assert(pjdlog_initialized == PJDLOG_INITIALIZED); + + /* + * Set pjdlog_debug_level to 2, so that file, line and func are + * included in log. This is fine as we will exit anyway. + */ + if (pjdlog_debug_level < 2) + pjdlog_debug_level = 2; + + /* + * When there is no message we pass __func__ as 'fmt'. + * It would be cleaner to pass NULL or "", but gcc generates a warning + * for both of those. + */ + if (fmt != func) { + va_start(ap, fmt); + _pjdlogv_common(func, file, line, LOG_CRIT, 0, -1, fmt, ap); + va_end(ap); + } + if (failedexpr == NULL) { + _pjdlog_common(func, file, line, LOG_CRIT, 0, -1, "Aborted."); + } else { + _pjdlog_common(func, file, line, LOG_CRIT, 0, -1, + "Assertion failed: (%s).", failedexpr); + } + if (error != -1) + _pjdlog_common(func, file, line, LOG_CRIT, 0, error, "Errno"); + abort(); +} + +#ifdef notyet +/* + * Receive log from the given socket. + */ +int +pjdlog_receive(int sock) +{ + char log[PJDLOG_MAX_MSGSIZE]; + int loglevel, debuglevel; + uint16_t dlen; + + if (robust_recv(sock, &dlen, sizeof(dlen)) == -1) + return (-1); + + PJDLOG_ASSERT(dlen > 0); + PJDLOG_ASSERT(dlen <= PJDLOG_MAX_MSGSIZE - 3); + + if (robust_recv(sock, log, (size_t)dlen) == -1) + return (-1); + + log[dlen - 1] = '\0'; + loglevel = log[0]; + debuglevel = log[1]; + _pjdlog_common(NULL, NULL, 0, loglevel, debuglevel, -1, "%s", log + 2); + + if (robust_send(sock, "ok", 2) == -1) + return (-1); + + return (0); +} +#endif diff --git a/lib/libpjdlog/pjdlog.h b/lib/libpjdlog/pjdlog.h new file mode 100644 index 0000000..3f38b10 --- /dev/null +++ b/lib/libpjdlog/pjdlog.h @@ -0,0 +1,174 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * Copyright (c) 2011 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _PJDLOG_H_ +#define _PJDLOG_H_ + +#include <sys/cdefs.h> + +#include <errno.h> +#include <stdarg.h> +#include <sysexits.h> +#include <syslog.h> + +#define PJDLOG_MODE_STD 0 +#define PJDLOG_MODE_SYSLOG 1 +#define PJDLOG_MODE_SOCK 2 + +void pjdlog_init(int mode); +void pjdlog_fini(void); + +void pjdlog_mode_set(int mode); +int pjdlog_mode_get(void); + +#ifdef notyet +void pjdlog_sock_set(int sock); +int pjdlog_sock_get(void); +#endif + +void pjdlog_debug_set(int level); +int pjdlog_debug_get(void); + +void pjdlog_prefix_set(const char *fmt, ...) __printflike(1, 2); +void pjdlogv_prefix_set(const char *fmt, va_list ap) __printflike(1, 0); +const char *pjdlog_prefix_get(void); +void pjdlog_prefix_push(const char *fmt, ...) __printflike(1, 2); +void pjdlogv_prefix_push(const char *fmt, va_list ap) __printflike(1, 0); +void pjdlog_prefix_pop(void); + +void _pjdlogv_common(const char *func, const char *file, int line, int loglevel, + int debuglevel, int error, const char *fmt, va_list ap) __printflike(7, 0); +void _pjdlog_common(const char *func, const char *file, int line, int loglevel, + int debuglevel, int error, const char *fmt, ...) __printflike(7, 8); + +void _pjdlogv_exit(const char *func, const char *file, int line, int exitcode, + int error, const char *fmt, va_list ap) __printflike(6, 0) __dead2; +void _pjdlog_exit(const char *func, const char *file, int line, int exitcode, + int error, const char *fmt, ...) __printflike(6, 7) __dead2; + +void _pjdlog_abort(const char *func, const char *file, int line, int error, + const char *failedexpr, const char *fmt, ...) __printflike(6, 7) __dead2; + +#ifdef notyet +int pjdlog_receive(int sock); +#endif + +#define pjdlogv_common(loglevel, debuglevel, error, fmt, ap) \ + _pjdlogv_common(__func__, __FILE__, __LINE__, (loglevel), \ + (debuglevel), (error), (fmt), (ap)) +#define pjdlog_common(loglevel, debuglevel, error, ...) \ + _pjdlog_common(__func__, __FILE__, __LINE__, (loglevel), \ + (debuglevel), (error), __VA_ARGS__) + +#define pjdlogv(loglevel, fmt, ap) \ + pjdlogv_common((loglevel), 0, -1, (fmt), (ap)) +#define pjdlog(loglevel, ...) \ + pjdlog_common((loglevel), 0, -1, __VA_ARGS__) + +#define pjdlogv_emergency(fmt, ap) pjdlogv(LOG_EMERG, (fmt), (ap)) +#define pjdlog_emergency(...) pjdlog(LOG_EMERG, __VA_ARGS__) +#define pjdlogv_alert(fmt, ap) pjdlogv(LOG_ALERT, (fmt), (ap)) +#define pjdlog_alert(...) pjdlog(LOG_ALERT, __VA_ARGS__) +#define pjdlogv_critical(fmt, ap) pjdlogv(LOG_CRIT, (fmt), (ap)) +#define pjdlog_critical(...) pjdlog(LOG_CRIT, __VA_ARGS__) +#define pjdlogv_error(fmt, ap) pjdlogv(LOG_ERR, (fmt), (ap)) +#define pjdlog_error(...) pjdlog(LOG_ERR, __VA_ARGS__) +#define pjdlogv_warning(fmt, ap) pjdlogv(LOG_WARNING, (fmt), (ap)) +#define pjdlog_warning(...) pjdlog(LOG_WARNING, __VA_ARGS__) +#define pjdlogv_notice(fmt, ap) pjdlogv(LOG_NOTICE, (fmt), (ap)) +#define pjdlog_notice(...) pjdlog(LOG_NOTICE, __VA_ARGS__) +#define pjdlogv_info(fmt, ap) pjdlogv(LOG_INFO, (fmt), (ap)) +#define pjdlog_info(...) pjdlog(LOG_INFO, __VA_ARGS__) + +#define pjdlog_debug(debuglevel, ...) \ + pjdlog_common(LOG_DEBUG, (debuglevel), -1, __VA_ARGS__) +#define pjdlogv_debug(debuglevel, fmt, ap) \ + pjdlogv_common(LOG_DEBUG, (debuglevel), -1, (fmt), (ap)) + +#define pjdlog_errno(loglevel, ...) \ + pjdlog_common((loglevel), 0, (errno), __VA_ARGS__) +#define pjdlogv_errno(loglevel, fmt, ap) \ + pjdlogv_common((loglevel), 0, (errno), (fmt), (ap)) + +#define pjdlogv_exit(exitcode, fmt, ap) \ + _pjdlogv_exit(__func__, __FILE__, __LINE__, (exitcode), \ + (errno), (fmt), (ap)) +#define pjdlog_exit(exitcode, ...) \ + _pjdlog_exit(__func__, __FILE__, __LINE__, (exitcode), (errno), \ + __VA_ARGS__) + +#define pjdlogv_exitx(exitcode, fmt, ap) \ + _pjdlogv_exit(__func__, __FILE__, __LINE__, (exitcode), -1, \ + (fmt), (ap)) +#define pjdlog_exitx(exitcode, ...) \ + _pjdlog_exit(__func__, __FILE__, __LINE__, (exitcode), -1, \ + __VA_ARGS__) + +#define PJDLOG_VERIFY(expr) do { \ + if (!(expr)) { \ + _pjdlog_abort(__func__, __FILE__, __LINE__, -1, #expr, \ + __func__); \ + } \ +} while (0) +#define PJDLOG_RVERIFY(expr, ...) do { \ + if (!(expr)) { \ + _pjdlog_abort(__func__, __FILE__, __LINE__, -1, #expr, \ + __VA_ARGS__); \ + } \ +} while (0) +#define PJDLOG_EVERIFY(expr) do { \ + if (!(expr)) { \ + _pjdlog_abort(__func__, __FILE__, __LINE__, errno, \ + #expr, __func__); \ + } \ +} while (0) +#define PJDLOG_ABORT(...) _pjdlog_abort(__func__, __FILE__, \ + __LINE__, -1, NULL, __VA_ARGS__) +#ifdef NDEBUG +#define PJDLOG_ASSERT(expr) do { } while (0) +#define PJDLOG_RASSERT(...) do { } while (0) +#else +#define PJDLOG_ASSERT(expr) do { \ + if (!(expr)) { \ + _pjdlog_abort(__func__, __FILE__, __LINE__, -1, #expr, \ + __func__); \ + } \ +} while (0) +#define PJDLOG_RASSERT(expr, ...) do { \ + if (!(expr)) { \ + _pjdlog_abort(__func__, __FILE__, __LINE__, -1, #expr, \ + __VA_ARGS__); \ + } \ +} while (0) +#endif + +#endif /* !_PJDLOG_H_ */ diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile index d9ac0b9..4227794 100644 --- a/lib/libpmc/Makefile +++ b/lib/libpmc/Makefile @@ -24,6 +24,7 @@ MAN+= pmc.soft.3 # PMC-dependent manual pages MAN+= pmc.atom.3 +MAN+= pmc.atomsilvermont.3 MAN+= pmc.core.3 MAN+= pmc.core2.3 MAN+= pmc.corei7.3 diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 74956a9..2b7b61b2 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> +#include <sys/param.h> #include <sys/module.h> #include <sys/pmc.h> #include <sys/syscall.h> @@ -85,7 +86,7 @@ static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, struct pmc_op_pmcallocate *_pmc_config); #if defined(__powerpc__) -static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, +static int powerpc_allocate_pmc(enum pmc_event _pe, char* ctrspec, struct pmc_op_pmcallocate *_pmc_config); #endif /* __powerpc__ */ @@ -156,6 +157,7 @@ PMC_CLASSDEP_TABLE(mips24k, MIPS24K); PMC_CLASSDEP_TABLE(octeon, OCTEON); PMC_CLASSDEP_TABLE(ucf, UCF); PMC_CLASSDEP_TABLE(ppc7450, PPC7450); +PMC_CLASSDEP_TABLE(ppc970, PPC970); static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; @@ -167,6 +169,11 @@ static const struct pmc_event_descr atom_event_table[] = __PMC_EV_ALIAS_ATOM() }; +static const struct pmc_event_descr atom_silvermont_event_table[] = +{ + __PMC_EV_ALIAS_ATOM_SILVERMONT() +}; + static const struct pmc_event_descr core_event_table[] = { __PMC_EV_ALIAS_CORE() @@ -244,6 +251,7 @@ static const struct pmc_event_descr westmereuc_event_table[] = } PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); +PMC_MDEP_TABLE(atom_silvermont, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); @@ -262,6 +270,7 @@ PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); +PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970); PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); static const struct pmc_event_descr tsc_event_table[] = @@ -285,6 +294,7 @@ static const struct pmc_class_descr NAME##_class_table_descr = \ #if defined(__i386__) || defined(__amd64__) PMC_CLASS_TABLE_DESC(iaf, IAF, iaf, iaf); PMC_CLASS_TABLE_DESC(atom, IAP, atom, iap); +PMC_CLASS_TABLE_DESC(atom_silvermont, IAP, atom_silvermont, iap); PMC_CLASS_TABLE_DESC(core, IAP, core, iap); PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap); PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap); @@ -322,7 +332,8 @@ PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); #endif /* __mips__ */ #if defined(__powerpc__) -PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); +PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc); +PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc); #endif static struct pmc_class_descr soft_class_table_descr = @@ -593,6 +604,8 @@ static struct pmc_event_alias core2_aliases_without_iaf[] = { #define atom_aliases core2_aliases #define atom_aliases_without_iaf core2_aliases_without_iaf +#define atom_silvermont_aliases core2_aliases +#define atom_silvermont_aliases_without_iaf core2_aliases_without_iaf #define corei7_aliases core2_aliases #define corei7_aliases_without_iaf core2_aliases_without_iaf #define haswell_aliases core2_aliases @@ -838,6 +851,7 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec, if (n != 1) return (-1); } else if (cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM || + cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM_SILVERMONT || cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2 || cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME) { if (KWPREFIXMATCH(p, IAP_KW_SNOOPRESPONSE "=")) { @@ -2404,13 +2418,19 @@ static struct pmc_event_alias ppc7450_aliases[] = { EV_ALIAS(NULL, NULL) }; -#define PPC7450_KW_OS "os" -#define PPC7450_KW_USR "usr" -#define PPC7450_KW_ANYTHREAD "anythread" +static struct pmc_event_alias ppc970_aliases[] = { + EV_ALIAS("instructions", "INSTR_COMPLETED"), + EV_ALIAS("cycles", "CYCLES"), + EV_ALIAS(NULL, NULL) +}; + +#define POWERPC_KW_OS "os" +#define POWERPC_KW_USR "usr" +#define POWERPC_KW_ANYTHREAD "anythread" static int -ppc7450_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, - struct pmc_op_pmcallocate *pmc_config __unused) +powerpc_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, + struct pmc_op_pmcallocate *pmc_config __unused) { char *p; @@ -2419,11 +2439,11 @@ ppc7450_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); while ((p = strsep(&ctrspec, ",")) != NULL) { - if (KWMATCH(p, PPC7450_KW_OS)) + if (KWMATCH(p, POWERPC_KW_OS)) pmc_config->pm_caps |= PMC_CAP_SYSTEM; - else if (KWMATCH(p, PPC7450_KW_USR)) + else if (KWMATCH(p, POWERPC_KW_USR)) pmc_config->pm_caps |= PMC_CAP_USER; - else if (KWMATCH(p, PPC7450_KW_ANYTHREAD)) + else if (KWMATCH(p, POWERPC_KW_ANYTHREAD)) pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM); else return (-1); @@ -2431,6 +2451,7 @@ ppc7450_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, return (0); } + #endif /* __powerpc__ */ @@ -2722,6 +2743,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = atom_event_table; count = PMC_EVENT_TABLE_SIZE(atom); break; + case PMC_CPU_INTEL_ATOM_SILVERMONT: + ev = atom_silvermont_event_table; + count = PMC_EVENT_TABLE_SIZE(atom_silvermont); + break; case PMC_CPU_INTEL_CORE: ev = core_event_table; count = PMC_EVENT_TABLE_SIZE(core); @@ -2830,6 +2855,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = ppc7450_event_table; count = PMC_EVENT_TABLE_SIZE(ppc7450); break; + case PMC_CLASS_PPC970: + ev = ppc970_event_table; + count = PMC_EVENT_TABLE_SIZE(ppc970); + break; case PMC_CLASS_SOFT: ev = soft_event_table; count = soft_event_info.pm_nevent; @@ -3034,6 +3063,9 @@ pmc_init(void) case PMC_CPU_INTEL_ATOM: PMC_MDEP_INIT_INTEL_V2(atom); break; + case PMC_CPU_INTEL_ATOM_SILVERMONT: + PMC_MDEP_INIT_INTEL_V2(atom_silvermont); + break; case PMC_CPU_INTEL_CORE: PMC_MDEP_INIT(core); pmc_class_table[n] = &core_class_table_descr; @@ -3100,6 +3132,10 @@ pmc_init(void) PMC_MDEP_INIT(ppc7450); pmc_class_table[n] = &ppc7450_class_table_descr; break; + case PMC_CPU_PPC_970: + PMC_MDEP_INIT(ppc970); + pmc_class_table[n] = &ppc970_class_table_descr; + break; #endif default: /* @@ -3183,6 +3219,11 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) ev = atom_event_table; evfence = atom_event_table + PMC_EVENT_TABLE_SIZE(atom); break; + case PMC_CPU_INTEL_ATOM_SILVERMONT: + ev = atom_silvermont_event_table; + evfence = atom_silvermont_event_table + + PMC_EVENT_TABLE_SIZE(atom_silvermont); + break; case PMC_CPU_INTEL_CORE: ev = core_event_table; evfence = core_event_table + PMC_EVENT_TABLE_SIZE(core); @@ -3270,6 +3311,9 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { ev = ppc7450_event_table; evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); + } else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) { + ev = ppc970_event_table; + evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970); } else if (pe == PMC_EV_TSC_TSC) { ev = tsc_event_table; evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); diff --git a/lib/libpmc/pmc.atom.3 b/lib/libpmc/pmc.atom.3 index f61a141..9b9a58f 100644 --- a/lib/libpmc/pmc.atom.3 +++ b/lib/libpmc/pmc.atom.3 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 12, 2008 +.Dd March 20, 2014 .Dt PMC.ATOM 3 .Os .Sh NAME @@ -1168,6 +1168,7 @@ and the underlying hardware events used on these CPUs. .El .Sh SEE ALSO .Xr pmc 3 , +.Xr pmc.atomsilvermont 3 , .Xr pmc.core 3 , .Xr pmc.core2 3 , .Xr pmc.iaf 3 , diff --git a/lib/libpmc/pmc.atomsilvermont.3 b/lib/libpmc/pmc.atomsilvermont.3 new file mode 100644 index 0000000..91e22e9 --- /dev/null +++ b/lib/libpmc/pmc.atomsilvermont.3 @@ -0,0 +1,535 @@ +.\" Copyright (c) 2014 Hiren Panchasara <hiren@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 20, 2014 +.Dt PMC.ATOMSILVERMONT 3 +.Os +.Sh NAME +.Nm pmc.atomsilvermont +.Nd measurement events for +.Tn Intel +.Tn Atom Silvermont +family CPUs +.Sh LIBRARY +.Lb libpmc +.Sh SYNOPSIS +.In pmc.h +.Sh DESCRIPTION +.Tn Intel +.Tn Atom Silvermont +CPUs contain PMCs conforming to version 3 of the +.Tn Intel +performance measurement architecture. +These CPUs contains two classes of PMCs: +.Bl -tag -width "Li PMC_CLASS_IAP" +.It Li PMC_CLASS_IAF +Fixed-function counters that count only one hardware event per counter. +.It Li PMC_CLASS_IAP +Programmable counters that may be configured to count one of a defined +set of hardware events. +.El +.Pp +The number of PMCs available in each class and their widths need to be +determined at run time by calling +.Xr pmc_cpuinfo 3 . +.Pp +Intel Atom Silvermont PMCs are documented in +.Rs +.%B "Intel 64 and IA-32 Intel(R) Architecture Software Developer's Manual" +.%T "Combined Volumes" +.%N "Order Number 325462-050US" +.%D February 2014 +.%Q "Intel Corporation" +.Re +.Ss ATOM SILVERMONT FIXED FUNCTION PMCS +These PMCs and their supported events are documented in +.Xr pmc.iaf 3 . +.Ss ATOM SILVERMONT PROGRAMMABLE PMCS +The programmable PMCs support the following capabilities: +.Bl -column "PMC_CAP_INTERRUPT" "Support" +.It Em Capability Ta Em Support +.It PMC_CAP_CASCADE Ta \&No +.It PMC_CAP_EDGE Ta Yes +.It PMC_CAP_INTERRUPT Ta Yes +.It PMC_CAP_INVERT Ta Yes +.It PMC_CAP_READ Ta Yes +.It PMC_CAP_PRECISE Ta \&No +.It PMC_CAP_SYSTEM Ta Yes +.It PMC_CAP_TAGGING Ta \&No +.It PMC_CAP_THRESHOLD Ta Yes +.It PMC_CAP_USER Ta Yes +.It PMC_CAP_WRITE Ta Yes +.El +.Ss Event Qualifiers +Event specifiers for these PMCs support the following common +qualifiers: +.Bl -tag -width indent +.It Li any +Count matching events seen on any logical processor in a package. +.It Li cmask= Ns Ar value +Configure the PMC to increment only if the number of configured +events measured in a cycle is greater than or equal to +.Ar value . +.It Li edge +Configure the PMC to count the number of de-asserted to asserted +transitions of the conditions expressed by the other qualifiers. +If specified, the counter will increment only once whenever a +condition becomes true, irrespective of the number of clocks during +which the condition remains true. +.It Li inv +Invert the sense of comparison when the +.Dq Li cmask +qualifier is present, making the counter increment when the number of +events per cycle is less than the value specified by the +.Dq Li cmask +qualifier. +.It Li os +Configure the PMC to count events happening at processor privilege +level 0. +.It Li usr +Configure the PMC to count events occurring at privilege levels 1, 2 +or 3. +.El +.Pp +If neither of the +.Dq Li os +or +.Dq Li usr +qualifiers are specified, the default is to enable both. +.Pp +Events that require core-specificity to be specified use a +additional qualifier +.Dq Li core= Ns Ar core , +where argument +.Ar core +is one of: +.Bl -tag -width indent +.It Li all +Measure event conditions on all cores. +.It Li this +Measure event conditions on this core. +.El +.Pp +The default is +.Dq Li this . +.Pp +Events that require an agent qualifier to be specified use an +additional qualifier +.Dq Li agent= Ns agent , +where argument +.Ar agent +is one of: +.Bl -tag -width indent +.It Li this +Measure events associated with this bus agent. +.It Li any +Measure events caused by any bus agent. +.El +.Pp +The default is +.Dq Li this . +.Pp +Events that require a hardware prefetch qualifier to be specified use an +additional qualifier +.Dq Li prefetch= Ns Ar prefetch , +where argument +.Ar prefetch +is one of: +.Bl -tag -width "exclude" +.It Li both +Include all prefetches. +.It Li only +Only count hardware prefetches. +.It Li exclude +Exclude hardware prefetches. +.El +.Pp +The default is +.Dq Li both . +.Pp +Events that require a cache coherence qualifier to be specified use an +additional qualifier +.Dq Li cachestate= Ns Ar state , +where argument +.Ar state +contains one or more of the following letters: +.Bl -tag -width indent +.It Li e +Count cache lines in the exclusive state. +.It Li i +Count cache lines in the invalid state. +.It Li m +Count cache lines in the modified state. +.It Li s +Count cache lines in the shared state. +.El +.Pp +The default is +.Dq Li eims . +.Pp +Events that require a snoop response qualifier to be specified use an +additional qualifier +.Dq Li snoopresponse= Ns Ar response , +where argument +.Ar response +comprises of the following keywords separated by +.Dq + +signs: +.Bl -tag -width indent +.It Li clean +Measure CLEAN responses. +.It Li hit +Measure HIT responses. +.It Li hitm +Measure HITM responses. +.El +.Pp +The default is to measure all the above responses. +.Pp +Events that require a snoop type qualifier use an additional qualifier +.Dq Li snooptype= Ns Ar type , +where argument +.Ar type +comprises the one of the following keywords: +.Bl -tag -width indent +.It Li cmp2i +Measure CMP2I snoops. +.It Li cmp2s +Measure CMP2S snoops. +.El +.Pp +The default is to measure both snoops. +.Ss Event Specifiers (Programmable PMCs) +Atom Silvermont programmable PMCs support the following events: +.Bl -tag -width indent +.It Li REHABQ.LD_BLOCK_ST_FORWARD +.Pq Event 03H , Umask 01H +The number of retired loads that were +prohibited from receiving forwarded data from the store +because of address mismatch. +.It Li REHABQ.LD_BLOCK_STD_NOTREADY +.Pq Event 03H , Umask 02H +The cases where a forward was technically possible, +but did not occur because the store data was not available +at the right time. +.It Li REHABQ.ST_SPLITS +.Pq Event 03H , Umask 04H +The number of retire stores that experienced. +cache line boundary splits. +.It Li REHABQ.LD_SPLITS +.Pq Event 03H , Umask 08H +The number of retire loads that experienced. +cache line boundary splits. +.It Li REHABQ.LOCK +.Pq Event 03H , Umask 10H +The number of retired memory operations with lock semantics. +These are either implicit locked instructions such as the +XCHG instruction or instructions with an explicit LOCK +prefix (0xF0). +.It Li REHABQ.STA_FULL +.Pq Event 03H , Umask 20H +The number of retired stores that are delayed +because there is not a store address buffer available. +.It Li REHABQ.ANY_LD +.Pq Event 03H , Umask 40H +The number of load uops reissued from Rehabq. +.It Li REHABQ.ANY_ST +.Pq Event 03H , Umask 80H +The number of store uops reissued from Rehabq. +.It Li MEM_UOPS_RETIRED.L1_MISS_LOADS +.Pq Event 04H , Umask 01H +The number of load ops retired that miss in L1 +Data cache. Note that prefetch misses will not be counted. +.It Li MEM_UOPS_RETIRED.L2_HIT_LOADS +.Pq Event 04H , Umask 02H +The number of load micro-ops retired that hit L2. +.It Li MEM_UOPS_RETIRED.L2_MISS_LOADS +.Pq Event 04H , Umask 04H +The number of load micro-ops retired that missed L2. +.It Li MEM_UOPS_RETIRED.DTLB_MISS_LOADS +.Pq Event 04H , Umask 08H +The number of load ops retired that had DTLB miss. +.It Li MEM_UOPS_RETIRED.UTLB_MISS +.Pq Event 04H , Umask 10H +The number of load ops retired that had UTLB miss. +.It Li MEM_UOPS_RETIRED.HITM +.Pq Event 04H , Umask 20H +The number of load ops retired that got data +from the other core or from the other module. +.It Li MEM_UOPS_RETIRED.ALL_LOADS +.Pq Event 04H , Umask 40H +The number of load ops retired. +.It Li MEM_UOP_RETIRED.ALL_STORES +.Pq Event 04H , Umask 80H +The number of store ops retired. +.It Li PAGE_WALKS.D_SIDE_CYCLES +.Pq Event 05H , Umask 01H +Every cycle when a D-side (walks due to a load) page walk +is in progress. Page walk duration divided by +number of page walks is the average duration of page-walks. +Edge trigger bit must be cleared. Set Edge to count the number +of page walks. +.It Li PAGE_WALKS.I_SIDE_CYCLES +.Pq Event 05H , Umask 02H +Every cycle when a I-side (walks due to an instruction fetch) +page walk is in progress. Page walk duration divided by number +of page walks is the average duration of page-walks. +.It Li PAGE_WALKS.WALKS +.Pq Event 05H , Umask 03H +The number of times a data (D) page walk or an instruction (I) +page walk is completed or started. Since a page walk implies a +TLB miss, the number of TLB misses can be counted by counting +the number of pagewalks. +.It Li LONGEST_LAT_CACHE.MISS +.Pq Event 2EH , Umask 41H +the total number of L2 cache references and +The number of L2 cache misses respectively. +L3 is not supported in Silvermont microarchitecture. +.It Li LONGEST_LAT_CACHE.REFERENCE +.Pq Event 2EH , Umask 4FH +The number of requests originating from the core that +references a cache line in the L2 cache. +L3 is not supported in Silvermont microarchitecture. +.It Li L2_REJECT_XQ.ALL +.Pq Event 30H , Umask 00H +The number of demand and prefetch +transactions that the L2 XQ rejects due to a full or near full +condition which likely indicates back pressure from the IDI link. +The XQ may reject transactions from the L2Q (non-cacheable +requests), BBS (L2 misses) and WOB (L2 write-back victims) +.It Li CORE_REJECT_L2Q.ALL +.Pq Event 31H , Umask 00H +The number of demand and L1 prefetcher +requests rejected by the L2Q due to a full or nearly full +condition which likely indicates back pressure from L2Q. +It also counts requests that would have gone directly to +the XQ, but are rejected due to a full or nearly full condition, +indicating back pressure from the IDI link. The L2Q may also +reject transactions from a core to insure fairness between +cores, or to delay a core's dirty eviction when the address +conflicts incoming external snoops. (Note that L2 prefetcher +requests that are dropped are not counted by this event.). +.It Li CPU_CLK_UNHALTED.CORE_P +.Pq Event 3CH , Umask 00H +The number of core cycles while the core is not in a halt +state. The core enters the halt state when it is running +the HLT instruction. In mobile systems the core frequency +may change from time to time. For this reason this event +may have a changing ratio with regards to time. +.It Li CPU_CLK_UNHALTED.REF_P +.Pq Event 3CH , Umask 01H +The number of reference cycles that the core is not in a halt +state. The core enters the halt state when it is running +the HLT instruction. +In mobile systems the core frequency may change from time. +This event is not affected by core frequency changes but counts +as if the core is running at the maximum frequency all the time. +.It Li ICACHE.HIT +.Pq Event 80H , Umask 01H +The number of instruction fetches from the instruction cache. +.It Li ICACHE.MISSES +.Pq Event 80H , Umask 02H +The number of instruction fetches that miss the +Instruction cache or produce memory requests. This includes +uncacheable fetches. An instruction fetch miss is counted only +once and not once for every cycle it is outstanding. +.It Li ICACHE.ACCESSES +.Pq Event 80H , Umask 03H +The number of instruction fetches, including uncacheable fetches. +.It Li NIP_STALL.ICACHE_MISS +.Pq Event B6H , Umask 04H +The number of cycles the NIP stalls because of an icache miss. +This is a cumulative count of cycles the NIP stalled for all +icache misses. +.It Li OFFCORE_RESPONSE_0 +.Pq Event B7H , Umask 01H +Requires MSR_OFFCORE_RESP0 to specify request type and response. +.It Li OFFCORE_RESPONSE_1 +.Pq Event B7H , Umask 02H +Requires MSR_OFFCORE_RESP to specify request type and response. +.It Li INST_RETIRED.ANY_P +.Pq Event C0H , Umask 00H +The number of instructions that retire execution. For instructions +that consist of multiple micro-ops, this event counts the +retirement of the last micro-op of the instruction. The counter +continues counting during hardware interrupts, traps, and inside +interrupt handlers. +.It Li UOPS_RETIRED.MS +.Pq Event C2H , Umask 01H +The number of micro-ops retired that were supplied from MSROM. +.It Li UOPS_RETIRED.ALL +.Pq Event C2H , Umask 10H +The number of micro-ops retired. +.It Li MACHINE_CLEARS.SMC +.Pq Event C3H , Umask 01H +The number of times that a program writes to a code section. +Self-modifying code causes a severe penalty in all Intel +architecture processors. +.It Li MACHINE_CLEARS.MEMORY_ORDERING +.Pq Event C3H , Umask 02H +The number of times that pipeline was cleared due to memory +ordering issues. +.It Li MACHINE_CLEARS.FP_ASSIST +.Pq Event C3H , Umask 04H +The number of times that pipeline stalled due to FP operations +needing assists. +.It Li MACHINE_CLEARS.ALL +.Pq Event C3H , Umask 08H +The number of times that pipeline stalled due to due to any causes +(including SMC, MO, FP assist, etc). +.It Li BR_INST_RETIRED.ALL_BRANCHES +.Pq Event C4H , Umask 00H +The number of branch instructions retired. +.It Li BR_INST_RETIRED.JCC +.Pq Event C4H , Umask 7EH +The number of branch instructions retired that were conditional +jumps. +.It Li BR_INST_RETIRED.FAR_BRANCH +.Pq Event C4H , Umask BFH +The number of far branch instructions retired. +.It Li BR_INST_RETIRED.NON_RETURN_IND +.Pq Event C4H , Umask EBH +The number of branch instructions retired that were near indirect +call or near indirect jmp. +.It Li BR_INST_RETIRED.RETURN +.Pq Event C4H , Umask F7H +The number of near RET branch instructions retired. +.It Li BR_INST_RETIRED.CALL +.Pq Event C4H , Umask F9H +The number of near CALL branch instructions retired. +.It Li BR_INST_RETIRED.IND_CALL +.Pq Event C4H , Umask FBH +The number of near indirect CALL branch instructions retired. +.It Li BR_INST_RETIRED.REL_CALL +.Pq Event C4H , Umask FDH +The number of near relative CALL branch instructions retired. +.It Li BR_INST_RETIRED.TAKEN_JCC +.Pq Event C4H , Umask FEH +The number of branch instructions retired that were conditional +jumps and predicted taken. +.It Li BR_MISP_RETIRED.ALL_BRANCHES +.Pq Event C5H , Umask 00H +The number of mispredicted branch instructions retired. +.It Li BR_MISP_RETIRED.JCC +.Pq Event C5H , Umask 7EH +The number of mispredicted branch instructions retired that were +conditional jumps. +.It Li BR_MISP_RETIRED.FAR +.Pq Event C5H , Umask BFH +The number of mispredicted far branch instructions retired. +.It Li BR_MISP_RETIRED.NON_RETURN_IND +.Pq Event C5H , Umask EBH +The number of mispredicted branch instructions retired that were +near indirect call or near indirect jmp. +.It Li BR_MISP_RETIRED.RETURN +.Pq Event C5H , Umask F7H +The number of mispredicted near RET branch instructions retired. +.It Li BR_MISP_RETIRED.CALL +.Pq Event C5H , Umask F9H +The number of mispredicted near CALL branch instructions retired. +.It Li BR_MISP_RETIRED.IND_CALL +.Pq Event C5H , Umask FBH +The number of mispredicted near indirect CALL branch instructions +retired. +.It Li BR_MISP_RETIRED.REL_CALL +.Pq Event C5H , Umask FDH +The number of mispredicted near relative CALL branch instructions +retired. +.It Li BR_MISP_RETIRED.TAKEN_JCC +.Pq Event C5H , Umask FEH +The number of mispredicted branch instructions retired that were +conditional jumps and predicted taken. +.It Li NO_ALLOC_CYCLES.ROB_FULL +.Pq Event CAH , Umask 01H +The number of cycles when no uops are allocated and the ROB is full +(less than 2 entries available). +.It Li NO_ALLOC_CYCLES.RAT_STALL +.Pq Event CAH , Umask 20H +The number of cycles when no uops are allocated and a RATstall is +asserted. +.It Li NO_ALLOC_CYCLES.ALL +.Pq Event CAH , Umask 3FH +The number of cycles when the front-end does not provide any +instructions to be allocated for any reason. +.It Li NO_ALLOC_CYCLES.NOT_DELIVERED +.Pq Event CAH , Umask 50H +The number of cycles when the front-end does not provide any +instructions to be allocated but the back end is not stalled. +.It Li RS_FULL_STALL.MEC +.Pq Event CBH , Umask 01H +The number of cycles the allocation pipe line stalled due to +the RS for the MEC cluster is full. +.It Li RS_FULL_STALL.ALL +.Pq Event CBH , Umask 1FH +The number of cycles that the allocation pipe line stalled due +to any one of the RS is full. +.It Li CYCLES_DIV_BUSY.ANY +.Pq Event CDH , Umask 01H +The number of cycles the divider is busy. +.It Li BACLEARS.ALL +.Pq Event E6H , Umask 01H +The number of baclears for any type of branch. +.It Li BACLEARS.RETURN +.Pq Event E6H , Umask 08H +The number of baclears for return branches. +.It Li BACLEARS.COND +.Pq Event E6H , Umask 10H +The number of baclears for conditional branches. +.It Li MS_DECODED.MS_ENTRY +.Pq Event E7H , Umask 01H) +The number of times the MSROM starts a flow of UOPS. +.El +.Sh SEE ALSO +.Xr pmc 3 , +.Xr pmc.atom 3 , +.Xr pmc.core 3 , +.Xr pmc.core2 3 , +.Xr pmc.iaf 3 , +.Xr pmc.k7 3 , +.Xr pmc.k8 3 , +.Xr pmc.p4 3 , +.Xr pmc.p5 3 , +.Xr pmc.p6 3 , +.Xr pmc.soft 3 , +.Xr pmc.tsc 3 , +.Xr pmc_cpuinfo 3 , +.Xr pmclog 3 , +.Xr hwpmc 4 +.Sh HISTORY +The +.Nm pmc +library first appeared in +.Fx 6.0 . +.Sh AUTHORS +The +.Lb libpmc +library was written by +.An "Joseph Koshy" +.Aq jkoshy@FreeBSD.org . +The support for the Atom Silvermont +microarchitecture was written by +.An "Hiren Panchasara" +.Aq hiren@FreeBSD.org . diff --git a/lib/libpmc/pmc.h b/lib/libpmc/pmc.h index e17a584..81672d2 100644 --- a/lib/libpmc/pmc.h +++ b/lib/libpmc/pmc.h @@ -30,6 +30,7 @@ #define _PMC_H_ #include <sys/cdefs.h> +#include <sys/types.h> #include <sys/pmc.h> /* diff --git a/lib/libproc/Makefile b/lib/libproc/Makefile index 5b1df74..d221296 100644 --- a/lib/libproc/Makefile +++ b/lib/libproc/Makefile @@ -27,6 +27,6 @@ DPADD+= ${LIBSTDCPLUSPLUS} SHLIB_MAJOR= 2 -WITHOUT_MAN= +MAN= .include <bsd.lib.mk> diff --git a/lib/libproc/_libproc.h b/lib/libproc/_libproc.h index aee1ac1..8099ba1 100644 --- a/lib/libproc/_libproc.h +++ b/lib/libproc/_libproc.h @@ -49,7 +49,9 @@ struct proc_handle { }; #ifdef DEBUG -#define DPRINTF(fmt, ...) warn(fmt, __VA_ARGS__) +#define DPRINTF(...) warn(__VA_ARGS__) +#define DPRINTFX(...) warnx(__VA_ARGS__) #else -#define DPRINTF(fmt, ...) +#define DPRINTF(...) do { } while (0) +#define DPRINTFX(...) do { } while (0) #endif diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c index c15e53c..2c2761a 100644 --- a/lib/libproc/proc_bkpt.c +++ b/lib/libproc/proc_bkpt.c @@ -37,8 +37,9 @@ __FBSDID("$FreeBSD$"); #include <assert.h> #include <err.h> -#include <stdio.h> #include <errno.h> +#include <signal.h> +#include <stdio.h> #include "_libproc.h" #if defined(__i386__) || defined(__amd64__) @@ -54,12 +55,39 @@ __FBSDID("$FreeBSD$"); #error "Add support for your architecture" #endif +static void +proc_cont(struct proc_handle *phdl) +{ + + ptrace(PT_CONTINUE, proc_getpid(phdl), (caddr_t)1, 0); +} + +static int +proc_stop(struct proc_handle *phdl) +{ + int status; + + if (kill(proc_getpid(phdl), SIGSTOP) == -1) { + DPRINTF("kill %d", proc_getpid(phdl)); + return (-1); + } else if (waitpid(proc_getpid(phdl), &status, WSTOPPED) == -1) { + DPRINTF("waitpid %d", proc_getpid(phdl)); + return (-1); + } else if (!WIFSTOPPED(status)) { + DPRINTFX("waitpid: unexpected status 0x%x", status); + return (-1); + } + + return (0); +} + int proc_bkptset(struct proc_handle *phdl, uintptr_t address, unsigned long *saved) { struct ptrace_io_desc piod; unsigned long paddr, caddr; + int ret = 0; *saved = 0; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || @@ -68,6 +96,12 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, return (-1); } + DPRINTFX("adding breakpoint at 0x%lx", address); + + if (phdl->status != PS_STOP) + if (proc_stop(phdl) != 0) + return (-1); + /* * Read the original instruction. */ @@ -78,9 +112,10 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - DPRINTF("ERROR: couldn't read instruction at address 0x%" PRIuPTR, - address); - return (-1); + DPRINTF("ERROR: couldn't read instruction at address 0x%" + PRIuPTR, address); + ret = -1; + goto done; } *saved = paddr; /* @@ -93,12 +128,18 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - warn("ERROR: couldn't write instruction at address 0x%" PRIuPTR, - address); - return (-1); + DPRINTF("ERROR: couldn't write instruction at address 0x%" + PRIuPTR, address); + ret = -1; + goto done; } - return (0); +done: + if (phdl->status != PS_STOP) + /* Restart the process if we had to stop it. */ + proc_cont(phdl); + + return (ret); } int @@ -107,13 +148,20 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, { struct ptrace_io_desc piod; unsigned long paddr, caddr; + int ret = 0; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { errno = ENOENT; return (-1); } - DPRINTF("removing breakpoint at 0x%lx\n", address); + + DPRINTFX("removing breakpoint at 0x%lx", address); + + if (phdl->status != PS_STOP) + if (proc_stop(phdl) != 0) + return (-1); + /* * Overwrite the breakpoint instruction that we setup previously. */ @@ -124,12 +172,16 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - DPRINTF("ERROR: couldn't write instruction at address 0x%" PRIuPTR, - address); - return (-1); + DPRINTF("ERROR: couldn't write instruction at address 0x%" + PRIuPTR, address); + ret = -1; } + + if (phdl->status != PS_STOP) + /* Restart the process if we had to stop it. */ + proc_cont(phdl); - return (0); + return (ret); } /* @@ -153,12 +205,12 @@ proc_bkptexec(struct proc_handle *phdl, unsigned long saved) int status; if (proc_regget(phdl, REG_PC, &pc) < 0) { - warn("ERROR: couldn't get PC register"); + DPRINTFX("ERROR: couldn't get PC register"); return (-1); } proc_bkptregadj(&pc); if (proc_bkptdel(phdl, pc, saved) < 0) { - warn("ERROR: couldn't delete breakpoint"); + DPRINTFX("ERROR: couldn't delete breakpoint"); return (-1); } /* @@ -167,13 +219,13 @@ proc_bkptexec(struct proc_handle *phdl, unsigned long saved) */ proc_regset(phdl, REG_PC, pc); if (ptrace(PT_STEP, proc_getpid(phdl), (caddr_t)1, 0) < 0) { - warn("ERROR: ptrace step failed"); + DPRINTFX("ERROR: ptrace step failed"); return (-1); } proc_wstatus(phdl); status = proc_getwstat(phdl); if (!WIFSTOPPED(status)) { - warn("ERROR: don't know why process stopped"); + DPRINTFX("ERROR: don't know why process stopped"); return (-1); } /* @@ -181,7 +233,7 @@ proc_bkptexec(struct proc_handle *phdl, unsigned long saved) * the same as the one that we were passed in. */ if (proc_bkptset(phdl, pc, &samesaved) < 0) { - warn("ERROR: couldn't restore breakpoint"); + DPRINTFX("ERROR: couldn't restore breakpoint"); return (-1); } assert(samesaved == saved); diff --git a/lib/libproc/proc_create.c b/lib/libproc/proc_create.c index 9bd24a2..d02eccf 100644 --- a/lib/libproc/proc_create.c +++ b/lib/libproc/proc_create.c @@ -75,7 +75,7 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl) /* Check for an unexpected status. */ if (WIFSTOPPED(status) == 0) - DPRINTF("ERROR: child process %d status 0x%x", pid, status); + DPRINTFX("ERROR: child process %d status 0x%x", pid, status); else phdl->status = PS_STOP; @@ -130,14 +130,14 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf, /* Wait for the child process to stop. */ if (waitpid(pid, &status, WUNTRACED) == -1) { error = errno; - DPRINTF("ERROR: child process %d didn't stop as expected", pid); + DPRINTF("ERROR: child process %d didn't stop as expected", pid); goto bad; } /* Check for an unexpected status. */ if (WIFSTOPPED(status) == 0) { error = errno; - DPRINTF("ERROR: child process %d status 0x%x", pid, status); + DPRINTFX("ERROR: child process %d status 0x%x", pid, status); goto bad; } else phdl->status = PS_STOP; diff --git a/lib/libproc/proc_regs.c b/lib/libproc/proc_regs.c index aac0125..145c8fe 100644 --- a/lib/libproc/proc_regs.c +++ b/lib/libproc/proc_regs.c @@ -76,7 +76,7 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) #endif break; default: - warn("ERROR: no support for reg number %d", reg); + DPRINTFX("ERROR: no support for reg number %d", reg); return (-1); } @@ -119,7 +119,7 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) #endif break; default: - warn("ERROR: no support for reg number %d", reg); + DPRINTFX("ERROR: no support for reg number %d", reg); return (-1); } if (ptrace(PT_SETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c index 2dd21fe..2338895 100644 --- a/lib/libproc/proc_sym.c +++ b/lib/libproc/proc_sym.c @@ -96,7 +96,7 @@ proc_objname(struct proc_handle *p, uintptr_t addr, char *objname, for (i = 0; i < p->nobjs; i++) { rdl = &p->rdobjs[i]; - if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) { + if (addr >= rdl->rdl_saddr && addr < rdl->rdl_eaddr) { strlcpy(objname, rdl->rdl_path, objnamesz); return (objname); } @@ -176,7 +176,7 @@ proc_addr2map(struct proc_handle *p, uintptr_t addr) kve = kves + i; if (kve->kve_type == KVME_TYPE_VNODE) lastvn = i; - if (addr >= kve->kve_start && addr <= kve->kve_end) { + if (addr >= kve->kve_start && addr < kve->kve_end) { if ((map = malloc(sizeof(*map))) == NULL) { free(kves); return (NULL); @@ -209,7 +209,7 @@ proc_addr2map(struct proc_handle *p, uintptr_t addr) for (i = 0; i < p->nobjs; i++) { rdl = &p->rdobjs[i]; - if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) { + if (addr >= rdl->rdl_saddr && addr < rdl->rdl_eaddr) { if ((map = malloc(sizeof(*map))) == NULL) return (NULL); proc_rdl2prmap(rdl, map); @@ -238,16 +238,16 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, if ((map = proc_addr2map(p, addr)) == NULL) return (-1); - if (!map->pr_mapname || (fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { - warn("ERROR: open %s failed", map->pr_mapname); + if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { - warn("ERROR: elf_begin() failed"); + DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1)); goto err1; } if (gelf_getehdr(e, &ehdr) == NULL) { - warn("ERROR: gelf_getehdr() failed"); + DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1)); goto err2; } /* @@ -275,7 +275,7 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, * Then look up the string name in STRTAB (.dynstr) */ if ((data = elf_getdata(dynsymscn, NULL)) == NULL) { - DPRINTF("ERROR: elf_getdata() failed"); + DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1)); goto symtab; } i = 0; @@ -284,8 +284,11 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, * Calculate the address mapped to the virtual memory * by rtld. */ - rsym = map->pr_vaddr + sym.st_value; - if (addr >= rsym && addr <= (rsym + sym.st_size)) { + if (ehdr.e_type != ET_EXEC) + rsym = map->pr_vaddr + sym.st_value; + else + rsym = sym.st_value; + if (addr >= rsym && addr < rsym + sym.st_size) { s = elf_strptr(e, dynsymstridx, sym.st_name); if (s) { if (s[0] == '_' && s[1] == 'Z' && s[2]) @@ -309,10 +312,8 @@ symtab: * Iterate over the Symbols Table to find the symbol. * Then look up the string name in STRTAB (.dynstr) */ - if (symtabscn == NULL) - goto err2; if ((data = elf_getdata(symtabscn, NULL)) == NULL) { - DPRINTF("ERROR: elf_getdata() failed"); + DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1)); goto err2; } i = 0; @@ -325,7 +326,7 @@ symtab: rsym = map->pr_vaddr + sym.st_value; else rsym = sym.st_value; - if (addr >= rsym && addr <= (rsym + sym.st_size)) { + if (addr >= rsym && addr < rsym + sym.st_size) { s = elf_strptr(e, symtabstridx, sym.st_name); if (s) { if (s[0] == '_' && s[1] == 'Z' && s[2]) @@ -420,7 +421,7 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, unsigned long symtabstridx = 0, dynsymstridx = 0; if ((map = proc_name2map(p, object)) == NULL) { - DPRINTF("ERROR: couldn't find object %s", object); + DPRINTFX("ERROR: couldn't find object %s", object); goto err0; } if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { @@ -428,11 +429,11 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { - warn("ERROR: elf_begin() failed"); + DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1)); goto err1; } if (gelf_getehdr(e, &ehdr) == NULL) { - warn("ERROR: gelf_getehdr() failed"); + DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1)); goto err2; } /* @@ -460,13 +461,13 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, * Then look up the string name in STRTAB (.dynstr) */ if ((data = elf_getdata(dynsymscn, NULL))) { - DPRINTF("ERROR: elf_getdata() failed"); i = 0; while (gelf_getsym(data, i++, &sym) != NULL) { s = elf_strptr(e, dynsymstridx, sym.st_name); if (s && strcmp(s, symbol) == 0) { memcpy(symcopy, &sym, sizeof(sym)); - symcopy->st_value = map->pr_vaddr + sym.st_value; + if (ehdr.e_type != ET_EXEC) + symcopy->st_value += map->pr_vaddr; error = 0; goto out; } @@ -476,20 +477,21 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, * Iterate over the Symbols Table to find the symbol. * Then look up the string name in STRTAB (.dynstr) */ - if (symtabscn == NULL) - goto err2; if ((data = elf_getdata(symtabscn, NULL))) { i = 0; while (gelf_getsym(data, i++, &sym) != NULL) { s = elf_strptr(e, symtabstridx, sym.st_name); if (s && strcmp(s, symbol) == 0) { memcpy(symcopy, &sym, sizeof(sym)); + if (ehdr.e_type != ET_EXEC) + symcopy->st_value += map->pr_vaddr; error = 0; goto out; } } } out: + DPRINTFX("found addr 0x%lx for %s", symcopy->st_value, symbol); err2: elf_end(e); err1: @@ -510,6 +512,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, prmap_t *map; Elf_Scn *scn, *foundscn = NULL; Elf_Data *data; + GElf_Ehdr ehdr; GElf_Shdr shdr; GElf_Sym sym; unsigned long stridx = -1; @@ -519,13 +522,17 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, if ((map = proc_name2map(p, object)) == NULL) return (-1); if ((fd = open(map->pr_mapname, O_RDONLY)) < 0) { - warn("ERROR: open %s failed", map->pr_mapname); + DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { - warn("ERROR: elf_begin() failed"); + DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1)); goto err1; } + if (gelf_getehdr(e, &ehdr) == NULL) { + DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1)); + goto err2; + } /* * Find the section we are looking for. */ @@ -546,7 +553,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, return (-1); stridx = shdr.sh_link; if ((data = elf_getdata(foundscn, NULL)) == NULL) { - DPRINTF("ERROR: elf_getdata() failed"); + DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1)); goto err2; } i = 0; @@ -576,7 +583,8 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, (mask & TYPE_FILE) == 0) continue; s = elf_strptr(e, stridx, sym.st_name); - sym.st_value += map->pr_vaddr; + if (ehdr.e_type != ET_EXEC) + sym.st_value += map->pr_vaddr; (*func)(cd, &sym, s); } error = 0; diff --git a/lib/libproc/proc_util.c b/lib/libproc/proc_util.c index 089095e..1c3d522 100644 --- a/lib/libproc/proc_util.c +++ b/lib/libproc/proc_util.c @@ -146,7 +146,7 @@ proc_wstatus(struct proc_handle *phdl) return (-1); if (waitpid(phdl->pid, &status, WUNTRACED) < 0) { if (errno != EINTR) - warn("waitpid"); + DPRINTF("waitpid"); return (-1); } if (WIFSTOPPED(status)) diff --git a/lib/libproc/test/t1-bkpt/Makefile b/lib/libproc/test/t1-bkpt/Makefile index fd93fdd..eb5b37f 100644 --- a/lib/libproc/test/t1-bkpt/Makefile +++ b/lib/libproc/test/t1-bkpt/Makefile @@ -7,6 +7,6 @@ SRCS= t1-bkpt.c LDADD= -lproc -lelf -lrtld_db -lutil DPADD= ${LIBPROC} ${LIBELF} -WITHOUT_MAN= +MAN= .include <bsd.prog.mk> diff --git a/lib/libproc/test/t2-name2map/Makefile b/lib/libproc/test/t2-name2map/Makefile index 3dca51c..9002acc 100644 --- a/lib/libproc/test/t2-name2map/Makefile +++ b/lib/libproc/test/t2-name2map/Makefile @@ -7,6 +7,6 @@ SRCS= t2-name2map.c LDADD= -lproc -lelf -lrtld_db -lutil DPADD= ${LIBPROC} ${LIBELF} -WITHOUT_MAN= +MAN= .include <bsd.prog.mk> diff --git a/lib/libproc/test/t3-name2sym/Makefile b/lib/libproc/test/t3-name2sym/Makefile index 187f9c1..68e23c6 100644 --- a/lib/libproc/test/t3-name2sym/Makefile +++ b/lib/libproc/test/t3-name2sym/Makefile @@ -7,6 +7,6 @@ SRCS= t3-name2sym.c LDADD= -lproc -lelf -lrtld_db -lutil DPADD= ${LIBPROC} ${LIBELF} -WITHOUT_MAN= +MAN= .include <bsd.prog.mk> diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index e1ec7af..727419b 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -61,7 +61,7 @@ __FBSDID("$FreeBSD$"); #include <sys/conf.h> #include <sys/ksem.h> #include <sys/mman.h> -#include <sys/capability.h> +#include <sys/capsicum.h> #define _KERNEL #include <sys/mount.h> #include <sys/pipe.h> @@ -2052,7 +2052,7 @@ procstat_getumask_sysctl(pid_t pid, unsigned short *maskp) mib[3] = pid; len = sizeof(*maskp); error = sysctl(mib, 4, maskp, &len, NULL, 0); - if (error != 0 && errno != ESRCH) + if (error != 0 && errno != ESRCH && errno != EPERM) warn("sysctl: kern.proc.umask: %d", pid); return (error); } diff --git a/lib/libprocstat/zfs/Makefile b/lib/libprocstat/zfs/Makefile index 7ecfc85..9200f02 100644 --- a/lib/libprocstat/zfs/Makefile +++ b/lib/libprocstat/zfs/Makefile @@ -10,6 +10,7 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common +CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys diff --git a/lib/librpcsec_gss/Makefile b/lib/librpcsec_gss/Makefile index cc14a7b..67a7963 100644 --- a/lib/librpcsec_gss/Makefile +++ b/lib/librpcsec_gss/Makefile @@ -13,7 +13,7 @@ SYMBOL_MAPS= ${.CURDIR}/Symbol.map CFLAGS+= -I${.CURDIR}/../../include CFLAGS+= -I${.CURDIR}/../../libc_rpc -NO_PROFILE= +MK_PROFILE= no MAN= rpcsec_gss.3 MAN+= rpc_gss_seccreate.3 diff --git a/lib/libsm/Makefile b/lib/libsm/Makefile index ce590d7..07172c7 100644 --- a/lib/libsm/Makefile +++ b/lib/libsm/Makefile @@ -31,7 +31,7 @@ SRCS+= assert.c debug.c errstring.c exc.c heap.c match.c rpool.c \ wbuf.c wsetup.c string.c stringf.c \ xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c \ signal.c clock.c config.c sem.c shm.c mbdb.c strexit.c cf.c ldap.c \ - niprop.c mpeix.c memstat.c util.c + niprop.c mpeix.c memstat.c util.c inet6_ntop.c CLEANFILES+=sm_os.h INTERNALLIB= diff --git a/lib/libsmb/Makefile b/lib/libsmb/Makefile index 3a9a64d..e464a8f 100644 --- a/lib/libsmb/Makefile +++ b/lib/libsmb/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <bsd.own.mk> + CONTRIBDIR= ${.CURDIR}/../../contrib/smbfs .PATH: ${CONTRIBDIR}/lib/smb @@ -16,4 +18,8 @@ SRCS= rcfile.c ctx.c cfopt.c subr.c nls.c rap.c mbuf.c rq.c file.c \ WARNS?= 1 CFLAGS+= -DSMB_CFG_FILE=\"/etc/nsmb.conf\" -I${CONTRIBDIR}/include +.if ${MK_ICONV} != "no" +CFLAGS+= -DHAVE_ICONV=1 +.endif + .include <bsd.lib.mk> diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile index 33c155f..5f64520 100644 --- a/lib/libstand/Makefile +++ b/lib/libstand/Makefile @@ -6,11 +6,12 @@ # quite large. # -.include <bsd.own.mk> +MK_PROFILE= no MK_SSP= no +.include <bsd.own.mk> + LIB= stand -NO_PROFILE= NO_PIC= INCS= stand.h MAN= libstand.3 @@ -21,18 +22,20 @@ CFLAGS+= -ffreestanding -Wformat CFLAGS+= -I${.CURDIR} .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -mpreferred-stack-boundary=2 CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float .endif +.if ${MACHINE_CPUARCH} == "i386" +CFLAGS.gcc+= -mpreferred-stack-boundary=2 +.endif +.if ${MACHINE_CPUARCH} == "amd64" +CFLAGS+= -fPIC +.endif .if ${MACHINE} == "pc98" CFLAGS+= -Os .endif .if ${MACHINE_CPUARCH} == "powerpc" CFLAGS+= -msoft-float -D_STANDALONE -DNETIF_DEBUG .endif -.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -I. -.endif .if ${MACHINE_CPUARCH} == "arm" CFLAGS+= -msoft-float -D_STANDALONE .endif @@ -103,9 +106,7 @@ SRCS+= syncicache.c SRCS+= uuid_equal.c uuid_is_nil.c # _setjmp/_longjmp -.if ${MACHINE_CPUARCH} == "amd64" -.PATH: ${.CURDIR}/i386 -.elif ${MACHINE_ARCH} == "powerpc64" +.if ${MACHINE_ARCH} == "powerpc64" .PATH: ${.CURDIR}/powerpc .else .PATH: ${.CURDIR}/${MACHINE_CPUARCH} @@ -179,13 +180,3 @@ SRCS+= nandfs.c .include <bsd.lib.mk> -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend ${OBJS}: machine -cleandepend: cleanmachine -cleanmachine: - rm -f machine - -machine: - rm -f machine - ln -s ${.CURDIR}/../../sys/i386/include machine -.endif diff --git a/lib/libstand/close.c b/lib/libstand/close.c index 61b1b0d..939f025 100644 --- a/lib/libstand/close.c +++ b/lib/libstand/close.c @@ -75,8 +75,10 @@ close(int fd) errno = EBADF; return (-1); } - if (f->f_rabuf != NULL) + if (f->f_rabuf != NULL) { free(f->f_rabuf); + f->f_rabuf = NULL; + } if (!(f->f_flags & F_RAW) && f->f_ops) err1 = (f->f_ops->fo_close)(f); if (!(f->f_flags & F_NODEV) && f->f_dev) diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c index e15ecdc..72205a2 100644 --- a/lib/libstand/dosfs.c +++ b/lib/libstand/dosfs.c @@ -162,6 +162,14 @@ dos_mount(DOS_FS *fs, struct open_file *fd) (void)dosunmount(fs); return(err); } + fs->root = dot[0]; + fs->root.name[0] = ' '; + if (fs->fatsz == 32) { + fs->root.clus[0] = fs->rdcl & 0xff; + fs->root.clus[1] = (fs->rdcl >> 8) & 0xff; + fs->root.dex.h_clus[0] = (fs->rdcl >> 16) & 0xff; + fs->root.dex.h_clus[1] = (fs->rdcl >> 24) & 0xff; + } return 0; } @@ -381,21 +389,32 @@ dos_readdir(struct open_file *fd, struct dirent *d) if (dd.de.name[0] == 0xe5) continue; - /* Skip volume labels */ - if (dd.de.attr & FA_LABEL) - continue; - - if ((dd.de.attr & FA_MASK) == FA_XDE) { - if (dd.xde.seq & 0x40) - chk = dd.xde.chk; - else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk) - continue; - x = dd.xde.seq & ~0x40; - if (x < 1 || x > 20) { - x = 0; + /* Check if directory entry is volume label */ + if (dd.de.attr & FA_LABEL) { + /* + * If volume label set, check if the current entry is + * extended entry (FA_XDE) for long file names. + */ + if ((dd.de.attr & FA_MASK) == FA_XDE) { + /* + * Read through all following extended entries + * to get the long file name. 0x40 marks the + * last entry containing part of long file name. + */ + if (dd.xde.seq & 0x40) + chk = dd.xde.chk; + else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk) + continue; + x = dd.xde.seq & ~0x40; + if (x < 1 || x > 20) { + x = 0; + continue; + } + cp_xdnm(fn, &dd.xde); + } else { + /* skip only volume label entries */ continue; } - cp_xdnm(fn, &dd.xde); } else { if (xdn == 1) { x = 0; @@ -483,10 +502,12 @@ namede(DOS_FS *fs, const char *path, DOS_DE **dep) int err; err = 0; - de = dot; - if (*path == '/') - path++; + de = &fs->root; while (*path) { + while (*path == '/') + path++; + if (*path == '\0') + break; if (!(s = strchr(path, '/'))) s = strchr(path, 0); if ((n = s - path) > 255) @@ -498,8 +519,6 @@ namede(DOS_FS *fs, const char *path, DOS_DE **dep) return ENOTDIR; if ((err = lookup(fs, stclus(fs->fatsz, de), name, &de))) return err; - if (*path == '/') - path++; } *dep = de; return 0; diff --git a/lib/libstand/dosfs.h b/lib/libstand/dosfs.h index e44b6b5..9e5744d 100644 --- a/lib/libstand/dosfs.h +++ b/lib/libstand/dosfs.h @@ -23,6 +23,8 @@ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ */ #ifndef DOSIO_H @@ -108,6 +110,7 @@ typedef struct { u_int lsndta; /* start of data area */ u_int fatsz; /* FAT entry size */ u_int xclus; /* maximum cluster number */ + DOS_DE root; } DOS_FS; typedef struct { diff --git a/lib/libstand/environment.c b/lib/libstand/environment.c index fde4cf9..291e330 100644 --- a/lib/libstand/environment.c +++ b/lib/libstand/environment.c @@ -75,7 +75,14 @@ env_setenv(const char *name, int flags, const void *value, * for one already. */ if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK)) - return(ev->ev_sethook(ev, flags, value)); + return (ev->ev_sethook(ev, flags, value)); + + /* If there is data in the variable, discard it. */ + if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0) + free(ev->ev_value); + ev->ev_value = NULL; + ev->ev_flags &= ~EV_DYNAMIC; + } else { /* @@ -84,6 +91,7 @@ env_setenv(const char *name, int flags, const void *value, ev = malloc(sizeof(struct env_var)); ev->ev_name = strdup(name); ev->ev_value = NULL; + ev->ev_flags = 0; /* hooks can only be set when the variable is instantiated */ ev->ev_sethook = sethook; ev->ev_unsethook = unsethook; @@ -117,21 +125,16 @@ env_setenv(const char *name, int flags, const void *value, } } } - - /* If there is data in the variable, discard it */ - if (ev->ev_value != NULL) - free(ev->ev_value); /* If we have a new value, use it */ if (flags & EV_VOLATILE) { ev->ev_value = strdup(value); + ev->ev_flags |= EV_DYNAMIC; } else { ev->ev_value = (char *)value; + ev->ev_flags |= flags & EV_DYNAMIC; } - /* Keep the flag components that are relevant */ - ev->ev_flags = flags & (EV_DYNAMIC); - return(0); } @@ -201,7 +204,7 @@ env_discard(struct env_var *ev) if (environ == ev) environ = ev->ev_next; free(ev->ev_name); - if (ev->ev_flags & EV_DYNAMIC) + if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0) free(ev->ev_value); free(ev); } diff --git a/lib/libstand/powerpc/_setjmp.S b/lib/libstand/powerpc/_setjmp.S index 5a30810..3884b11 100644 --- a/lib/libstand/powerpc/_setjmp.S +++ b/lib/libstand/powerpc/_setjmp.S @@ -1,36 +1,115 @@ -/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */ +/* $FreeBSD$ */ +/* from: NetBSD: setjmp.S,v 1.1 1998/01/27 15:13:12 sakamoto Exp $ */ +/* from: OpenBSD: setjmp.S,v 1.2 1996/12/28 06:22:18 rahnds Exp */ +/* kernel version of this file, does not have signal goop */ +/* int setjmp(jmp_buf env) */ #include <machine/asm.h> -#if (defined(LIBC_SCCS) || defined(LIBC_RCS)) && !defined(lint) - .text - .asciz "$FreeBSD$" +#ifdef __powerpc64__ +#define LD_REG ld +#define ST_REG std +#define REGWIDTH 8 +#else +#define LD_REG lwz +#define ST_REG stw +#define REGWIDTH 4 #endif -/* - * C library -- _setjmp, _longjmp - * - * _longjmp(a,v) - * will generate a "return(v?v:1)" from the last call to - * _setjmp(a) - * by restoring registers from the stack. - * The previous signal state is NOT restored. - */ +#define JMP_r1 1*REGWIDTH +#define JMP_r2 2*REGWIDTH +#define JMP_r14 3*REGWIDTH +#define JMP_r15 4*REGWIDTH +#define JMP_r16 5*REGWIDTH +#define JMP_r17 6*REGWIDTH +#define JMP_r18 7*REGWIDTH +#define JMP_r19 8*REGWIDTH +#define JMP_r20 9*REGWIDTH +#define JMP_r21 10*REGWIDTH +#define JMP_r22 11*REGWIDTH +#define JMP_r23 12*REGWIDTH +#define JMP_r24 13*REGWIDTH +#define JMP_r25 14*REGWIDTH +#define JMP_r26 15*REGWIDTH +#define JMP_r27 16*REGWIDTH +#define JMP_r28 17*REGWIDTH +#define JMP_r29 18*REGWIDTH +#define JMP_r30 19*REGWIDTH +#define JMP_r31 20*REGWIDTH +#define JMP_lr 21*REGWIDTH +#define JMP_cr 22*REGWIDTH +#define JMP_ctr 23*REGWIDTH +#define JMP_xer 24*REGWIDTH +#define JMP_sig 25*REGWIDTH -ENTRY(_setjmp) - mflr 11 - mfcr 12 - mr 10,1 - mr 9,2 - stmw 9,8(3) - li 3,0 +ASENTRY_NOPROF(setjmp) + ST_REG 31, JMP_r31(3) + /* r1, r2, r14-r30 */ + ST_REG 1, JMP_r1 (3) + ST_REG 2, JMP_r2 (3) + ST_REG 14, JMP_r14(3) + ST_REG 15, JMP_r15(3) + ST_REG 16, JMP_r16(3) + ST_REG 17, JMP_r17(3) + ST_REG 18, JMP_r18(3) + ST_REG 19, JMP_r19(3) + ST_REG 20, JMP_r20(3) + ST_REG 21, JMP_r21(3) + ST_REG 22, JMP_r22(3) + ST_REG 23, JMP_r23(3) + ST_REG 24, JMP_r24(3) + ST_REG 25, JMP_r25(3) + ST_REG 26, JMP_r26(3) + ST_REG 27, JMP_r27(3) + ST_REG 28, JMP_r28(3) + ST_REG 29, JMP_r29(3) + ST_REG 30, JMP_r30(3) + /* cr, lr, ctr, xer */ + mfcr 0 + ST_REG 0, JMP_cr(3) + mflr 0 + ST_REG 0, JMP_lr(3) + mfctr 0 + ST_REG 0, JMP_ctr(3) + mfxer 0 + ST_REG 0, JMP_xer(3) + /* f14-f31, fpscr */ + li 3, 0 blr -ENTRY(_longjmp) - lmw 9,8(3) - mtlr 11 - mtcr 12 - mr 2,9 - mr 1,10 - mr 3,4 + +.extern sigsetmask +ASENTRY_NOPROF(longjmp) + LD_REG 31, JMP_r31(3) + /* r1, r2, r14-r30 */ + LD_REG 1, JMP_r1 (3) + LD_REG 2, JMP_r2 (3) + LD_REG 14, JMP_r14(3) + LD_REG 15, JMP_r15(3) + LD_REG 16, JMP_r16(3) + LD_REG 17, JMP_r17(3) + LD_REG 18, JMP_r18(3) + LD_REG 19, JMP_r19(3) + LD_REG 20, JMP_r20(3) + LD_REG 21, JMP_r21(3) + LD_REG 22, JMP_r22(3) + LD_REG 23, JMP_r23(3) + LD_REG 24, JMP_r24(3) + LD_REG 25, JMP_r25(3) + LD_REG 26, JMP_r26(3) + LD_REG 27, JMP_r27(3) + LD_REG 28, JMP_r28(3) + LD_REG 29, JMP_r29(3) + LD_REG 30, JMP_r30(3) + /* cr, lr, ctr, xer */ + LD_REG 0, JMP_cr(3) + mtcr 0 + LD_REG 0, JMP_lr(3) + mtlr 0 + LD_REG 0, JMP_ctr(3) + mtctr 0 + LD_REG 0, JMP_xer(3) + mtxer 0 + /* f14-f31, fpscr */ + mr 3, 4 blr diff --git a/lib/libstand/sbrk.c b/lib/libstand/sbrk.c index 93d94e4..471e78e 100644 --- a/lib/libstand/sbrk.c +++ b/lib/libstand/sbrk.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include "stand.h" +#include "zalloc_defs.h" static size_t maxheap, heapsize = 0; static void *heapbase; @@ -40,8 +41,9 @@ static void *heapbase; void setheap(void *base, void *top) { - /* Align start address to 16 bytes for the malloc code. Sigh. */ - heapbase = (void *)(((uintptr_t)base + 15) & ~15); + /* Align start address for the malloc code. Sigh. */ + heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) & + ~MALLOCALIGN_MASK); maxheap = (char *)top - (char *)heapbase; } diff --git a/lib/libstand/zalloc.c b/lib/libstand/zalloc.c index 41aef0d..4d1ec62 100644 --- a/lib/libstand/zalloc.c +++ b/lib/libstand/zalloc.c @@ -71,6 +71,15 @@ __FBSDID("$FreeBSD$"); #include "zalloc_defs.h" /* + * Objects in the pool must be aligned to at least the size of struct MemNode. + * They must also be aligned to MALLOCALIGN, which should normally be larger + * than the struct, so assert that to be so at compile time. + */ +typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1]; + +#define MEMNODE_SIZE_MASK MALLOCALIGN_MASK + +/* * znalloc() - allocate memory (without zeroing) from pool. Call reclaim * and retry if appropriate, return NULL if unable to allocate * memory. diff --git a/lib/libstand/zalloc_defs.h b/lib/libstand/zalloc_defs.h index 5331ee0..7f2cc12 100644 --- a/lib/libstand/zalloc_defs.h +++ b/lib/libstand/zalloc_defs.h @@ -52,18 +52,26 @@ #define BLKEXTENDMASK (BLKEXTEND - 1) /* - * required malloc alignment. Just hardwire to 16. + * Required malloc alignment. * - * Note: if we implement a more sophisticated realloc, we should ensure that - * MALLOCALIGN is at least as large as MemNode. + * Embedded platforms using the u-boot API drivers require that all I/O buffers + * be on a cache line sized boundary. The worst case size for that is 64 bytes. + * For other platforms, 16 bytes works fine. The alignment also must be at + * least sizeof(struct MemNode); this is asserted in zalloc.c. */ +#if defined(__arm__) || defined(__mips__) || defined(__powerpc__) +#define MALLOCALIGN 64 +#else +#define MALLOCALIGN 16 +#endif +#define MALLOCALIGN_MASK (MALLOCALIGN - 1) + typedef struct Guard { size_t ga_Bytes; size_t ga_Magic; /* must be at least 32 bits */ } Guard; -#define MALLOCALIGN 16 #define GAMAGIC 0x55FF44FD #define GAFREE 0x5F54F4DF diff --git a/lib/libstand/zalloc_mem.h b/lib/libstand/zalloc_mem.h index f29c0d7..26d388d 100644 --- a/lib/libstand/zalloc_mem.h +++ b/lib/libstand/zalloc_mem.h @@ -48,8 +48,6 @@ typedef struct MemPool { uintptr_t mp_Used; } MemPool; -#define MEMNODE_SIZE_MASK ((sizeof(MemNode) <= 8) ? 7 : 15) - #define ZNOTE_FREE 0 #define ZNOTE_REUSE 1 diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile index c4de29a..1c70a5e 100644 --- a/lib/libthr/Makefile +++ b/lib/libthr/Makefile @@ -60,7 +60,7 @@ SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a .endif -.if !defined(WITHOUT_SYSCALL_COMPAT) +.if ${MK_SYSCALL_COMPAT} != "no" CFLAGS+=-DSYSCALL_COMPAT .endif diff --git a/lib/libthr/thread/thr_kill.c b/lib/libthr/thread/thr_kill.c index b54458c58..8b0f683 100644 --- a/lib/libthr/thread/thr_kill.c +++ b/lib/libthr/thread/thr_kill.c @@ -42,24 +42,27 @@ __weak_reference(_pthread_kill, pthread_kill); int _pthread_kill(pthread_t pthread, int sig) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; /* Check for invalid signal numbers: */ if (sig < 0 || sig > _SIG_MAXSIG) /* Invalid signal: */ - ret = EINVAL; + return (EINVAL); + + curthread = _get_curthread(); + /* * Ensure the thread is in the list of active threads, and the * signal is valid (signal 0 specifies error checking only) and * not being ignored: */ - else if (curthread == pthread) { + if (curthread == pthread) { if (sig > 0) _thr_send_sig(pthread, sig); ret = 0; - } if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) - == 0) { + } else if ((ret = _thr_find_thread(curthread, pthread, + /*include dead*/0)) == 0) { if (sig > 0) _thr_send_sig(pthread, sig); THR_THREAD_UNLOCK(curthread, pthread); diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 83a02b5..c6651cd 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -433,6 +433,9 @@ struct pthread { /* the sigaction should be used for deferred signal. */ struct sigaction deferred_sigact; + /* deferred signal delivery is performed, do not reenter. */ + int deferred_run; + /* Force new thread to exit. */ int force_exit; diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c index 415ddb0..57c9406 100644 --- a/lib/libthr/thread/thr_sig.c +++ b/lib/libthr/thread/thr_sig.c @@ -162,6 +162,7 @@ thr_sighandler(int sig, siginfo_t *info, void *_ucp) act = _thr_sigact[sig-1].sigact; _thr_rwl_unlock(&_thr_sigact[sig-1].lock); errno = err; + curthread->deferred_run = 0; /* * if a thread is in critical region, for example it holds low level locks, @@ -320,14 +321,18 @@ check_deferred_signal(struct pthread *curthread) siginfo_t info; int uc_len; - if (__predict_true(curthread->deferred_siginfo.si_signo == 0)) + if (__predict_true(curthread->deferred_siginfo.si_signo == 0 || + curthread->deferred_run)) return; + curthread->deferred_run = 1; uc_len = __getcontextx_size(); uc = alloca(uc_len); getcontext(uc); - if (curthread->deferred_siginfo.si_signo == 0) + if (curthread->deferred_siginfo.si_signo == 0) { + curthread->deferred_run = 0; return; + } __fillcontextx2((char *)uc); act = curthread->deferred_sigact; uc->uc_sigmask = curthread->deferred_sigmask; diff --git a/lib/libucl/Makefile b/lib/libucl/Makefile new file mode 100644 index 0000000..3832c9f --- /dev/null +++ b/lib/libucl/Makefile @@ -0,0 +1,22 @@ +# $FreeBSD$ + +LIBUCL= ${.CURDIR}/../../contrib/libucl + +LIB= ucl +PRIVATELIB= true +SHLIB_MAJOR= 1 +SRCS= ucl_emitter.c \ + ucl_hash.c \ + ucl_parser.c \ + ucl_schema.c \ + ucl_util.c \ + xxhash.c + +.PATH: ${LIBUCL}/src + +WARNS= 1 +CFLAGS+= -I${LIBUCL}/include \ + -I${LIBUCL}/src \ + -I${LIBUCL}/uthash + +.include <bsd.lib.mk> diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile index 99bdfc2..92c0843 100644 --- a/lib/libusb/Makefile +++ b/lib/libusb/Makefile @@ -130,6 +130,8 @@ MLINKS += libusb.3 libusb_event_handler_active.3 MLINKS += libusb.3 libusb_lock_event_waiters.3 MLINKS += libusb.3 libusb_unlock_event_waiters.3 MLINKS += libusb.3 libusb_wait_for_event.3 +MLINKS += libusb.3 libusb_handle_events_timeout_completed.3 +MLINKS += libusb.3 libusb_handle_events_completed.3 MLINKS += libusb.3 libusb_handle_events_timeout.3 MLINKS += libusb.3 libusb_handle_events.3 MLINKS += libusb.3 libusb_handle_events_locked.3 diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 index b50981c..785c8c4 100644 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 7, 2013 +.Dd January 5, 2014 .Dt LIBUSB 3 .Os .Sh NAME @@ -485,11 +485,40 @@ transfer completes or another thread stops event handling, and 1 if the timeout expired. .Pp .Ft int +.Fn libusb_handle_events_timeout_completed "libusb_context *ctx" "struct timeval *tv" "int *completed" +Handle any pending events by checking if timeouts have expired and by +checking the set of file descriptors for activity. +If the +.Fa completed +argument is not equal to NULL, this function will +loop until a transfer completion callback sets the variable pointed to +by the +.Fa completed +argument to non-zero. +If the +.Fa tv +argument is not equal to NULL, this function will return +LIBUSB_ERROR_TIMEOUT after the given timeout. +Returns 0 on success, or a LIBUSB_ERROR code on failure or timeout. +.Pp +.Ft int +.Fn libusb_handle_events_completed "libusb_context *ctx" "int *completed" +Handle any pending events by checking the set of file descriptors for activity. +If the +.Fa completed +argument is not equal to NULL, this function will +loop until a transfer completion callback sets the variable pointed to +by the +.Fa completed +argument to non-zero. +Returns 0 on success, or a LIBUSB_ERROR code on failure. +.Pp +.Ft int .Fn libusb_handle_events_timeout "libusb_context *ctx" "struct timeval *tv" Handle any pending events by checking if timeouts have expired and by checking the set of file descriptors for activity. Returns 0 on success, or a -LIBUSB_ERROR code on failure. +LIBUSB_ERROR code on failure or timeout. .Pp .Ft int .Fn libusb_handle_events "libusb_context *ctx" @@ -508,7 +537,7 @@ Must be called with the event lock held. Determine the next internal timeout that libusb needs to handle. Returns 0 if there are no pending timeouts, 1 if a timeout was returned, or a LIBUSB_ERROR -code on failure. +code on failure or timeout. .Pp .Ft void .Fn libusb_set_pollfd_notifiers "libusb_context *ctx" "libusb_pollfd_added_cb added_cb" "libusb_pollfd_removed_cb remove_cb" "void *user_data" diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index b14990e..4857f5b 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -192,6 +192,19 @@ enum libusb_transfer_flags { LIBUSB_TRANSFER_FREE_TRANSFER = 1 << 2, }; +enum libusb_log_level { + LIBUSB_LOG_LEVEL_NONE = 0, + LIBUSB_LOG_LEVEL_ERROR, + LIBUSB_LOG_LEVEL_WARNING, + LIBUSB_LOG_LEVEL_INFO, + LIBUSB_LOG_LEVEL_DEBUG +}; + +/* XXX */ +/* libusb_set_debug should take parameters from libusb_log_level + * above according to + * http://libusb.sourceforge.net/api-1.0/group__lib.html + */ enum libusb_debug_level { LIBUSB_DEBUG_NO=0, LIBUSB_DEBUG_FUNCTION=1, @@ -438,6 +451,8 @@ int libusb_event_handler_active(libusb_context * ctx); void libusb_lock_event_waiters(libusb_context * ctx); void libusb_unlock_event_waiters(libusb_context * ctx); int libusb_wait_for_event(libusb_context * ctx, struct timeval *tv); +int libusb_handle_events_timeout_completed(libusb_context * ctx, struct timeval *tv, int *completed); +int libusb_handle_events_completed(libusb_context * ctx, int *completed); int libusb_handle_events_timeout(libusb_context * ctx, struct timeval *tv); int libusb_handle_events(libusb_context * ctx); int libusb_handle_events_locked(libusb_context * ctx, struct timeval *tv); diff --git a/lib/libusb/libusb01.c b/lib/libusb/libusb01.c index 30a1430..91ae6e2 100644 --- a/lib/libusb/libusb01.c +++ b/lib/libusb/libusb01.c @@ -127,6 +127,8 @@ usb_get_transfer_by_ep_no(usb_dev_handle * dev, uint8_t ep_no) bufsize = 256; } else if (speed == LIBUSB20_SPEED_FULL) { bufsize = 4096; + } else if (speed == LIBUSB20_SPEED_SUPER) { + bufsize = 65536; } else { bufsize = 16384; } diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 79a570e..e8f9314 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -611,7 +611,6 @@ int libusb_claim_interface(struct libusb20_device *pdev, int interface_number) { libusb_device *dev; - int err = 0; dev = libusb_get_device(pdev); if (dev == NULL) @@ -621,13 +620,10 @@ libusb_claim_interface(struct libusb20_device *pdev, int interface_number) return (LIBUSB_ERROR_INVALID_PARAM); CTX_LOCK(dev->ctx); - if (dev->claimed_interfaces & (1 << interface_number)) - err = LIBUSB_ERROR_BUSY; - - if (!err) - dev->claimed_interfaces |= (1 << interface_number); + dev->claimed_interfaces |= (1 << interface_number); CTX_UNLOCK(dev->ctx); - return (err); + + return (0); } int @@ -939,6 +935,9 @@ libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) case LIBUSB20_SPEED_FULL: ret = 4096; break; + case LIBUSB20_SPEED_SUPER: + ret = 65536; + break; default: ret = 16384; break; diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c index 9aa31c4..e27bbba 100644 --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -336,29 +336,50 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) } int -libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv) +libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed) { - int err; + int err = 0; ctx = GET_CONTEXT(ctx); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed enter"); libusb_lock_events(ctx); - err = libusb_handle_events_locked(ctx, tv); + while (1) { + if (completed != NULL) { + if (*completed != 0 || err != 0) + break; + } + err = libusb_handle_events_locked(ctx, tv); + if (completed == NULL) + break; + } libusb_unlock_events(ctx); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed exit"); return (err); } int +libusb_handle_events_completed(libusb_context *ctx, int *completed) +{ + return (libusb_handle_events_timeout_completed(ctx, NULL, completed)); +} + +int +libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv) +{ + return (libusb_handle_events_timeout_completed(ctx, tv, NULL)); +} + +int libusb_handle_events(libusb_context *ctx) { - return (libusb_handle_events_timeout(ctx, NULL)); + return (libusb_handle_events_timeout_completed(ctx, NULL, NULL)); } int @@ -371,8 +392,9 @@ libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv) if (libusb_event_handling_ok(ctx)) { err = libusb10_handle_events_sub(ctx, tv); } else { - libusb_wait_for_event(ctx, tv); - err = 0; + err = libusb_wait_for_event(ctx, tv); + if (err != 0) + err = LIBUSB_ERROR_TIMEOUT; } return (err); } diff --git a/lib/libutil/expand_number.3 b/lib/libutil/expand_number.3 index f78223b..2f5871f 100644 --- a/lib/libutil/expand_number.3 +++ b/lib/libutil/expand_number.3 @@ -51,12 +51,13 @@ argument. The .Fn expand_number function +is case-insensitive and follows the SI power of two convention. .Pp The prefixes are: .Bl -column "Prefix" "Description" "1000000000000000000" -offset indent .It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" -.It Li k Ta No kilo Ta 1024 +.It Li K Ta No kilo Ta 1024 .It Li M Ta No mega Ta 1048576 .It Li G Ta No giga Ta 1073741824 .It Li T Ta No tera Ta 1099511627776 diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5 index a07e1f0..e780940 100644 --- a/lib/libutil/login.conf.5 +++ b/lib/libutil/login.conf.5 @@ -50,9 +50,7 @@ non-root user without a valid login class in A user with a uid of 0 without a valid login class will use the record "root" if it exists, or "default" if not. .Pp -In -.Fx , -users may individually create a file called +Users may individually create a file called .Pa .login_conf in their home directory using the same format, consisting of a single entry with a record id of "me". @@ -132,6 +130,7 @@ tag being delimited from the value by '=' instead of '#'). Whichever method is used, then all records in the database must use the same method to allow values to be correctly overridden in interpolated records. +A numeric value may be infinite. .It size A number which expresses a size. The default interpretation of a value is the number of bytes, but a @@ -150,6 +149,7 @@ represents terabytes. .El A size value is a numeric quantity and case of the suffix is not significant. Concatenated values are added together. +A size value may be infinite. .It time A period of time, by default in seconds. A prefix may specify a different unit: @@ -170,8 +170,16 @@ the number of seconds. Concatenated values are added together. For example, 2 hours and 40 minutes may be written either as 9600s, 160m or 2h40m. +A time value may be infinite. .El .Pp +.Dq infinity , +.Dq inf , +.Dq unlimited , +.Dq unlimit, +and -1 +are considered infinite values. +.Pp The usual convention to interpolate capability entries using the special .Em tc=value notation may be used. diff --git a/lib/libutil/login_class.3 b/lib/libutil/login_class.3 index 62a65f2..75f3614 100644 --- a/lib/libutil/login_class.3 +++ b/lib/libutil/login_class.3 @@ -118,6 +118,7 @@ sbsize RLIMIT_SBSIZE vmemoryuse RLIMIT_VMEM pseudoterminals RLIMIT_NPTS swapuse RLIMIT_SWAP +kqueues RLIMIT_KQUEUES .Ed .It LOGIN_SETPRIORITY Set the scheduling priority for the current process based on the diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 263044f..39cce12 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -66,6 +66,7 @@ static struct login_res { { "vmemoryuse", login_getcapsize, RLIMIT_VMEM }, { "pseudoterminals", login_getcapnum, RLIMIT_NPTS }, { "swapuse", login_getcapsize, RLIMIT_SWAP }, + { "kqueues", login_getcapsize, RLIMIT_KQUEUES }, { NULL, 0, 0 } }; diff --git a/lib/libutil/pw_util.3 b/lib/libutil/pw_util.3 index 7ef0657..6c449ba 100644 --- a/lib/libutil/pw_util.3 +++ b/lib/libutil/pw_util.3 @@ -48,13 +48,13 @@ .In pwd.h .In libutil.h .Ft int -.Fn pw_copy "int ffd" "int tfd" "const struct passwd *pw" "const struct passwd *oldpw" +.Fn pw_copy "int ffd" "int tfd" "const struct passwd *pw" "struct passwd *oldpw" .Ft "struct passwd *" .Fn pw_dup "const struct passwd *pw" .Ft int .Fn pw_edit "int nosetuid" .Ft int -.Fn pw_equal "const struct passwd *pw1" "const struct passwd pw2" +.Fn pw_equal "const struct passwd *pw1" "const struct passwd *pw2" .Ft void .Fn pw_fini "void" .Ft int diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 810b39e..60d3105 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -342,36 +342,40 @@ vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *vmexit) return (error); } +int +vm_suspend(struct vmctx *ctx) +{ + + return (ioctl(ctx->fd, VM_SUSPEND, 0)); +} + static int -vm_inject_event_real(struct vmctx *ctx, int vcpu, enum vm_event_type type, - int vector, int error_code, int error_code_valid) +vm_inject_exception_real(struct vmctx *ctx, int vcpu, int vector, + int error_code, int error_code_valid) { - struct vm_event ev; + struct vm_exception exc; - bzero(&ev, sizeof(ev)); - ev.cpuid = vcpu; - ev.type = type; - ev.vector = vector; - ev.error_code = error_code; - ev.error_code_valid = error_code_valid; + bzero(&exc, sizeof(exc)); + exc.cpuid = vcpu; + exc.vector = vector; + exc.error_code = error_code; + exc.error_code_valid = error_code_valid; - return (ioctl(ctx->fd, VM_INJECT_EVENT, &ev)); + return (ioctl(ctx->fd, VM_INJECT_EXCEPTION, &exc)); } int -vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, - int vector) +vm_inject_exception(struct vmctx *ctx, int vcpu, int vector) { - return (vm_inject_event_real(ctx, vcpu, type, vector, 0, 0)); + return (vm_inject_exception_real(ctx, vcpu, vector, 0, 0)); } int -vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, - int vector, int error_code) +vm_inject_exception2(struct vmctx *ctx, int vcpu, int vector, int errcode) { - return (vm_inject_event_real(ctx, vcpu, type, vector, error_code, 1)); + return (vm_inject_exception_real(ctx, vcpu, vector, errcode, 1)); } int @@ -397,6 +401,105 @@ vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) } int +vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector) +{ + struct vm_lapic_irq vmirq; + + bzero(&vmirq, sizeof(vmirq)); + vmirq.cpuid = vcpu; + vmirq.vector = vector; + + return (ioctl(ctx->fd, VM_LAPIC_LOCAL_IRQ, &vmirq)); +} + +int +vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg) +{ + struct vm_lapic_msi vmmsi; + + bzero(&vmmsi, sizeof(vmmsi)); + vmmsi.addr = addr; + vmmsi.msg = msg; + + return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi)); +} + +int +vm_ioapic_assert_irq(struct vmctx *ctx, int irq) +{ + struct vm_ioapic_irq ioapic_irq; + + bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); + ioapic_irq.irq = irq; + + return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq)); +} + +int +vm_ioapic_deassert_irq(struct vmctx *ctx, int irq) +{ + struct vm_ioapic_irq ioapic_irq; + + bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); + ioapic_irq.irq = irq; + + return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq)); +} + +int +vm_ioapic_pulse_irq(struct vmctx *ctx, int irq) +{ + struct vm_ioapic_irq ioapic_irq; + + bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); + ioapic_irq.irq = irq; + + return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq)); +} + +int +vm_ioapic_pincount(struct vmctx *ctx, int *pincount) +{ + + return (ioctl(ctx->fd, VM_IOAPIC_PINCOUNT, pincount)); +} + +int +vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) +{ + struct vm_isa_irq isa_irq; + + bzero(&isa_irq, sizeof(struct vm_isa_irq)); + isa_irq.atpic_irq = atpic_irq; + isa_irq.ioapic_irq = ioapic_irq; + + return (ioctl(ctx->fd, VM_ISA_ASSERT_IRQ, &isa_irq)); +} + +int +vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) +{ + struct vm_isa_irq isa_irq; + + bzero(&isa_irq, sizeof(struct vm_isa_irq)); + isa_irq.atpic_irq = atpic_irq; + isa_irq.ioapic_irq = ioapic_irq; + + return (ioctl(ctx->fd, VM_ISA_DEASSERT_IRQ, &isa_irq)); +} + +int +vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) +{ + struct vm_isa_irq isa_irq; + bzero(&isa_irq, sizeof(struct vm_isa_irq)); + isa_irq.atpic_irq = atpic_irq; + isa_irq.ioapic_irq = ioapic_irq; + + return (ioctl(ctx->fd, VM_ISA_PULSE_IRQ, &isa_irq)); +} + +int vm_inject_nmi(struct vmctx *ctx, int vcpu) { struct vm_nmi vmnmi; @@ -415,6 +518,7 @@ static struct { { "mtrap_exit", VM_CAP_MTRAP_EXIT }, { "pause_exit", VM_CAP_PAUSE_EXIT }, { "unrestricted_guest", VM_CAP_UNRESTRICTED_GUEST }, + { "enable_invpcid", VM_CAP_ENABLE_INVPCID }, { 0 } }; @@ -517,8 +621,8 @@ vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, } int -vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, - int destcpu, int vector, int numvec) +vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, + uint64_t addr, uint64_t msg, int numvec) { struct vm_pptdev_msi pptmsi; @@ -527,16 +631,16 @@ vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, pptmsi.bus = bus; pptmsi.slot = slot; pptmsi.func = func; - pptmsi.destcpu = destcpu; - pptmsi.vector = vector; + pptmsi.msg = msg; + pptmsi.addr = addr; pptmsi.numvec = numvec; return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); } int -vm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, - int idx, uint32_t msg, uint32_t vector_control, uint64_t addr) +vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, + int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) { struct vm_pptdev_msix pptmsix; @@ -791,3 +895,16 @@ vm_get_gpa_pmap(struct vmctx *ctx, uint64_t gpa, uint64_t *pte, int *num) return (error); } + +int +vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities) +{ + int error; + struct vm_hpet_cap cap; + + bzero(&cap, sizeof(struct vm_hpet_cap)); + error = ioctl(ctx->fd, VM_GET_HPET_CAPABILITIES, &cap); + if (capabilities != NULL) + *capabilities = cap.capabilities; + return (error); +} diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index 0720e2e..ed63fb2 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -61,12 +61,20 @@ int vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val); int vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *retval); int vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *ret_vmexit); +int vm_suspend(struct vmctx *ctx); int vm_apicid2vcpu(struct vmctx *ctx, int apicid); -int vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, - int vector); -int vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, - int vector, int error_code); +int vm_inject_exception(struct vmctx *ctx, int vcpu, int vec); +int vm_inject_exception2(struct vmctx *ctx, int vcpu, int vec, int errcode); int vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector); +int vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector); +int vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg); +int vm_ioapic_assert_irq(struct vmctx *ctx, int irq); +int vm_ioapic_deassert_irq(struct vmctx *ctx, int irq); +int vm_ioapic_pulse_irq(struct vmctx *ctx, int irq); +int vm_ioapic_pincount(struct vmctx *ctx, int *pincount); +int vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); +int vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); +int vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); int vm_inject_nmi(struct vmctx *ctx, int vcpu); int vm_capability_name2type(const char *capname); const char *vm_capability_type2name(int type); @@ -78,10 +86,11 @@ int vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); -int vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, - int dest, int vector, int numvec); -int vm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, - int idx, uint32_t msg, uint32_t vector_control, uint64_t addr); +int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, + int func, uint64_t addr, uint64_t msg, int numvec); +int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, + int func, int idx, uint64_t addr, uint64_t msg, + uint32_t vector_control); /* * Return a pointer to the statistics buffer. Note that this is not MT-safe. @@ -93,6 +102,8 @@ const char *vm_get_stat_desc(struct vmctx *ctx, int index); int vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *s); int vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state s); +int vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities); + /* Reset vcpu register state */ int vcpu_reset(struct vmctx *ctx, int vcpu); @@ -102,5 +113,8 @@ int vcpu_reset(struct vmctx *ctx, int vcpu); int vm_setup_freebsd_registers(struct vmctx *ctx, int vcpu, uint64_t rip, uint64_t cr3, uint64_t gdtbase, uint64_t rsp); +int vm_setup_freebsd_registers_i386(struct vmctx *vmctx, int vcpu, + uint32_t eip, uint32_t gdtbase, + uint32_t esp); void vm_setup_freebsd_gdt(uint64_t *gdtr); #endif /* _VMMAPI_H_ */ diff --git a/lib/libyaml/Makefile b/lib/libyaml/Makefile deleted file mode 100644 index 5ecec78..0000000 --- a/lib/libyaml/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# $FreeBSD$ - -LIBYAML= ${.CURDIR}/../../contrib/libyaml - -LIB= bsdyml -SHLIB_MAJOR= 0 -INCS= bsdyml.h -SRCS= api.c dumper.c emitter.c loader.c \ - parser.c reader.c scanner.c writer.c -MAN= libbsdyml.3 - -.PATH: ${LIBYAML}/src ${LIBYAML}/include -CLEANFILES= bsdyml.h - -WARNS?= 1 -CFLAGS+= -I${LIBYAML}/include \ - -I${LIBYAML} \ - -I${.CURDIR} \ - -DHAVE_CONFIG_H - -bsdyml.h: yaml.h - cp -f ${.ALLSRC} ${.TARGET} - -.include <bsd.lib.mk> diff --git a/lib/libyaml/Makefile.depend b/lib/libyaml/Makefile.depend deleted file mode 100644 index 65ce567..0000000 --- a/lib/libyaml/Makefile.depend +++ /dev/null @@ -1,18 +0,0 @@ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/lib/libgcc \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/lib/libyaml/config.h b/lib/libyaml/config.h deleted file mode 100644 index 7032919..0000000 --- a/lib/libyaml/config.h +++ /dev/null @@ -1,83 +0,0 @@ -/* $FreeBSD$ */ - -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "yaml" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "http://pyyaml.org/newticket?component=libyaml" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "yaml" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "yaml 0.1.4" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "yaml" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.1.4" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.1.4" - -/* Define the major version number. */ -#define YAML_VERSION_MAJOR 0 - -/* Define the minor version number. */ -#define YAML_VERSION_MINOR 1 - -/* Define the patch version number. */ -#define YAML_VERSION_PATCH 4 - -/* Define the version string. */ -#define YAML_VERSION_STRING "0.1.4" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ diff --git a/lib/libyaml/libbsdyml.3 b/lib/libyaml/libbsdyml.3 deleted file mode 100644 index 927c47c..0000000 --- a/lib/libyaml/libbsdyml.3 +++ /dev/null @@ -1,61 +0,0 @@ -.\" Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org> -.\" 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 05, 2013 -.Dt LIBBSDYML 3 -.Os -.Sh NAME -.Nm libbsdyml -.Nd LibYAML library for parsing and emitting YAML -.Sh SYNOPSIS -.In bsdyml.h -.Sh DESCRIPTION -The -.Nm -library is a verbatim copy of the LibYAML version 0.1.4 -.Pp -The -.Nm -library is intended to be used within the -.Fx -base system only. -Use of the -.Nm -library for other purposes is not supported and discouraged. -.Pp -To avoid version and autoconfiguration issues, the library has been -renamed to -.Nm -rather than retain the original LibYAML library and include file names -to prevent confusion and autoconfiguration issues for 3rd party -software. -.Sh SEE ALSO -For full documentation, please see the LibYAML webpage at -.Pa http://pyyaml.org/wiki/LibYAML . -.Sh AUTHORS -.An -nosplit -The original LibYAML was written by -.An Kirill Simonov Aq xi@resolvent.net . diff --git a/lib/libz/FREEBSD-upgrade b/lib/libz/FREEBSD-upgrade index d2d251b..4ee4eeb 100644 --- a/lib/libz/FREEBSD-upgrade +++ b/lib/libz/FREEBSD-upgrade @@ -1,4 +1,4 @@ -$FreeBSD: head/lib/libz/FREEBSD-upgrade 146082 2005-05-11 03:50:50Z kientzle $ +$FreeBSD$ ZLib 1.2.2 diff --git a/lib/libz/Makefile b/lib/libz/Makefile index 4ecb022..fe6fb29 100644 --- a/lib/libz/Makefile +++ b/lib/libz/Makefile @@ -1,11 +1,11 @@ # -# $FreeBSD: head/lib/libz/Makefile 232263 2012-02-28 18:30:18Z dim $ +# $FreeBSD$ # LIB= z SHLIBDIR?= /lib SHLIB_MAJOR= 6 -MAN= zlib.3 +MAN= zlib.3 zopen.3 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 #CFLAGS=-g -DDEBUG diff --git a/lib/libz/Symbol.map b/lib/libz/Symbol.map index b117cdd..731ce0a 100644 --- a/lib/libz/Symbol.map +++ b/lib/libz/Symbol.map @@ -1,5 +1,5 @@ /* - * $FreeBSD: head/lib/libz/Symbol.map 206709 2010-04-16 20:07:24Z delphij $ + * $FreeBSD$ */ ZLIB_1.2.7.1 { diff --git a/lib/libz/Versions.def b/lib/libz/Versions.def index f8e6425..4651e77 100644 --- a/lib/libz/Versions.def +++ b/lib/libz/Versions.def @@ -1,4 +1,4 @@ -# $FreeBSD: head/lib/libz/Versions.def 205486 2010-03-22 22:12:27Z delphij $ +# $FreeBSD$ ZLIB_1.2.4.0 { }; diff --git a/lib/libz/zopen.3 b/lib/libz/zopen.3 new file mode 100644 index 0000000..d7e631a --- /dev/null +++ b/lib/libz/zopen.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2014 Xin Li <delphij@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 5, 2014 +.Dt ZOPEN 3 +.Os +.Sh NAME +.Nm zopen +.Nd open a gzip compressed stream +.Sh LIBRARY +.Lb libz +.Sh SYNOPSIS +.Ft FILE * +.Fn zopen "const char *path" "const char *mode" +.Sh DESCRIPTION +The +.Fn zopen +opens a gzip file whose name is the string pointed to by +.Fa path +and associates a stream with it. +It is a wrapper around +.Xr zlib 3 +and standard stream I/O APIs. +.Pp +The argument +.Fa mode +have the same meaning as it does in +.Xr fopen 3 . +.Pp +The +.Nm +function will associate read, write, seek and close +functions of +.Xr zlib 3 +after successfully opened a file with +.Xr funopen 3 +so that they will be used to read or write the new stream. +.Sh RETURN VALUES +Upon successful completion +.Nm +returns a +.Tn FILE +pointer. +Otherwise, +.Dv NULL +is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +In addition to the errors documented for +.Xr fopen 3 , +the +.Nm +function may also fail for: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient memory is available. +.El +.Sh COMPATIBILITY +This implementation of +.Nm +function first appeared in +.Nx 1.6 +and +.Fx 4.5 . +The +.Nm +function may not be portable to systems other than +.Fx . +.Sh SEE ALSO +.Xr fopen 3 , +.Xr funopen 3 , +.Xr zlib 3 diff --git a/lib/libz/zopen.c b/lib/libz/zopen.c index 822a5e1..cde022d 100644 --- a/lib/libz/zopen.c +++ b/lib/libz/zopen.c @@ -3,7 +3,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/lib/libz/zopen.c 84228 2001-09-30 22:39:00Z dillon $"); +__FBSDID("$FreeBSD$"); #include <stdio.h> #include <zlib.h> @@ -29,6 +29,12 @@ xgzclose(void *cookie) return gzclose(cookie); } +static fpos_t +xgzseek(void *cookie, fpos_t offset, int whence) +{ + return gzseek(cookie, (z_off_t)offset, whence); +} + FILE * zopen(const char *fname, const char *mode) { @@ -37,7 +43,7 @@ zopen(const char *fname, const char *mode) return NULL; if(*mode == 'r') - return (funopen(gz, xgzread, NULL, NULL, xgzclose)); + return (funopen(gz, xgzread, NULL, xgzseek, xgzclose)); else - return (funopen(gz, NULL, xgzwrite, NULL, xgzclose)); + return (funopen(gz, NULL, xgzwrite, xgzseek, xgzclose)); } diff --git a/lib/msun/Makefile b/lib/msun/Makefile index 5264aeb..800e0ab 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -45,6 +45,7 @@ LIB= m SHLIBDIR?= /lib SHLIB_MAJOR= 5 WARNS?= 1 +IGNORE_PRAGMA= COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ @@ -73,7 +74,7 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ s_lround.c s_lroundf.c s_lroundl.c s_modff.c \ s_nan.c s_nearbyint.c s_nextafter.c s_nextafterf.c \ s_nexttowardf.c s_remquo.c s_remquof.c \ - s_rint.c s_rintf.c s_round.c s_roundf.c s_roundl.c \ + s_rint.c s_rintf.c s_round.c s_roundf.c \ s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c \ s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c s_trunc.c s_truncf.c \ @@ -98,13 +99,14 @@ COMMON_SRCS+= s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c .if ${LDBL_PREC} != 53 # If long double != double use these; otherwise, we alias the double versions. COMMON_SRCS+= e_acoshl.c e_acosl.c e_asinl.c e_atan2l.c e_atanhl.c \ - e_fmodl.c e_hypotl.c e_remainderl.c e_sqrtl.c \ + e_coshl.c e_fmodl.c e_hypotl.c \ + e_remainderl.c e_sinhl.c e_sqrtl.c \ invtrig.c k_cosl.c k_sinl.c k_tanl.c \ s_asinhl.c s_atanl.c s_cbrtl.c s_ceill.c s_cosl.c s_cprojl.c \ s_csqrtl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \ s_frexpl.c s_logbl.c s_logl.c s_nanl.c s_nextafterl.c \ - s_nexttoward.c s_remquol.c s_rintl.c s_scalbnl.c \ - s_sinl.c s_tanl.c s_truncl.c w_cabsl.c + s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c s_scalbnl.c \ + s_sinl.c s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c .endif # C99 complex functions @@ -162,7 +164,7 @@ MLINKS+=cimag.3 cimagf.3 cimag.3 cimagl.3 \ cimag.3 creal.3 cimag.3 crealf.3 cimag.3 creall.3 MLINKS+=copysign.3 copysignf.3 copysign.3 copysignl.3 MLINKS+=cos.3 cosf.3 cos.3 cosl.3 -MLINKS+=cosh.3 coshf.3 +MLINKS+=cosh.3 coshf.3 cosh.3 coshl.3 MLINKS+=csqrt.3 csqrtf.3 csqrt.3 csqrtl.3 MLINKS+=erf.3 erfc.3 erf.3 erff.3 erf.3 erfcf.3 MLINKS+=exp.3 expm1.3 exp.3 expm1f.3 exp.3 expm1l.3 exp.3 pow.3 exp.3 powf.3 \ @@ -210,11 +212,11 @@ MLINKS+=round.3 roundf.3 round.3 roundl.3 MLINKS+=scalbn.3 scalbln.3 scalbn.3 scalblnf.3 scalbn.3 scalblnl.3 MLINKS+=scalbn.3 scalbnf.3 scalbn.3 scalbnl.3 MLINKS+=sin.3 sinf.3 sin.3 sinl.3 -MLINKS+=sinh.3 sinhf.3 +MLINKS+=sinh.3 sinhf.3 sinh.3 sinhl.3 MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 cbrtl.3 sqrt.3 sqrtf.3 \ sqrt.3 sqrtl.3 MLINKS+=tan.3 tanf.3 tan.3 tanl.3 -MLINKS+=tanh.3 tanhf.3 +MLINKS+=tanh.3 tanhf.3 tanh.3 tanhl.3 MLINKS+=trunc.3 truncf.3 trunc.3 truncl.3 .include <bsd.lib.mk> diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map index 037659d..c36472b 100644 --- a/lib/msun/Symbol.map +++ b/lib/msun/Symbol.map @@ -260,6 +260,7 @@ FBSD_1.3 { ccosf; ccosh; ccoshf; + coshl; ctan; ctanf; ctanh; @@ -270,13 +271,12 @@ FBSD_1.3 { log1pl; log2l; logl; + sinhl; + tanhl; /* Implemented as weak aliases for imprecise versions */ - coshl; erfcl; erfl; lgammal; powl; - sinhl; - tanhl; tgammal; }; diff --git a/lib/msun/arm/Makefile.inc b/lib/msun/arm/Makefile.inc index 7d9e10b..09f08d8 100644 --- a/lib/msun/arm/Makefile.inc +++ b/lib/msun/arm/Makefile.inc @@ -2,3 +2,11 @@ LDBL_PREC = 53 SYM_MAPS += ${.CURDIR}/arm/Symbol.map + +.if ${TARGET_ARCH} == "armv6" +ARCH_SRCS = fenv-softfp.c fenv-vfp.c +.endif + +CFLAGS.fenv-vfp.c= -mfloat-abi=softfp +CFLAGS+= ${CFLAGS.${.IMPSRC:T}} + diff --git a/lib/msun/arm/Symbol.map b/lib/msun/arm/Symbol.map index c43d8cf..081294c 100644 --- a/lib/msun/arm/Symbol.map +++ b/lib/msun/arm/Symbol.map @@ -15,4 +15,7 @@ FBSD_1.3 { fegetenv; feholdexcept; feupdateenv; + feenableexcept; + fedisableexcept; + fegetexcept; }; diff --git a/lib/libelf/elf_getarsym.c b/lib/msun/arm/fenv-mangle.h index df85c05..476f7b2 100644 --- a/lib/libelf/elf_getarsym.c +++ b/lib/msun/arm/fenv-mangle.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Joseph Koshy + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,35 +22,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libelf.h> - -#include "_libelf.h" - -Elf_Arsym * -elf_getarsym(Elf *ar, size_t *ptr) -{ - size_t n; - Elf_Arsym *symtab; - - n = 0; - symtab = NULL; - - if (ar == NULL || ar->e_kind != ELF_K_AR) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) - n = ar->e_u.e_ar.e_symtabsz; - else if (ar->e_u.e_ar.e_rawsymtab) - symtab = _libelf_ar_process_symtab(ar, &n); - else - LIBELF_SET_ERROR(ARCHIVE, 0); - - if (ptr) - *ptr = n; - return (symtab); -} +#ifdef _FENV_MANGLE_H_ +#error Only include fenv-mangle.h once +#endif + +#define _FENV_MANGLE_H_ + +#ifndef FENV_MANGLE +#error FENV_MANGLE is undefined +#endif + +#define feclearexcept FENV_MANGLE(feclearexcept) +#define fegetexceptflag FENV_MANGLE(fegetexceptflag) +#define fesetexceptflag FENV_MANGLE(fesetexceptflag) +#define feraiseexcept FENV_MANGLE(feraiseexcept) +#define fetestexcept FENV_MANGLE(fetestexcept) +#define fegetround FENV_MANGLE(fegetround) +#define fesetround FENV_MANGLE(fesetround) +#define fegetenv FENV_MANGLE(fegetenv) +#define feholdexcept FENV_MANGLE(feholdexcept) +#define fesetenv FENV_MANGLE(fesetenv) +#define feupdateenv FENV_MANGLE(feupdateenv) +#define feenableexcept FENV_MANGLE(feenableexcept) +#define fedisableexcept FENV_MANGLE(fedisableexcept) +#define fegetexcept FENV_MANGLE(fegetexcept) diff --git a/lib/msun/arm/fenv-softfp.c b/lib/msun/arm/fenv-softfp.c new file mode 100644 index 0000000..c32c1c2 --- /dev/null +++ b/lib/msun/arm/fenv-softfp.c @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define FENV_MANGLE(x) __softfp_ ##x +#include "fenv-mangle.h" +#include "fenv.c" + diff --git a/lib/msun/arm/fenv-vfp.c b/lib/msun/arm/fenv-vfp.c new file mode 100644 index 0000000..fd615f3 --- /dev/null +++ b/lib/msun/arm/fenv-vfp.c @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define FENV_MANGLE(x) __vfp_ ##x +#include "fenv-mangle.h" +#define __ARM_PCS_VFP +#include "fenv.c" + diff --git a/lib/msun/arm/fenv.c b/lib/msun/arm/fenv.c index c94f9b4..2dd1933 100644 --- a/lib/msun/arm/fenv.c +++ b/lib/msun/arm/fenv.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,11 +30,34 @@ #define __fenv_static #include "fenv.h" +#if defined(__FreeBSD_ARCH_armv6__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 6) +#define FENV_ARMv6 +#endif + +/* When SOFTFP_ABI is defined we are using the softfp ABI. */ +#if defined(__VFP_FP__) && !defined(__ARM_PCS_VFP) +#define SOFTFP_ABI +#endif + + +#ifndef FENV_MANGLE +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; +#endif + + +/* If this is a non-mangled softfp version special processing is required */ +#if defined(FENV_MANGLE) || !defined(SOFTFP_ABI) || !defined(FENV_ARMv6) + /* * The following macros map between the softfloat emulator's flags and * the hardware's FPSR. The hardware this file was written for doesn't * have rounding control bits, so we stick those in the system ID byte. */ +#ifndef __ARM_PCS_VFP #define __set_env(env, flags, mask, rnd) env = ((flags) \ | (mask)<<_FPUSW_SHIFT \ | (rnd) << 24) @@ -42,17 +66,12 @@ & FE_ALL_EXCEPT) #define __env_round(env) (((env) >> 24) & _ROUND_MASK) #include "fenv-softfloat.h" +#endif #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" #endif -/* - * Hopefully the system ID byte is immutable, so it's valid to use - * this as a default environment. - */ -const fenv_t __fe_dfl_env = 0; - extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); @@ -64,3 +83,233 @@ extern inline int fegetenv(fenv_t *__envp); extern inline int feholdexcept(fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp); extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); + +#else /* !FENV_MANGLE && SOFTFP_ABI */ +/* Set by libc when the VFP unit is enabled */ +extern int _libc_arm_fpu_present; + +int __softfp_feclearexcept(int __excepts); +int __softfp_fegetexceptflag(fexcept_t *__flagp, int __excepts); +int __softfp_fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int __softfp_feraiseexcept(int __excepts); +int __softfp_fetestexcept(int __excepts); +int __softfp_fegetround(void); +int __softfp_fesetround(int __round); +int __softfp_fegetenv(fenv_t *__envp); +int __softfp_feholdexcept(fenv_t *__envp); +int __softfp_fesetenv(const fenv_t *__envp); +int __softfp_feupdateenv(const fenv_t *__envp); +int __softfp_feenableexcept(int __mask); +int __softfp_fedisableexcept(int __mask); +int __softfp_fegetexcept(void); + +int __vfp_feclearexcept(int __excepts); +int __vfp_fegetexceptflag(fexcept_t *__flagp, int __excepts); +int __vfp_fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int __vfp_feraiseexcept(int __excepts); +int __vfp_fetestexcept(int __excepts); +int __vfp_fegetround(void); +int __vfp_fesetround(int __round); +int __vfp_fegetenv(fenv_t *__envp); +int __vfp_feholdexcept(fenv_t *__envp); +int __vfp_fesetenv(const fenv_t *__envp); +int __vfp_feupdateenv(const fenv_t *__envp); +int __vfp_feenableexcept(int __mask); +int __vfp_fedisableexcept(int __mask); +int __vfp_fegetexcept(void); + +static int +__softfp_round_to_vfp(int round) +{ + + switch (round) { + case FE_TONEAREST: + default: + return VFP_FE_TONEAREST; + case FE_TOWARDZERO: + return VFP_FE_TOWARDZERO; + case FE_UPWARD: + return VFP_FE_UPWARD; + case FE_DOWNWARD: + return VFP_FE_DOWNWARD; + } +} + +static int +__softfp_round_from_vfp(int round) +{ + + switch (round) { + case VFP_FE_TONEAREST: + default: + return FE_TONEAREST; + case VFP_FE_TOWARDZERO: + return FE_TOWARDZERO; + case VFP_FE_UPWARD: + return FE_UPWARD; + case VFP_FE_DOWNWARD: + return FE_DOWNWARD; + } +} + +int feclearexcept(int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_feclearexcept(__excepts); + __softfp_feclearexcept(__excepts); + + return (0); +} + +int fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __vfp_flagp; + + __vfp_flagp = 0; + if (_libc_arm_fpu_present) + __vfp_fegetexceptflag(&__vfp_flagp, __excepts); + __softfp_fegetexceptflag(__flagp, __excepts); + + *__flagp |= __vfp_flagp; + + return (0); +} + +int fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetexceptflag(__flagp, __excepts); + __softfp_fesetexceptflag(__flagp, __excepts); + + return (0); +} + +int feraiseexcept(int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_feraiseexcept(__excepts); + __softfp_feraiseexcept(__excepts); + + return (0); +} + +int fetestexcept(int __excepts) +{ + int __got_excepts; + + __got_excepts = 0; + if (_libc_arm_fpu_present) + __got_excepts = __vfp_fetestexcept(__excepts); + __got_excepts |= __softfp_fetestexcept(__excepts); + + return (__got_excepts); +} + +int fegetround(void) +{ + + if (_libc_arm_fpu_present) + return __softfp_round_from_vfp(__vfp_fegetround()); + return __softfp_fegetround(); +} + +int fesetround(int __round) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetround(__softfp_round_to_vfp(__round)); + __softfp_fesetround(__round); + + return (0); +} + +int fegetenv(fenv_t *__envp) +{ + fenv_t __vfp_envp; + + __vfp_envp = 0; + if (_libc_arm_fpu_present) + __vfp_fegetenv(&__vfp_envp); + __softfp_fegetenv(__envp); + *__envp |= __vfp_envp; + + return (0); +} + +int feholdexcept(fenv_t *__envp) +{ + fenv_t __vfp_envp; + + __vfp_envp = 0; + if (_libc_arm_fpu_present) + __vfp_feholdexcept(&__vfp_envp); + __softfp_feholdexcept(__envp); + *__envp |= __vfp_envp; + + return (0); +} + +int fesetenv(const fenv_t *__envp) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetenv(__envp); + __softfp_fesetenv(__envp); + + return (0); +} + +int feupdateenv(const fenv_t *__envp) +{ + + if (_libc_arm_fpu_present) + __vfp_feupdateenv(__envp); + __softfp_feupdateenv(__envp); + + return (0); +} + +int feenableexcept(int __mask) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_feenableexcept(__mask); + __unmasked |= __softfp_feenableexcept(__mask); + + return (__unmasked); +} + +int fedisableexcept(int __mask) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_fedisableexcept(__mask); + __unmasked |= __softfp_fedisableexcept(__mask); + + return (__unmasked); +} + +int fegetexcept(void) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_fegetexcept(); + __unmasked |= __softfp_fegetexcept(); + + return (__unmasked); +} + +#endif + diff --git a/lib/msun/arm/fenv.h b/lib/msun/arm/fenv.h index e245fb0..280532f 100644 --- a/lib/msun/arm/fenv.h +++ b/lib/msun/arm/fenv.h @@ -44,14 +44,32 @@ typedef __uint32_t fexcept_t; #define FE_OVERFLOW 0x0004 #define FE_UNDERFLOW 0x0008 #define FE_INEXACT 0x0010 +#ifdef __ARM_PCS_VFP +#define FE_DENORMAL 0x0080 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL) +#else #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) +#endif /* Rounding modes */ +#define VFP_FE_TONEAREST 0x00000000 +#define VFP_FE_UPWARD 0x00400000 +#define VFP_FE_DOWNWARD 0x00800000 +#define VFP_FE_TOWARDZERO 0x00c00000 + +#ifdef __ARM_PCS_VFP +#define FE_TONEAREST VFP_FE_TONEAREST +#define FE_UPWARD VFP_FE_UPWARD +#define FE_DOWNWARD VFP_FE_DOWNWARD +#define FE_TOWARDZERO VFP_FE_TOWARDZERO +#else #define FE_TONEAREST 0x0000 #define FE_TOWARDZERO 0x0001 #define FE_UPWARD 0x0002 #define FE_DOWNWARD 0x0003 +#endif #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) __BEGIN_DECLS @@ -61,10 +79,12 @@ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) /* We need to be able to map status flag positions to mask flag positions */ -#define _FPUSW_SHIFT 16 +#ifndef __ARM_PCS_VFP +#define _FPUSW_SHIFT 16 #define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) +#endif -#ifndef ARM_HARD_FLOAT +#ifndef __ARM_PCS_VFP int feclearexcept(int __excepts); int fegetexceptflag(fexcept_t *__flagp, int __excepts); @@ -77,20 +97,27 @@ int fegetenv(fenv_t *__envp); int feholdexcept(fenv_t *__envp); int fesetenv(const fenv_t *__envp); int feupdateenv(const fenv_t *__envp); +#if __BSD_VISIBLE +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#endif + +#else /* __ARM_PCS_VFP */ -#else /* ARM_HARD_FLOAT */ +#define vmrs_fpscr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r)) +#define vmsr_fpscr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r)) -#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) -#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) +#define _FPU_MASK_SHIFT 8 __fenv_static inline int feclearexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); __fpsr &= ~__excepts; - __wfs(__fpsr); + vmsr_fpscr(__fpsr); return (0); } @@ -99,7 +126,7 @@ fegetexceptflag(fexcept_t *__flagp, int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); *__flagp = __fpsr & __excepts; return (0); } @@ -109,10 +136,10 @@ fesetexceptflag(const fexcept_t *__flagp, int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); __fpsr &= ~__excepts; __fpsr |= *__flagp & __excepts; - __wfs(__fpsr); + vmsr_fpscr(__fpsr); return (0); } @@ -130,34 +157,36 @@ fetestexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); return (__fpsr & __excepts); } __fenv_static inline int fegetround(void) { + fenv_t __fpsr; - /* - * Apparently, the rounding mode is specified as part of the - * instruction format on ARM, so the dynamic rounding mode is - * indeterminate. Some FPUs may differ. - */ - return (-1); + vmrs_fpscr(__fpsr); + return (__fpsr & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { + fenv_t __fpsr; - return (-1); + vmrs_fpscr(__fpsr); + __fpsr &= ~(_ROUND_MASK); + __fpsr |= __round; + vmsr_fpscr(__fpsr); + return (0); } __fenv_static inline int fegetenv(fenv_t *__envp) { - __rfs(__envp); + vmrs_fpscr(*__envp); return (0); } @@ -166,10 +195,10 @@ feholdexcept(fenv_t *__envp) { fenv_t __env; - __rfs(&__env); + vmrs_fpscr(__env); *__envp = __env; - __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); - __wfs(__env); + __env &= ~(FE_ALL_EXCEPT); + vmsr_fpscr(__env); return (0); } @@ -177,7 +206,7 @@ __fenv_static inline int fesetenv(const fenv_t *__envp) { - __wfs(*__envp); + vmsr_fpscr(*__envp); return (0); } @@ -186,8 +215,8 @@ feupdateenv(const fenv_t *__envp) { fexcept_t __fpsr; - __rfs(&__fpsr); - __wfs(*__envp); + vmrs_fpscr(__fpsr); + vmsr_fpscr(*__envp); feraiseexcept(__fpsr & FE_ALL_EXCEPT); return (0); } @@ -196,40 +225,42 @@ feupdateenv(const fenv_t *__envp) /* We currently provide no external definitions of the functions below. */ -static inline int +__fenv_static inline int feenableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + vmrs_fpscr(__old_fpsr); + __new_fpsr = __old_fpsr | + ((__mask & FE_ALL_EXCEPT) << _FPU_MASK_SHIFT); + vmsr_fpscr(__new_fpsr); + return ((__old_fpsr >> _FPU_MASK_SHIFT) & FE_ALL_EXCEPT); } -static inline int +__fenv_static inline int fedisableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + vmrs_fpscr(__old_fpsr); + __new_fpsr = __old_fpsr & + ~((__mask & FE_ALL_EXCEPT) << _FPU_MASK_SHIFT); + vmsr_fpscr(__new_fpsr); + return ((__old_fpsr >> _FPU_MASK_SHIFT) & FE_ALL_EXCEPT); } -static inline int +__fenv_static inline int fegetexcept(void) { fenv_t __fpsr; - __rfs(&__fpsr); - return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); + vmrs_fpscr(__fpsr); + return (__fpsr & FE_ALL_EXCEPT); } #endif /* __BSD_VISIBLE */ -#endif /* ARM_HARD_FLOAT */ +#endif /* __ARM_PCS_VFP */ __END_DECLS diff --git a/lib/msun/ld128/k_expl.h b/lib/msun/ld128/k_expl.h new file mode 100644 index 0000000..a5668fd --- /dev/null +++ b/lib/msun/ld128/k_expl.h @@ -0,0 +1,328 @@ +/* from: FreeBSD: head/lib/msun/ld128/s_expl.c 251345 2013-06-03 20:09:22Z kargl */ + +/*- + * Copyright (c) 2009-2013 Steven G. Kargl + * 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 unmodified, 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 ``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 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. + * + * Optimized by Bruce D. Evans. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * ld128 version of k_expl.h. See ../ld80/s_expl.c for most comments. + * + * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comments + * about the secondary kernels. + */ + +#define INTERVALS 128 +#define LOG2_INTERVALS 7 +#define BIAS (LDBL_MAX_EXP - 1) + +static const double +/* + * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication). L1 must + * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest + * bits zero so that multiplication of it by n is exact. + */ +INV_L = 1.8466496523378731e+2, /* 0x171547652b82fe.0p-45 */ +L2 = -1.0253670638894731e-29; /* -0x1.9ff0342542fc3p-97 */ +static const long double +/* 0x1.62e42fefa39ef35793c768000000p-8 */ +L1 = 5.41521234812457272982212595914567508e-3L; + +/* + * XXX values in hex in comments have been lost (or were never present) + * from here. + */ +static const long double +/* + * Domain [-0.002708, 0.002708], range ~[-2.4021e-38, 2.4234e-38]: + * |exp(x) - p(x)| < 2**-124.9 + * (0.002708 is ln2/(2*INTERVALS) rounded up a little). + * + * XXX the coeffs aren't very carefully rounded, and I get 3.6 more bits. + */ +A2 = 0.5, +A3 = 1.66666666666666666666666666651085500e-1L, +A4 = 4.16666666666666666666666666425885320e-2L, +A5 = 8.33333333333333333334522877160175842e-3L, +A6 = 1.38888888888888888889971139751596836e-3L; + +static const double +A7 = 1.9841269841269470e-4, /* 0x1.a01a01a019f91p-13 */ +A8 = 2.4801587301585286e-5, /* 0x1.71de3ec75a967p-19 */ +A9 = 2.7557324277411235e-6, /* 0x1.71de3ec75a967p-19 */ +A10 = 2.7557333722375069e-7; /* 0x1.27e505ab56259p-22 */ + +static const struct { + /* + * hi must be rounded to at most 106 bits so that multiplication + * by r1 in expm1l() is exact, but it is rounded to 88 bits due to + * historical accidents. + * + * XXX it is wasteful to use long double for both hi and lo. ld128 + * exp2l() uses only float for lo (in a very differently organized + * table; ld80 exp2l() is different again. It uses 2 doubles in a + * table organized like this one. 1 double and 1 float would + * suffice). There are different packing/locality/alignment/caching + * problems with these methods. + * + * XXX C's bad %a format makes the bits unreadable. They happen + * to all line up for the hi values 1 before the point and 88 + * in 22 nybbles, but for the low values the nybbles are shifted + * randomly. + */ + long double hi; + long double lo; +} tbl[INTERVALS] = { + 0x1p0L, 0x0p0L, + 0x1.0163da9fb33356d84a66aep0L, 0x3.36dcdfa4003ec04c360be2404078p-92L, + 0x1.02c9a3e778060ee6f7cacap0L, 0x4.f7a29bde93d70a2cabc5cb89ba10p-92L, + 0x1.04315e86e7f84bd738f9a2p0L, 0xd.a47e6ed040bb4bfc05af6455e9b8p-96L, + 0x1.059b0d31585743ae7c548ep0L, 0xb.68ca417fe53e3495f7df4baf84a0p-92L, + 0x1.0706b29ddf6ddc6dc403a8p0L, 0x1.d87b27ed07cb8b092ac75e311753p-88L, + 0x1.0874518759bc808c35f25cp0L, 0x1.9427fa2b041b2d6829d8993a0d01p-88L, + 0x1.09e3ecac6f3834521e060cp0L, 0x5.84d6b74ba2e023da730e7fccb758p-92L, + 0x1.0b5586cf9890f6298b92b6p0L, 0x1.1842a98364291408b3ceb0a2a2bbp-88L, + 0x1.0cc922b7247f7407b705b8p0L, 0x9.3dc5e8aac564e6fe2ef1d431fd98p-92L, + 0x1.0e3ec32d3d1a2020742e4ep0L, 0x1.8af6a552ac4b358b1129e9f966a4p-88L, + 0x1.0fb66affed31af232091dcp0L, 0x1.8a1426514e0b627bda694a400a27p-88L, + 0x1.11301d0125b50a4ebbf1aep0L, 0xd.9318ceac5cc47ab166ee57427178p-92L, + 0x1.12abdc06c31cbfb92bad32p0L, 0x4.d68e2f7270bdf7cedf94eb1cb818p-92L, + 0x1.1429aaea92ddfb34101942p0L, 0x1.b2586d01844b389bea7aedd221d4p-88L, + 0x1.15a98c8a58e512480d573cp0L, 0x1.d5613bf92a2b618ee31b376c2689p-88L, + 0x1.172b83c7d517adcdf7c8c4p0L, 0x1.0eb14a792035509ff7d758693f24p-88L, + 0x1.18af9388c8de9bbbf70b9ap0L, 0x3.c2505c97c0102e5f1211941d2840p-92L, + 0x1.1a35beb6fcb753cb698f68p0L, 0x1.2d1c835a6c30724d5cfae31b84e5p-88L, + 0x1.1bbe084045cd39ab1e72b4p0L, 0x4.27e35f9acb57e473915519a1b448p-92L, + 0x1.1d4873168b9aa7805b8028p0L, 0x9.90f07a98b42206e46166cf051d70p-92L, + 0x1.1ed5022fcd91cb8819ff60p0L, 0x1.121d1e504d36c47474c9b7de6067p-88L, + 0x1.2063b88628cd63b8eeb028p0L, 0x1.50929d0fc487d21c2b84004264dep-88L, + 0x1.21f49917ddc962552fd292p0L, 0x9.4bdb4b61ea62477caa1dce823ba0p-92L, + 0x1.2387a6e75623866c1fadb0p0L, 0x1.c15cb593b0328566902df69e4de2p-88L, + 0x1.251ce4fb2a63f3582ab7dep0L, 0x9.e94811a9c8afdcf796934bc652d0p-92L, + 0x1.26b4565e27cdd257a67328p0L, 0x1.d3b249dce4e9186ddd5ff44e6b08p-92L, + 0x1.284dfe1f5638096cf15cf0p0L, 0x3.ca0967fdaa2e52d7c8106f2e262cp-92L, + 0x1.29e9df51fdee12c25d15f4p0L, 0x1.a24aa3bca890ac08d203fed80a07p-88L, + 0x1.2b87fd0dad98ffddea4652p0L, 0x1.8fcab88442fdc3cb6de4519165edp-88L, + 0x1.2d285a6e4030b40091d536p0L, 0xd.075384589c1cd1b3e4018a6b1348p-92L, + 0x1.2ecafa93e2f5611ca0f45cp0L, 0x1.523833af611bdcda253c554cf278p-88L, + 0x1.306fe0a31b7152de8d5a46p0L, 0x3.05c85edecbc27343629f502f1af2p-92L, + 0x1.32170fc4cd8313539cf1c2p0L, 0x1.008f86dde3220ae17a005b6412bep-88L, + 0x1.33c08b26416ff4c9c8610cp0L, 0x1.96696bf95d1593039539d94d662bp-88L, + 0x1.356c55f929ff0c94623476p0L, 0x3.73af38d6d8d6f9506c9bbc93cbc0p-92L, + 0x1.371a7373aa9caa7145502ep0L, 0x1.4547987e3e12516bf9c699be432fp-88L, + 0x1.38cae6d05d86585a9cb0d8p0L, 0x1.bed0c853bd30a02790931eb2e8f0p-88L, + 0x1.3a7db34e59ff6ea1bc9298p0L, 0x1.e0a1d336163fe2f852ceeb134067p-88L, + 0x1.3c32dc313a8e484001f228p0L, 0xb.58f3775e06ab66353001fae9fca0p-92L, + 0x1.3dea64c12342235b41223ep0L, 0x1.3d773fba2cb82b8244267c54443fp-92L, + 0x1.3fa4504ac801ba0bf701aap0L, 0x4.1832fb8c1c8dbdff2c49909e6c60p-92L, + 0x1.4160a21f72e29f84325b8ep0L, 0x1.3db61fb352f0540e6ba05634413ep-88L, + 0x1.431f5d950a896dc7044394p0L, 0x1.0ccec81e24b0caff7581ef4127f7p-92L, + 0x1.44e086061892d03136f408p0L, 0x1.df019fbd4f3b48709b78591d5cb5p-88L, + 0x1.46a41ed1d005772512f458p0L, 0x1.229d97df404ff21f39c1b594d3a8p-88L, + 0x1.486a2b5c13cd013c1a3b68p0L, 0x1.062f03c3dd75ce8757f780e6ec99p-88L, + 0x1.4a32af0d7d3de672d8bcf4p0L, 0x6.f9586461db1d878b1d148bd3ccb8p-92L, + 0x1.4bfdad5362a271d4397afep0L, 0xc.42e20e0363ba2e159c579f82e4b0p-92L, + 0x1.4dcb299fddd0d63b36ef1ap0L, 0x9.e0cc484b25a5566d0bd5f58ad238p-92L, + 0x1.4f9b2769d2ca6ad33d8b68p0L, 0x1.aa073ee55e028497a329a7333dbap-88L, + 0x1.516daa2cf6641c112f52c8p0L, 0x4.d822190e718226177d7608d20038p-92L, + 0x1.5342b569d4f81df0a83c48p0L, 0x1.d86a63f4e672a3e429805b049465p-88L, + 0x1.551a4ca5d920ec52ec6202p0L, 0x4.34ca672645dc6c124d6619a87574p-92L, + 0x1.56f4736b527da66ecb0046p0L, 0x1.64eb3c00f2f5ab3d801d7cc7272dp-88L, + 0x1.58d12d497c7fd252bc2b72p0L, 0x1.43bcf2ec936a970d9cc266f0072fp-88L, + 0x1.5ab07dd48542958c930150p0L, 0x1.91eb345d88d7c81280e069fbdb63p-88L, + 0x1.5c9268a5946b701c4b1b80p0L, 0x1.6986a203d84e6a4a92f179e71889p-88L, + 0x1.5e76f15ad21486e9be4c20p0L, 0x3.99766a06548a05829e853bdb2b52p-92L, + 0x1.605e1b976dc08b076f592ap0L, 0x4.86e3b34ead1b4769df867b9c89ccp-92L, + 0x1.6247eb03a5584b1f0fa06ep0L, 0x1.d2da42bb1ceaf9f732275b8aef30p-88L, + 0x1.6434634ccc31fc76f8714cp0L, 0x4.ed9a4e41000307103a18cf7a6e08p-92L, + 0x1.66238825522249127d9e28p0L, 0x1.b8f314a337f4dc0a3adf1787ff74p-88L, + 0x1.68155d44ca973081c57226p0L, 0x1.b9f32706bfe4e627d809a85dcc66p-88L, + 0x1.6a09e667f3bcc908b2fb12p0L, 0x1.66ea957d3e3adec17512775099dap-88L, + 0x1.6c012750bdabeed76a9980p0L, 0xf.4f33fdeb8b0ecd831106f57b3d00p-96L, + 0x1.6dfb23c651a2ef220e2cbep0L, 0x1.bbaa834b3f11577ceefbe6c1c411p-92L, + 0x1.6ff7df9519483cf87e1b4ep0L, 0x1.3e213bff9b702d5aa477c12523cep-88L, + 0x1.71f75e8ec5f73dd2370f2ep0L, 0xf.0acd6cb434b562d9e8a20adda648p-92L, + 0x1.73f9a48a58173bd5c9a4e6p0L, 0x8.ab1182ae217f3a7681759553e840p-92L, + 0x1.75feb564267c8bf6e9aa32p0L, 0x1.a48b27071805e61a17b954a2dad8p-88L, + 0x1.780694fde5d3f619ae0280p0L, 0x8.58b2bb2bdcf86cd08e35fb04c0f0p-92L, + 0x1.7a11473eb0186d7d51023ep0L, 0x1.6cda1f5ef42b66977960531e821bp-88L, + 0x1.7c1ed0130c1327c4933444p0L, 0x1.937562b2dc933d44fc828efd4c9cp-88L, + 0x1.7e2f336cf4e62105d02ba0p0L, 0x1.5797e170a1427f8fcdf5f3906108p-88L, + 0x1.80427543e1a11b60de6764p0L, 0x9.a354ea706b8e4d8b718a672bf7c8p-92L, + 0x1.82589994cce128acf88afap0L, 0xb.34a010f6ad65cbbac0f532d39be0p-92L, + 0x1.8471a4623c7acce52f6b96p0L, 0x1.c64095370f51f48817914dd78665p-88L, + 0x1.868d99b4492ec80e41d90ap0L, 0xc.251707484d73f136fb5779656b70p-92L, + 0x1.88ac7d98a669966530bcdep0L, 0x1.2d4e9d61283ef385de170ab20f96p-88L, + 0x1.8ace5422aa0db5ba7c55a0p0L, 0x1.92c9bb3e6ed61f2733304a346d8fp-88L, + 0x1.8cf3216b5448bef2aa1cd0p0L, 0x1.61c55d84a9848f8c453b3ca8c946p-88L, + 0x1.8f1ae991577362b982745cp0L, 0x7.2ed804efc9b4ae1458ae946099d4p-92L, + 0x1.9145b0b91ffc588a61b468p0L, 0x1.f6b70e01c2a90229a4c4309ea719p-88L, + 0x1.93737b0cdc5e4f4501c3f2p0L, 0x5.40a22d2fc4af581b63e8326efe9cp-92L, + 0x1.95a44cbc8520ee9b483694p0L, 0x1.a0fc6f7c7d61b2b3a22a0eab2cadp-88L, + 0x1.97d829fde4e4f8b9e920f8p0L, 0x1.1e8bd7edb9d7144b6f6818084cc7p-88L, + 0x1.9a0f170ca07b9ba3109b8cp0L, 0x4.6737beb19e1eada6825d3c557428p-92L, + 0x1.9c49182a3f0901c7c46b06p0L, 0x1.1f2be58ddade50c217186c90b457p-88L, + 0x1.9e86319e323231824ca78ep0L, 0x6.4c6e010f92c082bbadfaf605cfd4p-92L, + 0x1.a0c667b5de564b29ada8b8p0L, 0xc.ab349aa0422a8da7d4512edac548p-92L, + 0x1.a309bec4a2d3358c171f76p0L, 0x1.0daad547fa22c26d168ea762d854p-88L, + 0x1.a5503b23e255c8b424491cp0L, 0xa.f87bc8050a405381703ef7caff50p-92L, + 0x1.a799e1330b3586f2dfb2b0p0L, 0x1.58f1a98796ce8908ae852236ca94p-88L, + 0x1.a9e6b5579fdbf43eb243bcp0L, 0x1.ff4c4c58b571cf465caf07b4b9f5p-88L, + 0x1.ac36bbfd3f379c0db966a2p0L, 0x1.1265fc73e480712d20f8597a8e7bp-88L, + 0x1.ae89f995ad3ad5e8734d16p0L, 0x1.73205a7fbc3ae675ea440b162d6cp-88L, + 0x1.b0e07298db66590842acdep0L, 0x1.c6f6ca0e5dcae2aafffa7a0554cbp-88L, + 0x1.b33a2b84f15faf6bfd0e7ap0L, 0x1.d947c2575781dbb49b1237c87b6ep-88L, + 0x1.b59728de559398e3881110p0L, 0x1.64873c7171fefc410416be0a6525p-88L, + 0x1.b7f76f2fb5e46eaa7b081ap0L, 0xb.53c5354c8903c356e4b625aacc28p-92L, + 0x1.ba5b030a10649840cb3c6ap0L, 0xf.5b47f297203757e1cc6eadc8bad0p-92L, + 0x1.bcc1e904bc1d2247ba0f44p0L, 0x1.b3d08cd0b20287092bd59be4ad98p-88L, + 0x1.bf2c25bd71e088408d7024p0L, 0x1.18e3449fa073b356766dfb568ff4p-88L, + 0x1.c199bdd85529c2220cb12ap0L, 0x9.1ba6679444964a36661240043970p-96L, + 0x1.c40ab5fffd07a6d14df820p0L, 0xf.1828a5366fd387a7bdd54cdf7300p-92L, + 0x1.c67f12e57d14b4a2137fd2p0L, 0xf.2b301dd9e6b151a6d1f9d5d5f520p-96L, + 0x1.c8f6d9406e7b511acbc488p0L, 0x5.c442ddb55820171f319d9e5076a8p-96L, + 0x1.cb720dcef90691503cbd1ep0L, 0x9.49db761d9559ac0cb6dd3ed599e0p-92L, + 0x1.cdf0b555dc3f9c44f8958ep0L, 0x1.ac51be515f8c58bdfb6f5740a3a4p-88L, + 0x1.d072d4a07897b8d0f22f20p0L, 0x1.a158e18fbbfc625f09f4cca40874p-88L, + 0x1.d2f87080d89f18ade12398p0L, 0x9.ea2025b4c56553f5cdee4c924728p-92L, + 0x1.d5818dcfba48725da05aeap0L, 0x1.66e0dca9f589f559c0876ff23830p-88L, + 0x1.d80e316c98397bb84f9d04p0L, 0x8.805f84bec614de269900ddf98d28p-92L, + 0x1.da9e603db3285708c01a5ap0L, 0x1.6d4c97f6246f0ec614ec95c99392p-88L, + 0x1.dd321f301b4604b695de3cp0L, 0x6.30a393215299e30d4fb73503c348p-96L, + 0x1.dfc97337b9b5eb968cac38p0L, 0x1.ed291b7225a944efd5bb5524b927p-88L, + 0x1.e264614f5a128a12761fa0p0L, 0x1.7ada6467e77f73bf65e04c95e29dp-88L, + 0x1.e502ee78b3ff6273d13014p0L, 0x1.3991e8f49659e1693be17ae1d2f9p-88L, + 0x1.e7a51fbc74c834b548b282p0L, 0x1.23786758a84f4956354634a416cep-88L, + 0x1.ea4afa2a490d9858f73a18p0L, 0xf.5db301f86dea20610ceee13eb7b8p-92L, + 0x1.ecf482d8e67f08db0312fap0L, 0x1.949cef462010bb4bc4ce72a900dfp-88L, + 0x1.efa1bee615a27771fd21a8p0L, 0x1.2dac1f6dd5d229ff68e46f27e3dfp-88L, + 0x1.f252b376bba974e8696fc2p0L, 0x1.6390d4c6ad5476b5162f40e1d9a9p-88L, + 0x1.f50765b6e4540674f84b76p0L, 0x2.862baff99000dfc4352ba29b8908p-92L, + 0x1.f7bfdad9cbe138913b4bfep0L, 0x7.2bd95c5ce7280fa4d2344a3f5618p-92L, + 0x1.fa7c1819e90d82e90a7e74p0L, 0xb.263c1dc060c36f7650b4c0f233a8p-92L, + 0x1.fd3c22b8f71f10975ba4b2p0L, 0x1.2bcf3a5e12d269d8ad7c1a4a8875p-88L +}; + +/* + * Kernel for expl(x). x must be finite and not tiny or huge. + * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN). + * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2). + */ +static inline void +__k_expl(long double x, long double *hip, long double *lop, int *kp) +{ + long double q, r, r1, t; + double dr, fn, r2; + int n, n2; + + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + /* XXX assume no extra precision for the additions, as for trig fns. */ + /* XXX this set of comments is now quadruplicated. */ + /* XXX but see ../src/e_exp.c for a fix using double_t. */ + fn = (double)x * INV_L + 0x1.8p52 - 0x1.8p52; +#if defined(HAVE_EFFICIENT_IRINT) + n = irint(fn); +#else + n = (int)fn; +#endif + n2 = (unsigned)n % INTERVALS; + /* Depend on the sign bit being propagated: */ + *kp = n >> LOG2_INTERVALS; + r1 = x - fn * L1; + r2 = fn * -L2; + r = r1 + r2; + + /* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */ + dr = r; + q = r2 + r * r * (A2 + r * (A3 + r * (A4 + r * (A5 + r * (A6 + + dr * (A7 + dr * (A8 + dr * (A9 + dr * A10)))))))); + t = tbl[n2].lo + tbl[n2].hi; + *hip = tbl[n2].hi; + *lop = tbl[n2].lo + t * (q + r1); +} + +/* + * XXX: the rest of the functions are identical for ld80 and ld128. + * However, we should use scalbnl() for ld128, since long double + * multiplication is very slow on the only supported ld128 arch (sparc64). + */ + +static inline void +k_hexpl(long double x, long double *hip, long double *lop) +{ + float twopkm1; + int k; + + __k_expl(x, hip, lop, &k); + SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23)); + *hip *= twopkm1; + *lop *= twopkm1; +} + +static inline long double +hexpl(long double x) +{ + long double hi, lo, twopkm2; + int k; + + twopkm2 = 1; + __k_expl(x, &hi, &lo, &k); + SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2); + return (lo + hi) * 2 * twopkm2; +} + +#ifdef _COMPLEX_H +/* + * See ../src/k_exp.c for details. + */ +static inline long double complex +__ldexp_cexpl(long double complex z, int expt) +{ + long double exp_x, hi, lo; + long double x, y, scale1, scale2; + int half_expt, k; + + x = creall(z); + y = cimagl(z); + __k_expl(x, &hi, &lo, &k); + + exp_x = (lo + hi) * 0x1p16382; + expt += k - 16382; + + scale1 = 1; + half_expt = expt / 2; + SET_LDBL_EXPSIGN(scale1, BIAS + half_expt); + scale2 = 1; + SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt); + + return (cpackl(cos(y) * exp_x * scale1 * scale2, + sinl(y) * exp_x * scale1 * scale2)); +} +#endif /* _COMPLEX_H */ diff --git a/lib/msun/ld128/s_expl.c b/lib/msun/ld128/s_expl.c index 176c932..a6a9676 100644 --- a/lib/msun/ld128/s_expl.c +++ b/lib/msun/ld128/s_expl.c @@ -38,16 +38,15 @@ __FBSDID("$FreeBSD$"); #include "fpmath.h" #include "math.h" #include "math_private.h" +#include "k_expl.h" -#define INTERVALS 128 -#define LOG2_INTERVALS 7 -#define BIAS (LDBL_MAX_EXP - 1) +/* XXX Prevent compilers from erroneously constant folding these: */ +static const volatile long double +huge = 0x1p10000L, +tiny = 0x1p-10000L; static const long double -huge = 0x1p10000L, twom10000 = 0x1p-10000L; -/* XXX Prevent gcc from erroneously constant folding this: */ -static volatile const long double tiny = 0x1p-10000L; static const long double /* log(2**16384 - 0.5) rounded towards zero: */ @@ -56,184 +55,16 @@ o_threshold = 11356.523406294143949491931077970763428L, /* log(2**(-16381-64-1)) rounded towards zero: */ u_threshold = -11433.462743336297878837243843452621503L; -static const double -/* - * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication). L1 must - * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest - * bits zero so that multiplication of it by n is exact. - */ -INV_L = 1.8466496523378731e+2, /* 0x171547652b82fe.0p-45 */ -L2 = -1.0253670638894731e-29; /* -0x1.9ff0342542fc3p-97 */ -static const long double -/* 0x1.62e42fefa39ef35793c768000000p-8 */ -L1 = 5.41521234812457272982212595914567508e-3L; - -static const long double -/* - * Domain [-0.002708, 0.002708], range ~[-2.4021e-38, 2.4234e-38]: - * |exp(x) - p(x)| < 2**-124.9 - * (0.002708 is ln2/(2*INTERVALS) rounded up a little). - */ -A2 = 0.5, -A3 = 1.66666666666666666666666666651085500e-1L, -A4 = 4.16666666666666666666666666425885320e-2L, -A5 = 8.33333333333333333334522877160175842e-3L, -A6 = 1.38888888888888888889971139751596836e-3L; - -static const double -A7 = 1.9841269841269471e-4, -A8 = 2.4801587301585284e-5, -A9 = 2.7557324277411234e-6, -A10 = 2.7557333722375072e-7; - -static const struct { - /* - * hi must be rounded to at most 106 bits so that multiplication - * by r1 in expm1l() is exact, but it is rounded to 88 bits due to - * historical accidents. - */ - long double hi; - long double lo; -} tbl[INTERVALS] = { - 0x1p0L, 0x0p0L, - 0x1.0163da9fb33356d84a66aep0L, 0x3.36dcdfa4003ec04c360be2404078p-92L, - 0x1.02c9a3e778060ee6f7cacap0L, 0x4.f7a29bde93d70a2cabc5cb89ba10p-92L, - 0x1.04315e86e7f84bd738f9a2p0L, 0xd.a47e6ed040bb4bfc05af6455e9b8p-96L, - 0x1.059b0d31585743ae7c548ep0L, 0xb.68ca417fe53e3495f7df4baf84a0p-92L, - 0x1.0706b29ddf6ddc6dc403a8p0L, 0x1.d87b27ed07cb8b092ac75e311753p-88L, - 0x1.0874518759bc808c35f25cp0L, 0x1.9427fa2b041b2d6829d8993a0d01p-88L, - 0x1.09e3ecac6f3834521e060cp0L, 0x5.84d6b74ba2e023da730e7fccb758p-92L, - 0x1.0b5586cf9890f6298b92b6p0L, 0x1.1842a98364291408b3ceb0a2a2bbp-88L, - 0x1.0cc922b7247f7407b705b8p0L, 0x9.3dc5e8aac564e6fe2ef1d431fd98p-92L, - 0x1.0e3ec32d3d1a2020742e4ep0L, 0x1.8af6a552ac4b358b1129e9f966a4p-88L, - 0x1.0fb66affed31af232091dcp0L, 0x1.8a1426514e0b627bda694a400a27p-88L, - 0x1.11301d0125b50a4ebbf1aep0L, 0xd.9318ceac5cc47ab166ee57427178p-92L, - 0x1.12abdc06c31cbfb92bad32p0L, 0x4.d68e2f7270bdf7cedf94eb1cb818p-92L, - 0x1.1429aaea92ddfb34101942p0L, 0x1.b2586d01844b389bea7aedd221d4p-88L, - 0x1.15a98c8a58e512480d573cp0L, 0x1.d5613bf92a2b618ee31b376c2689p-88L, - 0x1.172b83c7d517adcdf7c8c4p0L, 0x1.0eb14a792035509ff7d758693f24p-88L, - 0x1.18af9388c8de9bbbf70b9ap0L, 0x3.c2505c97c0102e5f1211941d2840p-92L, - 0x1.1a35beb6fcb753cb698f68p0L, 0x1.2d1c835a6c30724d5cfae31b84e5p-88L, - 0x1.1bbe084045cd39ab1e72b4p0L, 0x4.27e35f9acb57e473915519a1b448p-92L, - 0x1.1d4873168b9aa7805b8028p0L, 0x9.90f07a98b42206e46166cf051d70p-92L, - 0x1.1ed5022fcd91cb8819ff60p0L, 0x1.121d1e504d36c47474c9b7de6067p-88L, - 0x1.2063b88628cd63b8eeb028p0L, 0x1.50929d0fc487d21c2b84004264dep-88L, - 0x1.21f49917ddc962552fd292p0L, 0x9.4bdb4b61ea62477caa1dce823ba0p-92L, - 0x1.2387a6e75623866c1fadb0p0L, 0x1.c15cb593b0328566902df69e4de2p-88L, - 0x1.251ce4fb2a63f3582ab7dep0L, 0x9.e94811a9c8afdcf796934bc652d0p-92L, - 0x1.26b4565e27cdd257a67328p0L, 0x1.d3b249dce4e9186ddd5ff44e6b08p-92L, - 0x1.284dfe1f5638096cf15cf0p0L, 0x3.ca0967fdaa2e52d7c8106f2e262cp-92L, - 0x1.29e9df51fdee12c25d15f4p0L, 0x1.a24aa3bca890ac08d203fed80a07p-88L, - 0x1.2b87fd0dad98ffddea4652p0L, 0x1.8fcab88442fdc3cb6de4519165edp-88L, - 0x1.2d285a6e4030b40091d536p0L, 0xd.075384589c1cd1b3e4018a6b1348p-92L, - 0x1.2ecafa93e2f5611ca0f45cp0L, 0x1.523833af611bdcda253c554cf278p-88L, - 0x1.306fe0a31b7152de8d5a46p0L, 0x3.05c85edecbc27343629f502f1af2p-92L, - 0x1.32170fc4cd8313539cf1c2p0L, 0x1.008f86dde3220ae17a005b6412bep-88L, - 0x1.33c08b26416ff4c9c8610cp0L, 0x1.96696bf95d1593039539d94d662bp-88L, - 0x1.356c55f929ff0c94623476p0L, 0x3.73af38d6d8d6f9506c9bbc93cbc0p-92L, - 0x1.371a7373aa9caa7145502ep0L, 0x1.4547987e3e12516bf9c699be432fp-88L, - 0x1.38cae6d05d86585a9cb0d8p0L, 0x1.bed0c853bd30a02790931eb2e8f0p-88L, - 0x1.3a7db34e59ff6ea1bc9298p0L, 0x1.e0a1d336163fe2f852ceeb134067p-88L, - 0x1.3c32dc313a8e484001f228p0L, 0xb.58f3775e06ab66353001fae9fca0p-92L, - 0x1.3dea64c12342235b41223ep0L, 0x1.3d773fba2cb82b8244267c54443fp-92L, - 0x1.3fa4504ac801ba0bf701aap0L, 0x4.1832fb8c1c8dbdff2c49909e6c60p-92L, - 0x1.4160a21f72e29f84325b8ep0L, 0x1.3db61fb352f0540e6ba05634413ep-88L, - 0x1.431f5d950a896dc7044394p0L, 0x1.0ccec81e24b0caff7581ef4127f7p-92L, - 0x1.44e086061892d03136f408p0L, 0x1.df019fbd4f3b48709b78591d5cb5p-88L, - 0x1.46a41ed1d005772512f458p0L, 0x1.229d97df404ff21f39c1b594d3a8p-88L, - 0x1.486a2b5c13cd013c1a3b68p0L, 0x1.062f03c3dd75ce8757f780e6ec99p-88L, - 0x1.4a32af0d7d3de672d8bcf4p0L, 0x6.f9586461db1d878b1d148bd3ccb8p-92L, - 0x1.4bfdad5362a271d4397afep0L, 0xc.42e20e0363ba2e159c579f82e4b0p-92L, - 0x1.4dcb299fddd0d63b36ef1ap0L, 0x9.e0cc484b25a5566d0bd5f58ad238p-92L, - 0x1.4f9b2769d2ca6ad33d8b68p0L, 0x1.aa073ee55e028497a329a7333dbap-88L, - 0x1.516daa2cf6641c112f52c8p0L, 0x4.d822190e718226177d7608d20038p-92L, - 0x1.5342b569d4f81df0a83c48p0L, 0x1.d86a63f4e672a3e429805b049465p-88L, - 0x1.551a4ca5d920ec52ec6202p0L, 0x4.34ca672645dc6c124d6619a87574p-92L, - 0x1.56f4736b527da66ecb0046p0L, 0x1.64eb3c00f2f5ab3d801d7cc7272dp-88L, - 0x1.58d12d497c7fd252bc2b72p0L, 0x1.43bcf2ec936a970d9cc266f0072fp-88L, - 0x1.5ab07dd48542958c930150p0L, 0x1.91eb345d88d7c81280e069fbdb63p-88L, - 0x1.5c9268a5946b701c4b1b80p0L, 0x1.6986a203d84e6a4a92f179e71889p-88L, - 0x1.5e76f15ad21486e9be4c20p0L, 0x3.99766a06548a05829e853bdb2b52p-92L, - 0x1.605e1b976dc08b076f592ap0L, 0x4.86e3b34ead1b4769df867b9c89ccp-92L, - 0x1.6247eb03a5584b1f0fa06ep0L, 0x1.d2da42bb1ceaf9f732275b8aef30p-88L, - 0x1.6434634ccc31fc76f8714cp0L, 0x4.ed9a4e41000307103a18cf7a6e08p-92L, - 0x1.66238825522249127d9e28p0L, 0x1.b8f314a337f4dc0a3adf1787ff74p-88L, - 0x1.68155d44ca973081c57226p0L, 0x1.b9f32706bfe4e627d809a85dcc66p-88L, - 0x1.6a09e667f3bcc908b2fb12p0L, 0x1.66ea957d3e3adec17512775099dap-88L, - 0x1.6c012750bdabeed76a9980p0L, 0xf.4f33fdeb8b0ecd831106f57b3d00p-96L, - 0x1.6dfb23c651a2ef220e2cbep0L, 0x1.bbaa834b3f11577ceefbe6c1c411p-92L, - 0x1.6ff7df9519483cf87e1b4ep0L, 0x1.3e213bff9b702d5aa477c12523cep-88L, - 0x1.71f75e8ec5f73dd2370f2ep0L, 0xf.0acd6cb434b562d9e8a20adda648p-92L, - 0x1.73f9a48a58173bd5c9a4e6p0L, 0x8.ab1182ae217f3a7681759553e840p-92L, - 0x1.75feb564267c8bf6e9aa32p0L, 0x1.a48b27071805e61a17b954a2dad8p-88L, - 0x1.780694fde5d3f619ae0280p0L, 0x8.58b2bb2bdcf86cd08e35fb04c0f0p-92L, - 0x1.7a11473eb0186d7d51023ep0L, 0x1.6cda1f5ef42b66977960531e821bp-88L, - 0x1.7c1ed0130c1327c4933444p0L, 0x1.937562b2dc933d44fc828efd4c9cp-88L, - 0x1.7e2f336cf4e62105d02ba0p0L, 0x1.5797e170a1427f8fcdf5f3906108p-88L, - 0x1.80427543e1a11b60de6764p0L, 0x9.a354ea706b8e4d8b718a672bf7c8p-92L, - 0x1.82589994cce128acf88afap0L, 0xb.34a010f6ad65cbbac0f532d39be0p-92L, - 0x1.8471a4623c7acce52f6b96p0L, 0x1.c64095370f51f48817914dd78665p-88L, - 0x1.868d99b4492ec80e41d90ap0L, 0xc.251707484d73f136fb5779656b70p-92L, - 0x1.88ac7d98a669966530bcdep0L, 0x1.2d4e9d61283ef385de170ab20f96p-88L, - 0x1.8ace5422aa0db5ba7c55a0p0L, 0x1.92c9bb3e6ed61f2733304a346d8fp-88L, - 0x1.8cf3216b5448bef2aa1cd0p0L, 0x1.61c55d84a9848f8c453b3ca8c946p-88L, - 0x1.8f1ae991577362b982745cp0L, 0x7.2ed804efc9b4ae1458ae946099d4p-92L, - 0x1.9145b0b91ffc588a61b468p0L, 0x1.f6b70e01c2a90229a4c4309ea719p-88L, - 0x1.93737b0cdc5e4f4501c3f2p0L, 0x5.40a22d2fc4af581b63e8326efe9cp-92L, - 0x1.95a44cbc8520ee9b483694p0L, 0x1.a0fc6f7c7d61b2b3a22a0eab2cadp-88L, - 0x1.97d829fde4e4f8b9e920f8p0L, 0x1.1e8bd7edb9d7144b6f6818084cc7p-88L, - 0x1.9a0f170ca07b9ba3109b8cp0L, 0x4.6737beb19e1eada6825d3c557428p-92L, - 0x1.9c49182a3f0901c7c46b06p0L, 0x1.1f2be58ddade50c217186c90b457p-88L, - 0x1.9e86319e323231824ca78ep0L, 0x6.4c6e010f92c082bbadfaf605cfd4p-92L, - 0x1.a0c667b5de564b29ada8b8p0L, 0xc.ab349aa0422a8da7d4512edac548p-92L, - 0x1.a309bec4a2d3358c171f76p0L, 0x1.0daad547fa22c26d168ea762d854p-88L, - 0x1.a5503b23e255c8b424491cp0L, 0xa.f87bc8050a405381703ef7caff50p-92L, - 0x1.a799e1330b3586f2dfb2b0p0L, 0x1.58f1a98796ce8908ae852236ca94p-88L, - 0x1.a9e6b5579fdbf43eb243bcp0L, 0x1.ff4c4c58b571cf465caf07b4b9f5p-88L, - 0x1.ac36bbfd3f379c0db966a2p0L, 0x1.1265fc73e480712d20f8597a8e7bp-88L, - 0x1.ae89f995ad3ad5e8734d16p0L, 0x1.73205a7fbc3ae675ea440b162d6cp-88L, - 0x1.b0e07298db66590842acdep0L, 0x1.c6f6ca0e5dcae2aafffa7a0554cbp-88L, - 0x1.b33a2b84f15faf6bfd0e7ap0L, 0x1.d947c2575781dbb49b1237c87b6ep-88L, - 0x1.b59728de559398e3881110p0L, 0x1.64873c7171fefc410416be0a6525p-88L, - 0x1.b7f76f2fb5e46eaa7b081ap0L, 0xb.53c5354c8903c356e4b625aacc28p-92L, - 0x1.ba5b030a10649840cb3c6ap0L, 0xf.5b47f297203757e1cc6eadc8bad0p-92L, - 0x1.bcc1e904bc1d2247ba0f44p0L, 0x1.b3d08cd0b20287092bd59be4ad98p-88L, - 0x1.bf2c25bd71e088408d7024p0L, 0x1.18e3449fa073b356766dfb568ff4p-88L, - 0x1.c199bdd85529c2220cb12ap0L, 0x9.1ba6679444964a36661240043970p-96L, - 0x1.c40ab5fffd07a6d14df820p0L, 0xf.1828a5366fd387a7bdd54cdf7300p-92L, - 0x1.c67f12e57d14b4a2137fd2p0L, 0xf.2b301dd9e6b151a6d1f9d5d5f520p-96L, - 0x1.c8f6d9406e7b511acbc488p0L, 0x5.c442ddb55820171f319d9e5076a8p-96L, - 0x1.cb720dcef90691503cbd1ep0L, 0x9.49db761d9559ac0cb6dd3ed599e0p-92L, - 0x1.cdf0b555dc3f9c44f8958ep0L, 0x1.ac51be515f8c58bdfb6f5740a3a4p-88L, - 0x1.d072d4a07897b8d0f22f20p0L, 0x1.a158e18fbbfc625f09f4cca40874p-88L, - 0x1.d2f87080d89f18ade12398p0L, 0x9.ea2025b4c56553f5cdee4c924728p-92L, - 0x1.d5818dcfba48725da05aeap0L, 0x1.66e0dca9f589f559c0876ff23830p-88L, - 0x1.d80e316c98397bb84f9d04p0L, 0x8.805f84bec614de269900ddf98d28p-92L, - 0x1.da9e603db3285708c01a5ap0L, 0x1.6d4c97f6246f0ec614ec95c99392p-88L, - 0x1.dd321f301b4604b695de3cp0L, 0x6.30a393215299e30d4fb73503c348p-96L, - 0x1.dfc97337b9b5eb968cac38p0L, 0x1.ed291b7225a944efd5bb5524b927p-88L, - 0x1.e264614f5a128a12761fa0p0L, 0x1.7ada6467e77f73bf65e04c95e29dp-88L, - 0x1.e502ee78b3ff6273d13014p0L, 0x1.3991e8f49659e1693be17ae1d2f9p-88L, - 0x1.e7a51fbc74c834b548b282p0L, 0x1.23786758a84f4956354634a416cep-88L, - 0x1.ea4afa2a490d9858f73a18p0L, 0xf.5db301f86dea20610ceee13eb7b8p-92L, - 0x1.ecf482d8e67f08db0312fap0L, 0x1.949cef462010bb4bc4ce72a900dfp-88L, - 0x1.efa1bee615a27771fd21a8p0L, 0x1.2dac1f6dd5d229ff68e46f27e3dfp-88L, - 0x1.f252b376bba974e8696fc2p0L, 0x1.6390d4c6ad5476b5162f40e1d9a9p-88L, - 0x1.f50765b6e4540674f84b76p0L, 0x2.862baff99000dfc4352ba29b8908p-92L, - 0x1.f7bfdad9cbe138913b4bfep0L, 0x7.2bd95c5ce7280fa4d2344a3f5618p-92L, - 0x1.fa7c1819e90d82e90a7e74p0L, 0xb.263c1dc060c36f7650b4c0f233a8p-92L, - 0x1.fd3c22b8f71f10975ba4b2p0L, 0x1.2bcf3a5e12d269d8ad7c1a4a8875p-88L -}; - long double expl(long double x) { - union IEEEl2bits u, v; - long double q, r, r1, t, twopk, twopkp10000; - double dr, fn, r2; - int k, n, n2; + union IEEEl2bits u; + long double hi, lo, t, twopk; + int k; uint16_t hx, ix; + DOPRINT_START(&x); + /* Filter out exceptional cases. */ u.e = x; hx = u.xbits.expsign; @@ -241,60 +72,33 @@ expl(long double x) if (ix >= BIAS + 13) { /* |x| >= 8192 or x is NaN */ if (ix == BIAS + LDBL_MAX_EXP) { if (hx & 0x8000) /* x is -Inf or -NaN */ - return (-1 / x); - return (x + x); /* x is +Inf or +NaN */ + RETURNP(-1 / x); + RETURNP(x + x); /* x is +Inf or +NaN */ } if (x > o_threshold) - return (huge * huge); + RETURNP(huge * huge); if (x < u_threshold) - return (tiny * tiny); + RETURNP(tiny * tiny); } else if (ix < BIAS - 114) { /* |x| < 0x1p-114 */ - return (1 + x); /* 1 with inexact iff x != 0 */ + RETURN2P(1, x); /* 1 with inexact iff x != 0 */ } ENTERI(); - /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ - /* XXX assume no extra precision for the additions, as for trig fns. */ - /* XXX this set of comments is now quadruplicated. */ - fn = (double)x * INV_L + 0x1.8p52 - 0x1.8p52; -#if defined(HAVE_EFFICIENT_IRINT) - n = irint(fn); -#else - n = (int)fn; -#endif - n2 = (unsigned)n % INTERVALS; - k = n >> LOG2_INTERVALS; - r1 = x - fn * L1; - r2 = fn * -L2; - r = r1 + r2; - - /* Prepare scale factors. */ - /* XXX sparc64 multiplication is so slow that scalbnl() is faster. */ - v.e = 1; - if (k >= LDBL_MIN_EXP) { - v.xbits.expsign = BIAS + k; - twopk = v.e; - } else { - v.xbits.expsign = BIAS + k + 10000; - twopkp10000 = v.e; - } - - /* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */ - dr = r; - q = r2 + r * r * (A2 + r * (A3 + r * (A4 + r * (A5 + r * (A6 + - dr * (A7 + dr * (A8 + dr * (A9 + dr * A10)))))))); - t = tbl[n2].lo + tbl[n2].hi; - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + twopk = 1; + __k_expl(x, &hi, &lo, &k); + t = SUM2P(hi, lo); /* Scale by 2**k. */ + /* XXX sparc64 multiplication is so slow that scalbnl() is faster. */ if (k >= LDBL_MIN_EXP) { if (k == LDBL_MAX_EXP) RETURNI(t * 2 * 0x1p16383L); + SET_LDBL_EXPSIGN(twopk, BIAS + k); RETURNI(t * twopk); } else { - RETURNI(t * twopkp10000 * twom10000); + SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000); + RETURNI(t * twopk * twom10000); } } @@ -312,6 +116,12 @@ expl(long double x) * Setting T3 to 0 would require the |x| < 0x1p-113 condition to appear * in both subintervals, so set T3 = 2**-5, which places the condition * into the [T1, T3] interval. + * + * XXX we now do this more to (partially) balance the number of terms + * in the C and D polys than to avoid checking the condition in both + * intervals. + * + * XXX these micro-optimizations are excessive. */ static const double T1 = -0.1659, /* ~-30.625/128 * log(2) */ @@ -321,6 +131,12 @@ T3 = 0.03125; /* * Domain [-0.1659, 0.03125], range ~[2.9134e-44, 1.8404e-37]: * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-122.03 + * + * XXX none of the long double C or D coeffs except C10 is correctly printed. + * If you re-print their values in %.35Le format, the result is always + * different. For example, the last 2 digits in C3 should be 59, not 67. + * 67 is apparently from rounding an extra-precision value to 36 decimal + * places. */ static const long double C3 = 1.66666666666666666666666666666666667e-1L, @@ -335,6 +151,13 @@ C11 = 2.50521083854417203619031960151253944e-8L, C12 = 2.08767569878679576457272282566520649e-9L, C13 = 1.60590438367252471783548748824255707e-10L; +/* + * XXX this has 1 more coeff than needed. + * XXX can start the double coeffs but not the double mults at C10. + * With my coeffs (C10-C17 double; s = best_s): + * Domain [-0.1659, 0.03125], range ~[-1.1976e-37, 1.1976e-37]: + * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 + */ static const double C14 = 1.1470745580491932e-11, /* 0x1.93974a81dae30p-37 */ C15 = 7.6471620181090468e-13, /* 0x1.ae7f3820adab1p-41 */ @@ -359,6 +182,13 @@ D11 = 2.50521083855084570046480450935267433e-8L, D12 = 2.08767569819738524488686318024854942e-9L, D13 = 1.60590442297008495301927448122499313e-10L; +/* + * XXX this has 1 more coeff than needed. + * XXX can start the double coeffs but not the double mults at D11. + * With my coeffs (D11-D16 double): + * Domain [0.03125, 0.1659], range ~[-1.1980e-37, 1.1980e-37]: + * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 + */ static const double D14 = 1.1470726176204336e-11, /* 0x1.93971dc395d9ep-37 */ D15 = 7.6478532249581686e-13, /* 0x1.ae892e3D16fcep-41 */ @@ -375,6 +205,8 @@ expm1l(long double x) int k, n, n2; uint16_t hx, ix; + DOPRINT_START(&x); + /* Filter out exceptional cases. */ u.e = x; hx = u.xbits.expsign; @@ -382,11 +214,11 @@ expm1l(long double x) if (ix >= BIAS + 7) { /* |x| >= 128 or x is NaN */ if (ix == BIAS + LDBL_MAX_EXP) { if (hx & 0x8000) /* x is -Inf or -NaN */ - return (-1 / x - 1); - return (x + x); /* x is +Inf or +NaN */ + RETURNP(-1 / x - 1); + RETURNP(x + x); /* x is +Inf or +NaN */ } if (x > o_threshold) - return (huge * huge); + RETURNP(huge * huge); /* * expm1l() never underflows, but it must avoid * unrepresentable large negative exponents. We used a @@ -395,7 +227,7 @@ expm1l(long double x) * in the same way as large ones here. */ if (hx & 0x8000) /* x <= -128 */ - return (tiny - 1); /* good for x < -114ln2 - eps */ + RETURN2P(tiny, -1); /* good for x < -114ln2 - eps */ } ENTERI(); @@ -407,7 +239,7 @@ expm1l(long double x) if (x < T3) { if (ix < BIAS - 113) { /* |x| < 0x1p-113 */ /* x (rounded) with inexact if x != 0: */ - RETURNI(x == 0 ? x : + RETURNPI(x == 0 ? x : (0x1p200 * x + fabsl(x)) * 0x1p-200); } q = x * x2 * C3 + x2 * x2 * (C4 + x * (C5 + x * (C6 + @@ -428,9 +260,9 @@ expm1l(long double x) hx2_hi = x_hi * x_hi / 2; hx2_lo = x_lo * (x + x_hi) / 2; if (ix >= BIAS - 7) - RETURNI(hx2_lo + x_lo + q + (hx2_hi + x_hi)); + RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q); else - RETURNI(hx2_lo + q + hx2_hi + x); + RETURN2PI(x, hx2_lo + q + hx2_hi); } /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ @@ -463,21 +295,21 @@ expm1l(long double x) t = tbl[n2].lo + tbl[n2].hi; if (k == 0) { - t = tbl[n2].lo * (r1 + 1) + t * q + tbl[n2].hi * r1 + - (tbl[n2].hi - 1); + t = SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q + + tbl[n2].hi * r1); RETURNI(t); } if (k == -1) { - t = tbl[n2].lo * (r1 + 1) + t * q + tbl[n2].hi * r1 + - (tbl[n2].hi - 2); + t = SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q + + tbl[n2].hi * r1); RETURNI(t / 2); } if (k < -7) { - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); RETURNI(t * twopk - 1); } if (k > 2 * LDBL_MANT_DIG - 1) { - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); if (k == LDBL_MAX_EXP) RETURNI(t * 2 * 0x1p16383L - 1); RETURNI(t * twopk - 1); @@ -487,8 +319,8 @@ expm1l(long double x) twomk = v.e; if (k > LDBL_MANT_DIG - 1) - t = tbl[n2].lo - twomk + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1)); else - t = tbl[n2].lo + t * (q + r1) + (tbl[n2].hi - twomk); + t = SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1)); RETURNI(t * twopk); } diff --git a/lib/msun/ld80/k_expl.h b/lib/msun/ld80/k_expl.h new file mode 100644 index 0000000..ebfb9a8 --- /dev/null +++ b/lib/msun/ld80/k_expl.h @@ -0,0 +1,305 @@ +/* from: FreeBSD: head/lib/msun/ld80/s_expl.c 251343 2013-06-03 19:51:32Z kargl */ + +/*- + * Copyright (c) 2009-2013 Steven G. Kargl + * 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 unmodified, 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 ``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 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. + * + * Optimized by Bruce D. Evans. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * See s_expl.c for more comments about __k_expl(). + * + * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comments + * about the secondary kernels. + */ + +#define INTERVALS 128 +#define LOG2_INTERVALS 7 +#define BIAS (LDBL_MAX_EXP - 1) + +static const double +/* + * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication). L1 must + * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest + * bits zero so that multiplication of it by n is exact. + */ +INV_L = 1.8466496523378731e+2, /* 0x171547652b82fe.0p-45 */ +L1 = 5.4152123484527692e-3, /* 0x162e42ff000000.0p-60 */ +L2 = -3.2819649005320973e-13, /* -0x1718432a1b0e26.0p-94 */ +/* + * Domain [-0.002708, 0.002708], range ~[-5.7136e-24, 5.7110e-24]: + * |exp(x) - p(x)| < 2**-77.2 + * (0.002708 is ln2/(2*INTERVALS) rounded up a little). + */ +A2 = 0.5, +A3 = 1.6666666666666119e-1, /* 0x15555555555490.0p-55 */ +A4 = 4.1666666666665887e-2, /* 0x155555555554e5.0p-57 */ +A5 = 8.3333354987869413e-3, /* 0x1111115b789919.0p-59 */ +A6 = 1.3888891738560272e-3; /* 0x16c16c651633ae.0p-62 */ + +/* + * 2^(i/INTERVALS) for i in [0,INTERVALS] is represented by two values where + * the first 53 bits of the significand are stored in hi and the next 53 + * bits are in lo. Tang's paper states that the trailing 6 bits of hi must + * be zero for his algorithm in both single and double precision, because + * the table is re-used in the implementation of expm1() where a floating + * point addition involving hi must be exact. Here hi is double, so + * converting it to long double gives 11 trailing zero bits. + */ +static const struct { + double hi; + double lo; +} tbl[INTERVALS] = { + 0x1p+0, 0x0p+0, + /* + * XXX hi is rounded down, and the formatting is not quite normal. + * But I rather like both. The 0x1.*p format is good for 4N+1 + * mantissa bits. Rounding down makes the lo terms positive, + * so that the columnar formatting can be simpler. + */ + 0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54, + 0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53, + 0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53, + 0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55, + 0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53, + 0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57, + 0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54, + 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54, + 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54, + 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59, + 0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53, + 0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53, + 0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53, + 0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53, + 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55, + 0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53, + 0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53, + 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55, + 0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53, + 0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54, + 0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53, + 0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55, + 0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55, + 0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54, + 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55, + 0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55, + 0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53, + 0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55, + 0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53, + 0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54, + 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56, + 0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55, + 0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55, + 0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54, + 0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53, + 0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53, + 0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53, + 0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53, + 0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53, + 0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55, + 0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53, + 0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53, + 0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53, + 0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59, + 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54, + 0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56, + 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54, + 0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56, + 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54, + 0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53, + 0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53, + 0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53, + 0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53, + 0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54, + 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55, + 0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54, + 0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60, + 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54, + 0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53, + 0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53, + 0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53, + 0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53, + 0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57, + 0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53, + 0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53, + 0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53, + 0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53, + 0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53, + 0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53, + 0x1.75feb564267c8p+0, 0x1.7edd354674916p-53, + 0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54, + 0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53, + 0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54, + 0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56, + 0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53, + 0x1.82589994cce12p+0, 0x1.159f115f56694p-53, + 0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53, + 0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53, + 0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54, + 0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54, + 0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53, + 0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55, + 0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53, + 0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53, + 0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53, + 0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53, + 0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53, + 0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56, + 0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56, + 0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53, + 0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54, + 0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53, + 0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54, + 0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54, + 0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53, + 0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54, + 0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53, + 0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53, + 0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53, + 0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53, + 0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53, + 0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55, + 0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53, + 0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55, + 0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54, + 0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54, + 0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56, + 0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56, + 0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53, + 0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53, + 0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53, + 0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55, + 0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53, + 0x1.da9e603db3285p+0, 0x1.c2300696db532p-54, + 0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54, + 0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53, + 0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53, + 0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55, + 0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54, + 0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53, + 0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53, + 0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54, + 0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54, + 0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54, + 0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53, + 0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55, + 0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57 +}; + +/* + * Kernel for expl(x). x must be finite and not tiny or huge. + * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN). + * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2). + */ +static inline void +__k_expl(long double x, long double *hip, long double *lop, int *kp) +{ + long double fn, q, r, r1, r2, t, z; + int n, n2; + + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + fn = x * INV_L + 0x1.8p63 - 0x1.8p63; + r = x - fn * L1 - fn * L2; /* r = r1 + r2 done independently. */ +#if defined(HAVE_EFFICIENT_IRINTL) + n = irintl(fn); +#elif defined(HAVE_EFFICIENT_IRINT) + n = irint(fn); +#else + n = (int)fn; +#endif + n2 = (unsigned)n % INTERVALS; + /* Depend on the sign bit being propagated: */ + *kp = n >> LOG2_INTERVALS; + r1 = x - fn * L1; + r2 = fn * -L2; + + /* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */ + z = r * r; +#if 0 + q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6; +#else + q = r2 + z * A2 + z * r * (A3 + r * A4 + z * (A5 + r * A6)); +#endif + t = (long double)tbl[n2].lo + tbl[n2].hi; + *hip = tbl[n2].hi; + *lop = tbl[n2].lo + t * (q + r1); +} + +static inline void +k_hexpl(long double x, long double *hip, long double *lop) +{ + float twopkm1; + int k; + + __k_expl(x, hip, lop, &k); + SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23)); + *hip *= twopkm1; + *lop *= twopkm1; +} + +static inline long double +hexpl(long double x) +{ + long double hi, lo, twopkm2; + int k; + + twopkm2 = 1; + __k_expl(x, &hi, &lo, &k); + SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2); + return (lo + hi) * 2 * twopkm2; +} + +#ifdef _COMPLEX_H +/* + * See ../src/k_exp.c for details. + */ +static inline long double complex +__ldexp_cexpl(long double complex z, int expt) +{ + long double exp_x, hi, lo; + long double x, y, scale1, scale2; + int half_expt, k; + + x = creall(z); + y = cimagl(z); + __k_expl(x, &hi, &lo, &k); + + exp_x = (lo + hi) * 0x1p16382; + expt += k - 16382; + + scale1 = 1; + half_expt = expt / 2; + SET_LDBL_EXPSIGN(scale1, BIAS + half_expt); + scale2 = 1; + SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt); + + return (cpackl(cos(y) * exp_x * scale1 * scale2, + sinl(y) * exp_x * scale1 * scale2)); +} +#endif /* _COMPLEX_H */ diff --git a/lib/msun/ld80/s_expl.c b/lib/msun/ld80/s_expl.c index ec748d3..3147d35 100644 --- a/lib/msun/ld80/s_expl.c +++ b/lib/msun/ld80/s_expl.c @@ -48,16 +48,15 @@ __FBSDID("$FreeBSD$"); #include "fpmath.h" #include "math.h" #include "math_private.h" +#include "k_expl.h" -#define INTERVALS 128 -#define LOG2_INTERVALS 7 -#define BIAS (LDBL_MAX_EXP - 1) +/* XXX Prevent compilers from erroneously constant folding these: */ +static const volatile long double +huge = 0x1p10000L, +tiny = 0x1p-10000L; static const long double -huge = 0x1p10000L, twom10000 = 0x1p-10000L; -/* XXX Prevent gcc from erroneously constant folding this: */ -static volatile const long double tiny = 0x1p-10000L; static const union IEEEl2bits /* log(2**16384 - 0.5) rounded towards zero: */ @@ -68,178 +67,16 @@ o_thresholdu = LD80C(0xb17217f7d1cf79ab, 13, 11356.5234062941439488L), u_thresholdu = LD80C(0xb21dfe7f09e2baa9, 13, -11399.4985314888605581L); #define u_threshold (u_thresholdu.e) -static const double -/* - * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication). L1 must - * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest - * bits zero so that multiplication of it by n is exact. - */ -INV_L = 1.8466496523378731e+2, /* 0x171547652b82fe.0p-45 */ -L1 = 5.4152123484527692e-3, /* 0x162e42ff000000.0p-60 */ -L2 = -3.2819649005320973e-13, /* -0x1718432a1b0e26.0p-94 */ -/* - * Domain [-0.002708, 0.002708], range ~[-5.7136e-24, 5.7110e-24]: - * |exp(x) - p(x)| < 2**-77.2 - * (0.002708 is ln2/(2*INTERVALS) rounded up a little). - */ -A2 = 0.5, -A3 = 1.6666666666666119e-1, /* 0x15555555555490.0p-55 */ -A4 = 4.1666666666665887e-2, /* 0x155555555554e5.0p-57 */ -A5 = 8.3333354987869413e-3, /* 0x1111115b789919.0p-59 */ -A6 = 1.3888891738560272e-3; /* 0x16c16c651633ae.0p-62 */ - -/* - * 2^(i/INTERVALS) for i in [0,INTERVALS] is represented by two values where - * the first 53 bits of the significand are stored in hi and the next 53 - * bits are in lo. Tang's paper states that the trailing 6 bits of hi must - * be zero for his algorithm in both single and double precision, because - * the table is re-used in the implementation of expm1() where a floating - * point addition involving hi must be exact. Here hi is double, so - * converting it to long double gives 11 trailing zero bits. - */ -static const struct { - double hi; - double lo; -} tbl[INTERVALS] = { - 0x1p+0, 0x0p+0, - 0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54, - 0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53, - 0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53, - 0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55, - 0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53, - 0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57, - 0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54, - 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54, - 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54, - 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59, - 0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53, - 0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53, - 0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53, - 0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53, - 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55, - 0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53, - 0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53, - 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55, - 0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53, - 0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54, - 0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53, - 0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55, - 0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55, - 0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54, - 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55, - 0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55, - 0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53, - 0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55, - 0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53, - 0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54, - 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56, - 0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55, - 0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55, - 0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54, - 0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53, - 0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53, - 0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53, - 0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53, - 0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53, - 0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55, - 0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53, - 0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53, - 0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53, - 0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59, - 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54, - 0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56, - 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54, - 0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56, - 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54, - 0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53, - 0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53, - 0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53, - 0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53, - 0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54, - 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55, - 0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54, - 0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60, - 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54, - 0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53, - 0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53, - 0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53, - 0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53, - 0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57, - 0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53, - 0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53, - 0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53, - 0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53, - 0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53, - 0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53, - 0x1.75feb564267c8p+0, 0x1.7edd354674916p-53, - 0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54, - 0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53, - 0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54, - 0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56, - 0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53, - 0x1.82589994cce12p+0, 0x1.159f115f56694p-53, - 0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53, - 0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53, - 0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54, - 0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54, - 0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53, - 0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55, - 0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53, - 0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53, - 0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53, - 0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53, - 0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53, - 0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56, - 0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56, - 0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53, - 0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54, - 0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53, - 0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54, - 0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54, - 0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53, - 0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54, - 0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53, - 0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53, - 0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53, - 0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53, - 0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53, - 0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55, - 0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53, - 0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55, - 0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54, - 0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54, - 0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56, - 0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56, - 0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53, - 0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53, - 0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53, - 0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55, - 0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53, - 0x1.da9e603db3285p+0, 0x1.c2300696db532p-54, - 0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54, - 0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53, - 0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53, - 0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55, - 0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54, - 0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53, - 0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53, - 0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54, - 0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54, - 0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54, - 0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53, - 0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55, - 0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57 -}; - long double expl(long double x) { - union IEEEl2bits u, v; - long double fn, q, r, r1, r2, t, twopk, twopkp10000; - long double z; - int k, n, n2; + union IEEEl2bits u; + long double hi, lo, t, twopk; + int k; uint16_t hx, ix; + DOPRINT_START(&x); + /* Filter out exceptional cases. */ u.e = x; hx = u.xbits.expsign; @@ -247,59 +84,32 @@ expl(long double x) if (ix >= BIAS + 13) { /* |x| >= 8192 or x is NaN */ if (ix == BIAS + LDBL_MAX_EXP) { if (hx & 0x8000) /* x is -Inf, -NaN or unsupported */ - return (-1 / x); - return (x + x); /* x is +Inf, +NaN or unsupported */ + RETURNP(-1 / x); + RETURNP(x + x); /* x is +Inf, +NaN or unsupported */ } if (x > o_threshold) - return (huge * huge); + RETURNP(huge * huge); if (x < u_threshold) - return (tiny * tiny); - } else if (ix < BIAS - 65) { /* |x| < 0x1p-65 (includes pseudos) */ - return (1 + x); /* 1 with inexact iff x != 0 */ + RETURNP(tiny * tiny); + } else if (ix < BIAS - 75) { /* |x| < 0x1p-75 (includes pseudos) */ + RETURN2P(1, x); /* 1 with inexact iff x != 0 */ } ENTERI(); - /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ - fn = x * INV_L + 0x1.8p63 - 0x1.8p63; - r = x - fn * L1 - fn * L2; /* r = r1 + r2 done independently. */ -#if defined(HAVE_EFFICIENT_IRINTL) - n = irintl(fn); -#elif defined(HAVE_EFFICIENT_IRINT) - n = irint(fn); -#else - n = (int)fn; -#endif - n2 = (unsigned)n % INTERVALS; - /* Depend on the sign bit being propagated: */ - k = n >> LOG2_INTERVALS; - r1 = x - fn * L1; - r2 = fn * -L2; - - /* Prepare scale factors. */ - v.e = 1; - if (k >= LDBL_MIN_EXP) { - v.xbits.expsign = BIAS + k; - twopk = v.e; - } else { - v.xbits.expsign = BIAS + k + 10000; - twopkp10000 = v.e; - } - - /* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */ - z = r * r; - q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6; - t = (long double)tbl[n2].lo + tbl[n2].hi; - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + twopk = 1; + __k_expl(x, &hi, &lo, &k); + t = SUM2P(hi, lo); /* Scale by 2**k. */ if (k >= LDBL_MIN_EXP) { if (k == LDBL_MAX_EXP) RETURNI(t * 2 * 0x1p16383L); + SET_LDBL_EXPSIGN(twopk, BIAS + k); RETURNI(t * twopk); } else { - RETURNI(t * twopkp10000 * twom10000); + SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000); + RETURNI(t * twopk * twom10000); } } @@ -326,8 +136,11 @@ T1 = -0.1659, /* ~-30.625/128 * log(2) */ T2 = 0.1659; /* ~30.625/128 * log(2) */ /* - * Domain [-0.1659, 0.1659], range ~[-1.2027e-22, 3.4417e-22]: - * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-71.2 + * Domain [-0.1659, 0.1659], range ~[-2.6155e-22, 2.5507e-23]: + * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-71.6 + * + * XXX the coeffs aren't very carefully rounded, and I get 2.8 more bits, + * but unlike for ld128 we can't drop any terms. */ static const union IEEEl2bits B3 = LD80C(0xaaaaaaaaaaaaaaab, -3, 1.66666666666666666671e-1L), @@ -353,6 +166,8 @@ expm1l(long double x) int k, n, n2; uint16_t hx, ix; + DOPRINT_START(&x); + /* Filter out exceptional cases. */ u.e = x; hx = u.xbits.expsign; @@ -360,11 +175,11 @@ expm1l(long double x) if (ix >= BIAS + 6) { /* |x| >= 64 or x is NaN */ if (ix == BIAS + LDBL_MAX_EXP) { if (hx & 0x8000) /* x is -Inf, -NaN or unsupported */ - return (-1 / x - 1); - return (x + x); /* x is +Inf, +NaN or unsupported */ + RETURNP(-1 / x - 1); + RETURNP(x + x); /* x is +Inf, +NaN or unsupported */ } if (x > o_threshold) - return (huge * huge); + RETURNP(huge * huge); /* * expm1l() never underflows, but it must avoid * unrepresentable large negative exponents. We used a @@ -373,15 +188,15 @@ expm1l(long double x) * in the same way as large ones here. */ if (hx & 0x8000) /* x <= -64 */ - return (tiny - 1); /* good for x < -65ln2 - eps */ + RETURN2P(tiny, -1); /* good for x < -65ln2 - eps */ } ENTERI(); if (T1 < x && x < T2) { - if (ix < BIAS - 64) { /* |x| < 0x1p-64 (includes pseudos) */ + if (ix < BIAS - 74) { /* |x| < 0x1p-74 (includes pseudos) */ /* x (rounded) with inexact if x != 0: */ - RETURNI(x == 0 ? x : + RETURNPI(x == 0 ? x : (0x1p100 * x + fabsl(x)) * 0x1p-100); } @@ -402,9 +217,9 @@ expm1l(long double x) hx2_hi = x_hi * x_hi / 2; hx2_lo = x_lo * (x + x_hi) / 2; if (ix >= BIAS - 7) - RETURNI(hx2_lo + x_lo + q + (hx2_hi + x_hi)); + RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q); else - RETURNI(hx2_lo + q + hx2_hi + x); + RETURN2PI(x, hx2_lo + q + hx2_hi); } /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ @@ -438,21 +253,21 @@ expm1l(long double x) t = (long double)tbl[n2].lo + tbl[n2].hi; if (k == 0) { - t = tbl[n2].lo * (r1 + 1) + t * q + tbl[n2].hi * r1 + - (tbl[n2].hi - 1); + t = SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q + + tbl[n2].hi * r1); RETURNI(t); } if (k == -1) { - t = tbl[n2].lo * (r1 + 1) + t * q + tbl[n2].hi * r1 + - (tbl[n2].hi - 2); + t = SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q + + tbl[n2].hi * r1); RETURNI(t / 2); } if (k < -7) { - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); RETURNI(t * twopk - 1); } if (k > 2 * LDBL_MANT_DIG - 1) { - t = tbl[n2].lo + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); if (k == LDBL_MAX_EXP) RETURNI(t * 2 * 0x1p16383L - 1); RETURNI(t * twopk - 1); @@ -462,8 +277,8 @@ expm1l(long double x) twomk = v.e; if (k > LDBL_MANT_DIG - 1) - t = tbl[n2].lo - twomk + t * (q + r1) + tbl[n2].hi; + t = SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1)); else - t = tbl[n2].lo + t * (q + r1) + (tbl[n2].hi - twomk); + t = SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1)); RETURNI(t * twopk); } diff --git a/lib/msun/man/cosh.3 b/lib/msun/man/cosh.3 index 96abc5a..334b564 100644 --- a/lib/msun/man/cosh.3 +++ b/lib/msun/man/cosh.3 @@ -28,12 +28,13 @@ .\" from: @(#)cosh.3 5.1 (Berkeley) 5/2/91 .\" $FreeBSD$ .\" -.Dd January 14, 2005 +.Dd August 17, 2013 .Dt COSH 3 .Os .Sh NAME .Nm cosh , -.Nm coshf +.Nm coshf , +.Nm coshl .Nd hyperbolic cosine functions .Sh LIBRARY .Lb libm @@ -43,11 +44,14 @@ .Fn cosh "double x" .Ft float .Fn coshf "float x" +.Ft long double +.Fn coshl "long double x" .Sh DESCRIPTION The -.Fn cosh -and the -.Fn coshf +.Fn cosh , +.Fn coshf , +and +.Fn coshl functions compute the hyperbolic cosine of .Fa x . .Sh SEE ALSO diff --git a/lib/msun/man/sinh.3 b/lib/msun/man/sinh.3 index 02944cc..b34cc38 100644 --- a/lib/msun/man/sinh.3 +++ b/lib/msun/man/sinh.3 @@ -27,12 +27,14 @@ .\" .\" from: @(#)sinh.3 6.6 (Berkeley) 4/19/91 .\" $FreeBSD$ -.Dd January 14, 2005 +.\" +.Dd August 17, 2013 .Dt SINH 3 .Os .Sh NAME .Nm sinh , -.Nm sinhf +.Nm sinhf , +.Nm sinhl .Nd hyperbolic sine function .Sh LIBRARY .Lb libm @@ -42,11 +44,14 @@ .Fn sinh "double x" .Ft float .Fn sinhf "float x" +.Ft long double +.Fn sinhl "long double x" .Sh DESCRIPTION The -.Fn sinh -and the -.Fn sinhf +.Fn sinh , +.Fn sinhf , +and +.Fn sinhl functions compute the hyperbolic sine of .Fa x . .Sh SEE ALSO diff --git a/lib/msun/man/tanh.3 b/lib/msun/man/tanh.3 index 6fb185c..ea2468f 100644 --- a/lib/msun/man/tanh.3 +++ b/lib/msun/man/tanh.3 @@ -28,12 +28,13 @@ .\" from: @(#)tanh.3 5.1 (Berkeley) 5/2/91 .\" $FreeBSD$ .\" -.Dd May 2, 1991 +.Dd August 17, 2013 .Dt TANH 3 .Os .Sh NAME .Nm tanh , -.Nm tanhf +.Nm tanhf , +.Nm tanhl .Nd hyperbolic tangent functions .Sh LIBRARY .Lb libm @@ -43,20 +44,24 @@ .Fn tanh "double x" .Ft float .Fn tanhf "float x" +.Ft long double +.Fn tanhl "long double x" .Sh DESCRIPTION The -.Fn tanh -and the -.Fn tanhf +.Fn tanh , +.Fn tanhf , +and +.Fn tanhl functions compute the hyperbolic tangent of .Fa x . For a discussion of error due to roundoff, see .Xr math 3 . .Sh RETURN VALUES The -.Fn tanh +.Fn tanh , +.Fn tanhf , and the -.Fn tanhf +.Fn tanhl functions return the hyperbolic tangent value. .Sh SEE ALSO .Xr acos 3 , diff --git a/lib/msun/src/e_cosh.c b/lib/msun/src/e_cosh.c index a363695..246b5fb 100644 --- a/lib/msun/src/e_cosh.c +++ b/lib/msun/src/e_cosh.c @@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$"); * only cosh(0)=1 is exact for finite x. */ +#include <float.h> + #include "math.h" #include "math_private.h" @@ -77,3 +79,7 @@ __ieee754_cosh(double x) /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(cosh, coshl); +#endif diff --git a/lib/msun/src/e_coshl.c b/lib/msun/src/e_coshl.c new file mode 100644 index 0000000..0a21277 --- /dev/null +++ b/lib/msun/src/e_coshl.c @@ -0,0 +1,130 @@ +/* from: FreeBSD: head/lib/msun/src/e_coshl.c XXX */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * See e_cosh.c for complete comments. + * + * Converted to long double by Bruce D. Evans. + */ + +#include <float.h> +#ifdef __i386__ +#include <ieeefp.h> +#endif + +#include "fpmath.h" +#include "math.h" +#include "math_private.h" +#include "k_expl.h" + +#if LDBL_MAX_EXP != 0x4000 +/* We also require the usual expsign encoding. */ +#error "Unsupported long double format" +#endif + +#define BIAS (LDBL_MAX_EXP - 1) + +static const volatile long double huge = 0x1p10000L, tiny = 0x1p-10000L; +#if LDBL_MANT_DIG == 64 +/* + * Domain [-1, 1], range ~[-1.8211e-21, 1.8211e-21]: + * |cosh(x) - c(x)| < 2**-68.8 + */ +static const union IEEEl2bits +C4u = LD80C(0xaaaaaaaaaaaaac78, -5, 4.16666666666666682297e-2L); +#define C4 C4u.e +static const double +C2 = 0.5, +C6 = 1.3888888888888616e-3, /* 0x16c16c16c16b99.0p-62 */ +C8 = 2.4801587301767953e-5, /* 0x1a01a01a027061.0p-68 */ +C10 = 2.7557319163300398e-7, /* 0x127e4fb6c9b55f.0p-74 */ +C12 = 2.0876768371393075e-9, /* 0x11eed99406a3f4.0p-81 */ +C14 = 1.1469537039374480e-11, /* 0x1938c67cd18c48.0p-89 */ +C16 = 4.8473490896852041e-14; /* 0x1b49c429701e45.0p-97 */ +#elif LDBL_MANT_DIG == 113 +/* + * Domain [-1, 1], range ~[-2.3194e-37, 2.3194e-37]: + * |cosh(x) - c(x)| < 2**-121.69 + */ +static const long double +C4 = 4.16666666666666666666666666666666225e-2L, /* 0x1555555555555555555555555554e.0p-117L */ +C6 = 1.38888888888888888888888888889434831e-3L, /* 0x16c16c16c16c16c16c16c16c1dd7a.0p-122L */ +C8 = 2.48015873015873015873015871870962089e-5L, /* 0x1a01a01a01a01a01a01a017af2756.0p-128L */ +C10 = 2.75573192239858906525574318600800201e-7L, /* 0x127e4fb7789f5c72ef01c8a040640.0p-134L */ +C12 = 2.08767569878680989791444691755468269e-9L, /* 0x11eed8eff8d897b543d0679607399.0p-141L */ +C14= 1.14707455977297247387801189650495351e-11L, /* 0x193974a8c07c9d24ae169a7fa9b54.0p-149L */ +C16 = 4.77947733238737883626416876486279985e-14L; /* 0x1ae7f3e733b814d4e1b90f5727fe4.0p-157L */ +static const double +C2 = 0.5, +C18 = 1.5619206968597871e-16, /* 0x16827863b9900b.0p-105 */ +C20 = 4.1103176218528049e-19, /* 0x1e542ba3d3c269.0p-114 */ +C22 = 8.8967926401641701e-22, /* 0x10ce399542a014.0p-122 */ +C24 = 1.6116681626523904e-24, /* 0x1f2c981d1f0cb7.0p-132 */ +C26 = 2.5022374732804632e-27; /* 0x18c7ecf8b2c4a0.0p-141 */ +#else +#error "Unsupported long double format" +#endif /* LDBL_MANT_DIG == 64 */ + +/* log(2**16385 - 0.5) rounded up: */ +static const float +o_threshold = 1.13572168e4; /* 0xb174de.0p-10 */ + +long double +coshl(long double x) +{ + long double hi,lo,x2,x4; + double dx2; + uint16_t ix; + + GET_LDBL_EXPSIGN(ix,x); + ix &= 0x7fff; + + /* x is INF or NaN */ + if(ix>=0x7fff) return x*x; + + ENTERI(); + + /* |x| < 1, return 1 or c(x) */ + if(ix<0x3fff) { + if (ix<BIAS-(LDBL_MANT_DIG+1)/2) /* |x| < TINY */ + RETURNI(1+tiny); /* cosh(tiny) = 1(+) with inexact */ + x2 = x*x; +#if LDBL_MANT_DIG == 64 + x4 = x2*x2; + RETURNI(((C16*x2 + C14)*x4 + (C12*x2 + C10))*(x4*x4*x2) + + ((C8*x2 + C6)*x2 + C4)*x4 + C2*x2 + 1); +#elif LDBL_MANT_DIG == 113 + dx2 = x2; + RETURNI((((((((((((C26*dx2 + C24)*dx2 + C22)*dx2 + + C20)*x2 + C18)*x2 + + C16)*x2 + C14)*x2 + C12)*x2 + C10)*x2 + C8)*x2 + C6)*x2 + + C4)*(x2*x2) + C2*x2 + 1); +#endif + } + + /* |x| in [1, 64), return accurate exp(|x|)/2+1/exp(|x|)/2 */ + if (ix < 0x4005) { + k_hexpl(fabsl(x), &hi, &lo); + RETURNI(lo + 0.25/(hi + lo) + hi); + } + + /* |x| in [64, o_threshold], return correctly-overflowing exp(|x|)/2 */ + if (fabsl(x) <= o_threshold) + RETURNI(hexpl(fabsl(x))); + + /* |x| > o_threshold, cosh(x) overflow */ + RETURNI(huge*huge); +} diff --git a/lib/msun/src/e_sinh.c b/lib/msun/src/e_sinh.c index 17442d0..6c01f4a 100644 --- a/lib/msun/src/e_sinh.c +++ b/lib/msun/src/e_sinh.c @@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$"); * only sinh(0)=0 is exact for finite x. */ +#include <float.h> + #include "math.h" #include "math_private.h" @@ -71,3 +73,7 @@ __ieee754_sinh(double x) /* |x| > overflowthresold, sinh(x) overflow */ return x*shuge; } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(sinh, sinhl); +#endif diff --git a/lib/msun/src/e_sinhl.c b/lib/msun/src/e_sinhl.c new file mode 100644 index 0000000..ce7e333 --- /dev/null +++ b/lib/msun/src/e_sinhl.c @@ -0,0 +1,131 @@ +/* from: FreeBSD: head/lib/msun/src/e_sinhl.c XXX */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * See e_sinh.c for complete comments. + * + * Converted to long double by Bruce D. Evans. + */ + +#include <float.h> +#ifdef __i386__ +#include <ieeefp.h> +#endif + +#include "fpmath.h" +#include "math.h" +#include "math_private.h" +#include "k_expl.h" + +#if LDBL_MAX_EXP != 0x4000 +/* We also require the usual expsign encoding. */ +#error "Unsupported long double format" +#endif + +#define BIAS (LDBL_MAX_EXP - 1) + +static const long double shuge = 0x1p16383L; +#if LDBL_MANT_DIG == 64 +/* + * Domain [-1, 1], range ~[-6.6749e-22, 6.6749e-22]: + * |sinh(x)/x - s(x)| < 2**-70.3 + */ +static const union IEEEl2bits +S3u = LD80C(0xaaaaaaaaaaaaaaaa, -3, 1.66666666666666666658e-1L); +#define S3 S3u.e +static const double +S5 = 8.3333333333333332e-3, /* 0x11111111111111.0p-59 */ +S7 = 1.9841269841270074e-4, /* 0x1a01a01a01a070.0p-65 */ +S9 = 2.7557319223873889e-6, /* 0x171de3a5565fe6.0p-71 */ +S11 = 2.5052108406704084e-8, /* 0x1ae6456857530f.0p-78 */ +S13 = 1.6059042748655297e-10, /* 0x161245fa910697.0p-85 */ +S15 = 7.6470006914396920e-13, /* 0x1ae7ce4eff2792.0p-93 */ +S17 = 2.8346142308424267e-15; /* 0x19882ce789ffc6.0p-101 */ +#elif LDBL_MANT_DIG == 113 +/* + * Domain [-1, 1], range ~[-2.9673e-36, 2.9673e-36]: + * |sinh(x)/x - s(x)| < 2**-118.0 + */ +static const long double +S3 = 1.66666666666666666666666666666666033e-1L, /* 0x1555555555555555555555555553b.0p-115L */ +S5 = 8.33333333333333333333333333337643193e-3L, /* 0x111111111111111111111111180f5.0p-119L */ +S7 = 1.98412698412698412698412697391263199e-4L, /* 0x1a01a01a01a01a01a01a0176aad11.0p-125L */ +S9 = 2.75573192239858906525574406205464218e-6L, /* 0x171de3a556c7338faac243aaa9592.0p-131L */ +S11 = 2.50521083854417187749675637460977997e-8L, /* 0x1ae64567f544e38fe59b3380d7413.0p-138L */ +S13 = 1.60590438368216146368737762431552702e-10L, /* 0x16124613a86d098059c7620850fc2.0p-145L */ +S15 = 7.64716373181980539786802470969096440e-13L, /* 0x1ae7f3e733b814193af09ce723043.0p-153L */ +S17 = 2.81145725434775409870584280722701574e-15L; /* 0x1952c77030c36898c3fd0b6dfc562.0p-161L */ +static const double +S19= 8.2206352435411005e-18, /* 0x12f49b4662b86d.0p-109 */ +S21= 1.9572943931418891e-20, /* 0x171b8f2fab9628.0p-118 */ +S23 = 3.8679983530666939e-23, /* 0x17617002b73afc.0p-127 */ +S25 = 6.5067867911512749e-26; /* 0x1423352626048a.0p-136 */ +#else +#error "Unsupported long double format" +#endif /* LDBL_MANT_DIG == 64 */ + +/* log(2**16385 - 0.5) rounded up: */ +static const float +o_threshold = 1.13572168e4; /* 0xb174de.0p-10 */ + +long double +sinhl(long double x) +{ + long double hi,lo,x2,x4; + double dx2,s; + int16_t ix,jx; + + GET_LDBL_EXPSIGN(jx,x); + ix = jx&0x7fff; + + /* x is INF or NaN */ + if(ix>=0x7fff) return x+x; + + ENTERI(); + + s = 1; + if (jx<0) s = -1; + + /* |x| < 64, return x, s(x), or accurate s*(exp(|x|)/2-1/exp(|x|)/2) */ + if (ix<0x4005) { /* |x|<64 */ + if (ix<BIAS-(LDBL_MANT_DIG+1)/2) /* |x|<TINY */ + if(shuge+x>1) RETURNI(x); /* sinh(tiny) = tiny with inexact */ + if (ix<0x3fff) { /* |x|<1 */ + x2 = x*x; +#if LDBL_MANT_DIG == 64 + x4 = x2*x2; + RETURNI(((S17*x2 + S15)*x4 + (S13*x2 + S11))*(x2*x*x4*x4) + + ((S9*x2 + S7)*x2 + S5)*(x2*x*x2) + S3*(x2*x) + x); +#elif LDBL_MANT_DIG == 113 + dx2 = x2; + RETURNI(((((((((((S25*dx2 + S23)*dx2 + + S21)*x2 + S19)*x2 + + S17)*x2 + S15)*x2 + S13)*x2 + S11)*x2 + S9)*x2 + S7)*x2 + + S5)* (x2*x*x2) + + S3*(x2*x) + x); +#endif + } + k_hexpl(fabsl(x), &hi, &lo); + RETURNI(s*(lo - 0.25/(hi + lo) + hi)); + } + + /* |x| in [64, o_threshold], return correctly-overflowing s*exp(|x|)/2 */ + if (fabsl(x) <= o_threshold) + RETURNI(s*hexpl(fabsl(x))); + + /* |x| > o_threshold, sinh(x) overflow */ + return x*shuge; +} diff --git a/lib/msun/src/fenv-softfloat.h b/lib/msun/src/fenv-softfloat.h index 02d2a2c..48c1277 100644 --- a/lib/msun/src/fenv-softfloat.h +++ b/lib/msun/src/fenv-softfloat.h @@ -156,7 +156,7 @@ feupdateenv(const fenv_t *__envp) /* We currently provide no external definitions of the functions below. */ -static inline int +__fenv_static inline int feenableexcept(int __mask) { int __omask = __softfloat_float_exception_mask; @@ -165,7 +165,7 @@ feenableexcept(int __mask) return (__omask); } -static inline int +__fenv_static inline int fedisableexcept(int __mask) { int __omask = __softfloat_float_exception_mask; @@ -174,7 +174,7 @@ fedisableexcept(int __mask) return (__omask); } -static inline int +__fenv_static inline int fegetexcept(void) { diff --git a/lib/msun/src/imprecise.c b/lib/msun/src/imprecise.c index a7503bf..5bd3d64 100644 --- a/lib/msun/src/imprecise.c +++ b/lib/msun/src/imprecise.c @@ -60,10 +60,7 @@ DECLARE_WEAK(powl); long double imprecise_ ## f ## l(long double v) { return f(v); }\ DECLARE_WEAK(f ## l) -DECLARE_IMPRECISE(cosh); DECLARE_IMPRECISE(erfc); DECLARE_IMPRECISE(erf); DECLARE_IMPRECISE(lgamma); -DECLARE_IMPRECISE(sinh); -DECLARE_IMPRECISE(tanh); DECLARE_IMPRECISE(tgamma); diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h index 1bd931c..fc4becc 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -451,6 +451,7 @@ long double atanl(long double); long double cbrtl(long double); long double ceill(long double); long double copysignl(long double, long double) __pure2; +long double coshl(long double); long double cosl(long double); long double exp2l(long double); long double expl(long double); @@ -488,8 +489,10 @@ long double rintl(long double); long double roundl(long double); long double scalblnl(long double, long); long double scalbnl(long double, int); +long double sinhl(long double); long double sinl(long double); long double sqrtl(long double); +long double tanhl(long double); long double tanl(long double); long double truncl(long double); @@ -510,13 +513,10 @@ __END_DECLS */ __BEGIN_DECLS -long double coshl(long double); long double erfcl(long double); long double erfl(long double); long double lgammal(long double); long double powl(long double, long double); -long double sinhl(long double); -long double tanhl(long double); long double tgammal(long double); __END_DECLS diff --git a/lib/msun/src/s_round.c b/lib/msun/src/s_round.c index 65de31b..fab3019 100644 --- a/lib/msun/src/s_round.c +++ b/lib/msun/src/s_round.c @@ -27,25 +27,34 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <math.h> +#include <float.h> + +#include "math.h" +#include "math_private.h" double round(double x) { double t; + uint32_t hx; - if (!isfinite(x)) - return (x); + GET_HIGH_WORD(hx, x); + if ((hx & 0x7fffffff) == 0x7ff00000) + return (x + x); - if (x >= 0.0) { + if (!(hx & 0x80000000)) { t = floor(x); if (t - x <= -0.5) - t += 1.0; + t += 1; return (t); } else { t = floor(-x); if (t + x <= -0.5) - t += 1.0; + t += 1; return (-t); } } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(round, roundl); +#endif diff --git a/lib/msun/src/s_roundf.c b/lib/msun/src/s_roundf.c index 952e8e7..e7e2eb9 100644 --- a/lib/msun/src/s_roundf.c +++ b/lib/msun/src/s_roundf.c @@ -27,25 +27,28 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <math.h> +#include "math.h" +#include "math_private.h" float roundf(float x) { float t; + uint32_t hx; - if (!isfinite(x)) - return (x); + GET_FLOAT_WORD(hx, x); + if ((hx & 0x7fffffff) == 0x7f800000) + return (x + x); - if (x >= 0.0) { + if (!(hx & 0x80000000)) { t = floorf(x); - if (t - x <= -0.5) - t += 1.0; + if (t - x <= -0.5F) + t += 1; return (t); } else { t = floorf(-x); - if (t + x <= -0.5) - t += 1.0; + if (t + x <= -0.5F) + t += 1; return (-t); } } diff --git a/lib/msun/src/s_roundl.c b/lib/msun/src/s_roundl.c index a70b617..2d15e13 100644 --- a/lib/msun/src/s_roundl.c +++ b/lib/msun/src/s_roundl.c @@ -27,25 +27,36 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <math.h> +#include <float.h> +#ifdef __i386__ +#include <ieeefp.h> +#endif + +#include "fpmath.h" +#include "math.h" +#include "math_private.h" long double roundl(long double x) { long double t; + uint16_t hx; + + GET_LDBL_EXPSIGN(hx, x); + if ((hx & 0x7fff) == 0x7fff) + return (x + x); - if (!isfinite(x)) - return (x); + ENTERI(); - if (x >= 0.0) { + if (!(hx & 0x8000)) { t = floorl(x); - if (t - x <= -0.5) - t += 1.0; - return (t); + if (t - x <= -0.5L) + t += 1; + RETURNI(t); } else { t = floorl(-x); - if (t + x <= -0.5) - t += 1.0; - return (-t); + if (t + x <= -0.5L) + t += 1; + RETURNI(-t); } } diff --git a/lib/msun/src/s_tanh.c b/lib/msun/src/s_tanh.c index 96e3565..f7b71c5 100644 --- a/lib/msun/src/s_tanh.c +++ b/lib/msun/src/s_tanh.c @@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$"); * only tanh(0)=0 is exact for finite argument. */ +#include <float.h> + #include "math.h" #include "math_private.h" @@ -75,3 +77,7 @@ tanh(double x) } return (jx>=0)? z: -z; } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(tanh, tanhl); +#endif diff --git a/lib/msun/src/s_tanhl.c b/lib/msun/src/s_tanhl.c new file mode 100644 index 0000000..886158b --- /dev/null +++ b/lib/msun/src/s_tanhl.c @@ -0,0 +1,172 @@ +/* from: FreeBSD: head/lib/msun/src/s_tanhl.c XXX */ + +/* @(#)s_tanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * See s_tanh.c for complete comments. + * + * Converted to long double by Bruce D. Evans. + */ + +#include <float.h> +#ifdef __i386__ +#include <ieeefp.h> +#endif + +#include "math.h" +#include "math_private.h" +#include "fpmath.h" +#include "k_expl.h" + +#if LDBL_MAX_EXP != 0x4000 +/* We also require the usual expsign encoding. */ +#error "Unsupported long double format" +#endif + +#define BIAS (LDBL_MAX_EXP - 1) + +static const volatile double tiny = 1.0e-300; +static const double one = 1.0; +#if LDBL_MANT_DIG == 64 +/* + * Domain [-0.25, 0.25], range ~[-1.6304e-22, 1.6304e-22]: + * |tanh(x)/x - t(x)| < 2**-72.3 + */ +static const union IEEEl2bits +T3u = LD80C(0xaaaaaaaaaaaaaa9f, -2, -3.33333333333333333017e-1L); +#define T3 T3u.e +static const double +T5 = 1.3333333333333314e-1, /* 0x1111111111110a.0p-55 */ +T7 = -5.3968253968210485e-2, /* -0x1ba1ba1ba1a1a1.0p-57 */ +T9 = 2.1869488531393817e-2, /* 0x1664f488172022.0p-58 */ +T11 = -8.8632352345964591e-3, /* -0x1226e34bc138d5.0p-59 */ +T13 = 3.5921169709993771e-3, /* 0x1d6d371d3e400f.0p-61 */ +T15 = -1.4555786415756001e-3, /* -0x17d923aa63814d.0p-62 */ +T17 = 5.8645267876296793e-4, /* 0x13378589b85aa7.0p-63 */ +T19 = -2.1121033571392224e-4; /* -0x1baf0af80c4090.0p-65 */ +#elif LDBL_MANT_DIG == 113 +/* + * Domain [-0.25, 0.25], range ~[-2.4211e-37, 2.4211e-37]: + * |tanh(x)/x - t(x)| < 2**121.6 + */ +static const long double +T3 = -3.33333333333333333333333333333332980e-1L, /* -0x1555555555555555555555555554e.0p-114L */ +T5 = 1.33333333333333333333333333332707260e-1L, /* 0x1111111111111111111111110ab7b.0p-115L */ +T7 = -5.39682539682539682539682535723482314e-2L, /* -0x1ba1ba1ba1ba1ba1ba1ba17b5fc98.0p-117L */ +T9 = 2.18694885361552028218693591149061717e-2L, /* 0x1664f4882c10f9f32d6b1a12a25e5.0p-118L */ +T11 = -8.86323552990219656883762347736381851e-3L, /* -0x1226e355e6c23c8f5a5a0f386cb4d.0p-119L */ +T13 = 3.59212803657248101358314398220822722e-3L, /* 0x1d6d3d0e157ddfb403ad3637442c6.0p-121L */ +T15 = -1.45583438705131796512568010348874662e-3L; /* -0x17da36452b75e150c44cc34253b34.0p-122L */ +static const double +T17 = 5.9002744094556621e-4, /* 0x1355824803668e.0p-63 */ +T19 = -2.3912911424260516e-4, /* -0x1f57d7734c8dde.0p-65 */ +T21 = 9.6915379535512898e-5, /* 0x1967e18ad6a6ca.0p-66 */ +T23 = -3.9278322983156353e-5, /* -0x1497d8e6b75729.0p-67 */ +T25 = 1.5918887220143869e-5, /* 0x10b1319998cafa.0p-68 */ +T27 = -6.4514295231630956e-6, /* -0x1b0f2b71b218eb.0p-70 */ +T29 = 2.6120754043964365e-6, /* 0x15e963a3cf3a39.0p-71 */ +T31 = -1.0407567231003314e-6, /* -0x1176041e656869.0p-72 */ +T33 = 3.4744117554063574e-7; /* 0x1750fe732cab9c.0p-74 */ +#endif /* LDBL_MANT_DIG == 64 */ + +static inline long double +divl(long double a, long double b, long double c, long double d, + long double e, long double f) +{ + long double inv, r; + float fr, fw; + + _2sumF(a, c); + b = b + c; + _2sumF(d, f); + e = e + f; + + inv = 1 / (d + e); + + r = (a + b) * inv; + fr = r; + r = fr; + + fw = d + e; + e = d - fw + e; + d = fw; + + r = r + (a - d * r + b - e * r) * inv; + + return r; +} + +long double +tanhl(long double x) +{ + long double hi,lo,s,x2,x4,z; + double dx2; + int16_t jx,ix; + + GET_LDBL_EXPSIGN(jx,x); + ix = jx&0x7fff; + + /* x is INF or NaN */ + if(ix>=0x7fff) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + ENTERI(); + + /* |x| < 40 */ + if (ix < 0x4004 || fabsl(x) < 40) { /* |x|<40 */ + if (__predict_false(ix<BIAS-(LDBL_MANT_DIG+1)/2)) { /* |x|<TINY */ + /* tanh(+-0) = +0; tanh(tiny) = tiny(-+) with inexact: */ + return (x == 0 ? x : (0x1p200 * x - x) * 0x1p-200); + } + if (ix<0x3ffd) { /* |x|<0.25 */ + x2 = x*x; +#if LDBL_MANT_DIG == 64 + x4 = x2*x2; + RETURNI(((T19*x2 + T17)*x4 + (T15*x2 + T13))*(x2*x*x2*x4*x4) + + ((T11*x2 + T9)*x4 + (T7*x2 + T5))*(x2*x*x2) + + T3*(x2*x) + x); +#elif LDBL_MANT_DIG == 113 + dx2 = x2; +#if 0 + RETURNI(((((((((((((((T33*dx2 + T31)*dx2 + T29)*dx2 + T27)*dx2 + + T25)*x2 + T23)*x2 + T21)*x2 + T19)*x2 + T17)*x2 + + T15)*x2 + T13)*x2 + T11)*x2 + T9)*x2 + T7)*x2 + T5)* + (x2*x*x2) + + T3*(x2*x) + x); +#else + long double q = ((((((((((((((T33*dx2 + T31)*dx2 + T29)*dx2 + T27)*dx2 + + T25)*x2 + T23)*x2 + T21)*x2 + T19)*x2 + T17)*x2 + + T15)*x2 + T13)*x2 + T11)*x2 + T9)*x2 + T7)*x2 + T5)* + (x2*x*x2); + RETURNI(q + T3*(x2*x) + x); +#endif +#endif + } + k_hexpl(2*fabsl(x), &hi, &lo); + if (ix<0x4001 && fabsl(x) < 1.5) /* |x|<1.5 */ + z = divl(hi, lo, -0.5, hi, lo, 0.5); + else + z = one - one/(lo+0.5+hi); + /* |x| >= 40, return +-1 */ + } else { + z = one - tiny; /* raise inexact flag */ + } + s = 1; + if (jx<0) s = -1; + RETURNI(s*z); +} diff --git a/lib/ncurses/Makefile b/lib/ncurses/Makefile index 05cd7a2..b363f64 100644 --- a/lib/ncurses/Makefile +++ b/lib/ncurses/Makefile @@ -1,6 +1,11 @@ # $FreeBSD$ -SUBDIR= ncurses form menu panel \ - ncursesw formw menuw panelw +.include <bsd.own.mk> + +SUBDIR= ncurses form menu panel + +.if ${MK_NCURSESW} != "no" +SUBDIR+= ncursesw formw menuw panelw +.endif .include <bsd.subdir.mk> diff --git a/lib/ncurses/form/Makefile b/lib/ncurses/form/Makefile index aa12242..dd903b0 100644 --- a/lib/ncurses/form/Makefile +++ b/lib/ncurses/form/Makefile @@ -84,6 +84,7 @@ MAN= \ form_post.3 \ form_requestname.3 \ form_userptr.3 \ + form_variables.3 \ form_win.3 CLEANFILES+= ${MAN:M*.3} @@ -157,7 +158,7 @@ MLINKS= form_cursor.3 pos_form_cursor.3 \ form_win.3 set_form_sub.3 \ form_win.3 set_form_win.3 .else -NO_MAN= +MAN= .endif .include <bsd.lib.mk> diff --git a/lib/ncurses/menu/Makefile b/lib/ncurses/menu/Makefile index 46bc023..3aac081 100644 --- a/lib/ncurses/menu/Makefile +++ b/lib/ncurses/menu/Makefile @@ -130,7 +130,7 @@ MLINKS= menu_attributes.3 menu_back.3 \ mitem_value.3 set_item_value.3 \ mitem_visible.3 item_visible.3 .else -NO_MAN= +MAN= .endif .include <bsd.lib.mk> diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile index eb5e762..9cf3cc8 100644 --- a/lib/ncurses/ncurses/Makefile +++ b/lib/ncurses/ncurses/Makefile @@ -3,7 +3,8 @@ SHLIBDIR?= /lib .if !defined(ENABLE_WIDEC) -NO_MAN= +# Override any MAN= setting below.. +MK_MAN=no .endif .include <bsd.own.mk> @@ -161,7 +162,6 @@ SRCS+= \ lib_wattron.c \ lib_winch.c \ lib_window.c \ - memmove.c \ nc_panel.c \ resizeterm.c \ safe_sprintf.c \ @@ -211,9 +211,9 @@ SRCS+= \ lib_tputs.c \ lib_ttyflags.c \ name_match.c \ + obsolete.c \ parse_entry.c \ read_entry.c \ - setbuf.c \ strings.c \ trim_sgr0.c \ write_entry.c @@ -391,14 +391,16 @@ build-tools: make_hash make_keys make_keys: make_keys.c names.c ncurses_def.h ${HEADERS} ${CC} -o $@ ${CFLAGS} ${NCURSES_DIR}/ncurses/tinfo/make_keys.c -make_hash: comp_hash.c hashsize.h ncurses_def.h ${HEADERS} +make_hash: make_hash.c hashsize.h ncurses_def.h ${HEADERS} ${CC} -o $@ ${CFLAGS} -DMAIN_PROGRAM \ - ${NCURSES_DIR}/ncurses/tinfo/comp_hash.c + ${NCURSES_DIR}/ncurses/tinfo/make_hash.c # ./configure generated MKterm.h.awk: MKterm.h.awk.in sed <${NCURSES_DIR}/include/MKterm.h.awk.in >$@ \ -e "/@BROKEN_LINKER@/s%%${BROKEN_LINKER}%" \ + -e "s%@NCURSES_USE_DATABASE@%0%g" \ + -e "s%@NCURSES_USE_TERMCAP@%1%g" \ -e "/@NCURSES_MAJOR@/s%%${NCURSES_MAJOR}%" \ -e "/@NCURSES_MINOR@/s%%${NCURSES_MINOR}%" \ -e "/@NCURSES_CONST@/s%%${NCURSES_CONST}%" \ @@ -417,6 +419,10 @@ termcap.h: termcap.h.in -e "/@NCURSES_CONST@/s%%${NCURSES_CONST}%" \ -e "/@NCURSES_OSPEED@/s%%${NCURSES_OSPEED}%" +ncurses_dll.h: ncurses_dll.h.in + sed <${NCURSES_DIR}/include/ncurses_dll.h.in >$@ \ + -e "s%@NCURSES_WRAP_PREFIX@%_nc_%g" + curses.head: curses.h.in sed <${NCURSES_DIR}/include/curses.h.in >$@ \ -e "/@BROKEN_LINKER@/s%%${BROKEN_LINKER}%" \ @@ -441,6 +447,10 @@ curses.head: curses.h.in -e "/@NCURSES_WINT_T@/s%%${NCURSES_WINT_T}%" \ -e "/@NEED_WCHAR_H@/s%%${NEED_WCHAR_H}%" \ -e "/@USE_CXX_BOOL@/s%%${USE_CXX_BOOL}%" \ + -e "s%@NCURSES_SP_FUNCS@%0%g" \ + -e "s%@NCURSES_INTEROP_FUNCS@%0%g" \ + -e "s%@NCURSES_CCHARW_MAX@%5%g" \ + -e "s%@NCURSES_TPARM_ARG@%long%g" \ -e "s%@cf_cv_1UL@%${ONEUL}%g" \ -e "s%@cf_cv_builtin_bool@%${BUILTIN_BOOL}%g" \ -e "s%@cf_cv_enable_lp64@%${ENABLE_LP64}%g" \ @@ -455,6 +465,7 @@ curses.head: curses.h.in unctrl.h: unctrl.h.in sed <${NCURSES_DIR}/include/$@.in >$@ \ + -e "s%@NCURSES_SP_FUNCS@%0%g" \ -e "/@NCURSES_MAJOR@/s%%${NCURSES_MAJOR}%" \ -e "/@NCURSES_MINOR@/s%%${NCURSES_MINOR}%" @@ -508,6 +519,7 @@ MAN= \ curs_scr_dump.3 \ curs_scroll.3 \ curs_slk.3 \ + curs_sp_funcs.3 \ curs_termattrs.3 \ curs_termcap.3 \ curs_terminfo.3 \ @@ -515,6 +527,7 @@ MAN= \ curs_touch.3 \ curs_trace.3 \ curs_util.3 \ + curs_variables.3 \ curs_window.3 \ default_colors.3 \ define_key.3 \ @@ -524,6 +537,7 @@ MAN= \ legacy_coding.3 \ ncurses.3 \ resizeterm.3 \ + term_variables.3 \ wresize.3 MAN+= \ @@ -538,12 +552,12 @@ MAN+= \ curs_ins_wstr.3 \ curs_printw.3 \ curs_scanw.3 -.endif - -CLEANFILES+= ${MAN:M*.3} MAN+= term.5 terminfo.5 MAN+= term.7 +.endif + +CLEANFILES+= ${MAN:M*.3} MLINKS= ncurses.3 curses.3 \ curs_addch.3 addch.3 \ @@ -823,6 +837,123 @@ MLINKS= ncurses.3 curses.3 \ curs_slk.3 slk_restore.3 \ curs_slk.3 slk_set.3 \ curs_slk.3 slk_touch.3 \ + curs_sp_funcs.3 sp_funcs.3 \ + curs_sp_funcs.3 assume_default_colors_sp.3 \ + curs_sp_funcs.3 baudrate_sp.3 \ + curs_sp_funcs.3 beep_sp.3 \ + curs_sp_funcs.3 can_change_color_sp.3 \ + curs_sp_funcs.3 cbreak_sp.3 \ + curs_sp_funcs.3 ceiling_panel.3 \ + curs_sp_funcs.3 color_content_sp.3 \ + curs_sp_funcs.3 curs_set_sp.3 \ + curs_sp_funcs.3 def_prog_mode_sp.3 \ + curs_sp_funcs.3 def_shell_mode_sp.3 \ + curs_sp_funcs.3 define_key_sp.3 \ + curs_sp_funcs.3 del_curterm_sp.3 \ + curs_sp_funcs.3 delay_output_sp.3 \ + curs_sp_funcs.3 doupdate_sp.3 \ + curs_sp_funcs.3 echo_sp.3 \ + curs_sp_funcs.3 endwin_sp.3 \ + curs_sp_funcs.3 erasechar_sp.3 \ + curs_sp_funcs.3 filter_sp.3 \ + curs_sp_funcs.3 flash_sp.3 \ + curs_sp_funcs.3 flushinp_sp.3 \ + curs_sp_funcs.3 get_escdelay_sp.3 \ + curs_sp_funcs.3 getmouse_sp.3 \ + curs_sp_funcs.3 getwin_sp.3 \ + curs_sp_funcs.3 ground_panel.3 \ + curs_sp_funcs.3 halfdelay_sp.3 \ + curs_sp_funcs.3 has_colors_sp.3 \ + curs_sp_funcs.3 has_ic_sp.3 \ + curs_sp_funcs.3 has_il_sp.3 \ + curs_sp_funcs.3 has_key_sp.3 \ + curs_sp_funcs.3 has_mouse_sp.3 \ + curs_sp_funcs.3 init_color_sp.3 \ + curs_sp_funcs.3 init_pair_sp.3 \ + curs_sp_funcs.3 intrflush_sp.3 \ + curs_sp_funcs.3 is_term_resized_sp.3 \ + curs_sp_funcs.3 isendwin_sp.3 \ + curs_sp_funcs.3 key_defined_sp.3 \ + curs_sp_funcs.3 keybound_sp.3 \ + curs_sp_funcs.3 keyname_sp.3 \ + curs_sp_funcs.3 keyok_sp.3 \ + curs_sp_funcs.3 killchar_sp.3 \ + curs_sp_funcs.3 mcprint_sp.3 \ + curs_sp_funcs.3 mouseinterval_sp.3 \ + curs_sp_funcs.3 mousemask_sp.3 \ + curs_sp_funcs.3 mvcur_sp.3 \ + curs_sp_funcs.3 napms_sp.3 \ + curs_sp_funcs.3 new_form_sp.3 \ + curs_sp_funcs.3 new_menu_sp.3 \ + curs_sp_funcs.3 new_prescr.3 \ + curs_sp_funcs.3 newpad_sp.3 \ + curs_sp_funcs.3 newterm_sp.3 \ + curs_sp_funcs.3 newwin_sp.3 \ + curs_sp_funcs.3 nl_sp.3 \ + curs_sp_funcs.3 nocbreak_sp.3 \ + curs_sp_funcs.3 noecho_sp.3 \ + curs_sp_funcs.3 nofilter_sp.3 \ + curs_sp_funcs.3 nonl_sp.3 \ + curs_sp_funcs.3 noqiflush_sp.3 \ + curs_sp_funcs.3 noraw_sp.3 \ + curs_sp_funcs.3 pair_content_sp.3 \ + curs_sp_funcs.3 putp_sp.3 \ + curs_sp_funcs.3 qiflush_sp.3 \ + curs_sp_funcs.3 raw_sp.3 \ + curs_sp_funcs.3 reset_prog_mode_sp.3 \ + curs_sp_funcs.3 reset_shell_mode_sp.3 \ + curs_sp_funcs.3 resetty_sp.3 \ + curs_sp_funcs.3 resize_term_sp.3 \ + curs_sp_funcs.3 resizeterm_sp.3 \ + curs_sp_funcs.3 restartterm_sp.3 \ + curs_sp_funcs.3 ripoffline_sp.3 \ + curs_sp_funcs.3 savetty_sp.3 \ + curs_sp_funcs.3 scr_init_sp.3 \ + curs_sp_funcs.3 scr_restore_sp.3 \ + curs_sp_funcs.3 scr_set_sp.3 \ + curs_sp_funcs.3 set_curterm_sp.3 \ + curs_sp_funcs.3 set_escdelay_sp.3 \ + curs_sp_funcs.3 set_tabsize_sp.3 \ + curs_sp_funcs.3 slk_attr_set_sp.3 \ + curs_sp_funcs.3 slk_attr_sp.3 \ + curs_sp_funcs.3 slk_attroff_sp.3 \ + curs_sp_funcs.3 slk_attron_sp.3 \ + curs_sp_funcs.3 slk_attrset_sp.3 \ + curs_sp_funcs.3 slk_clear_sp.3 \ + curs_sp_funcs.3 slk_color_sp.3 \ + curs_sp_funcs.3 slk_init_sp.3 \ + curs_sp_funcs.3 slk_label_sp.3 \ + curs_sp_funcs.3 slk_noutrefresh_sp.3 \ + curs_sp_funcs.3 slk_refresh_sp.3 \ + curs_sp_funcs.3 slk_restore_sp.3 \ + curs_sp_funcs.3 slk_set_sp.3 \ + curs_sp_funcs.3 slk_touch_sp.3 \ + curs_sp_funcs.3 start_color_sp.3 \ + curs_sp_funcs.3 term_attrs_sp.3 \ + curs_sp_funcs.3 termattrs_sp.3 \ + curs_sp_funcs.3 termname_sp.3 \ + curs_sp_funcs.3 tgetent_sp.3 \ + curs_sp_funcs.3 tgetflag_sp.3 \ + curs_sp_funcs.3 tgetnum_sp.3 \ + curs_sp_funcs.3 tgetstr_sp.3 \ + curs_sp_funcs.3 tigetflag_sp.3 \ + curs_sp_funcs.3 tigetnum_sp.3 \ + curs_sp_funcs.3 tigetstr_sp.3 \ + curs_sp_funcs.3 tputs_sp.3 \ + curs_sp_funcs.3 typeahead_sp.3 \ + curs_sp_funcs.3 unctrl_sp.3 \ + curs_sp_funcs.3 unget_wch_sp.3 \ + curs_sp_funcs.3 ungetch_sp.3 \ + curs_sp_funcs.3 ungetmouse_sp.3 \ + curs_sp_funcs.3 update_panels_sp.3 \ + curs_sp_funcs.3 use_default_colors_sp.3 \ + curs_sp_funcs.3 use_env_sp.3 \ + curs_sp_funcs.3 use_legacy_coding_sp.3 \ + curs_sp_funcs.3 vid_attr_sp.3 \ + curs_sp_funcs.3 vid_puts_sp.3 \ + curs_sp_funcs.3 vidattr_sp.3 \ + curs_sp_funcs.3 vidputs_sp.3 \ + curs_sp_funcs.3 wunctrl_sp.3 \ curs_termattrs.3 baudrate.3 \ curs_termattrs.3 erasechar.3 \ curs_termattrs.3 erasewchar.3 \ diff --git a/lib/ncurses/ncurses/ncurses_cfg.h b/lib/ncurses/ncurses/ncurses_cfg.h index 42570c9..9ca3a97 100644 --- a/lib/ncurses/ncurses/ncurses_cfg.h +++ b/lib/ncurses/ncurses/ncurses_cfg.h @@ -49,135 +49,166 @@ #ifndef NC_CONFIG_H #define NC_CONFIG_H -#ifdef __cplusplus +#define SYSTEM_NAME "FreeBSD" +#if 0 #include <stdlib.h> #endif +#define HAVE_LONG_FILE_NAMES 1 +#define MIXEDCASE_FILENAMES 1 +#define USE_SYSMOUSE 1 +#define HAVE_BIG_CORE 1 +#define TERMPATH "/etc/termcap:/usr/share/misc/termcap" +#define USE_GETCAP 1 +#define HAVE_REMOVE 1 +#define HAVE_UNLINK 1 +#define HAVE_LINK 1 +#define HAVE_SYMLINK 1 +#define USE_LINKS 1 #define BSD_TPUTS 1 -#define CC_HAS_PROTOS 1 -#define CPP_HAS_STATIC_CAST 1 -#define ETIP_NEEDS_MATH_H 1 -#define GCC_NORETURN __attribute__((noreturn)) -#define GCC_PRINTF 1 +#define HAVE_LANGINFO_CODESET 1 +#define HAVE_FSEEKO 1 +#define HAVE_ASSUME_DEFAULT_COLORS 1 +#define HAVE_CURSES_VERSION 1 +#define HAVE_HAS_KEY 1 +#define HAVE_RESIZETERM 1 +#define HAVE_RESIZE_TERM 1 +#define HAVE_TERM_ENTRY_H 1 +#define HAVE_USE_DEFAULT_COLORS 1 +#define HAVE_USE_SCREEN 1 +#define HAVE_USE_WINDOW 1 +#define HAVE_WRESIZE 1 +#define NCURSES_EXT_FUNCS 1 +#define NCURSES_NO_PADDING 1 +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define SIZEOF_SIGNED_CHAR 1 +#define USE_SIGWINCH 1 +#define USE_ASSUMED_COLOR 1 +#define USE_HASHMAP 1 +#define USE_COLORFGBG 1 +#define NCURSES_WRAP_PREFIX "_nc_" #define GCC_SCANF 1 +#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var))) +#define GCC_PRINTF 1 +#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) #define GCC_UNUSED __attribute__((unused)) -#define HAVE_BIG_CORE 1 -#define HAVE_BSD_CGETENT 1 -#define HAVE_CURSES_VERSION 1 +#define GCC_NORETURN __attribute__((noreturn)) +#define HAVE_NC_ALLOC_H 1 +#define HAVE_GETTIMEOFDAY 1 +#define STDC_HEADERS 1 #define HAVE_DIRENT_H 1 -#define HAVE_ERRNO 1 +#define TIME_WITH_SYS_TIME 1 +#define HAVE_REGEX_H_FUNCS 1 #define HAVE_FCNTL_H 1 -#define HAVE_FORM_H 1 -#define HAVE_FSEEKO 1 +#define HAVE_GETOPT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_LOCALE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_POLL_H 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_POLL_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TIMES_H 1 +#define HAVE_TTYENT_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_WCTYPE_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_GETOPT_H 1 +#define HAVE_GETOPT_HEADER 1 +#define HAVE_SYS_TIME_SELECT 1 +#define SIG_ATOMIC_T volatile sig_atomic_t +#define TYPEOF_CHTYPE int +#define HAVE_ERRNO 1 #define HAVE_GETCWD 1 #define HAVE_GETEGID 1 #define HAVE_GETEUID 1 -#define HAVE_GETOPT_H 1 -#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTTYNAM 1 -#define HAVE_HAS_KEY 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_IOSTREAM 1 -#define HAVE_ISASCII 1 #define HAVE_ISSETUGID 1 -#define HAVE_LANGINFO_CODESET 1 -#define HAVE_LIBFORM 1 -#define HAVE_LIBMENU 1 -#define HAVE_LIBPANEL 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LINK 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LONG_FILE_NAMES 1 -#define HAVE_MEMORY_H 1 -#define HAVE_MENU_H 1 -#define HAVE_MKSTEMP 1 -#define HAVE_NANOSLEEP 1 -#define HAVE_NC_ALLOC_H 1 -#define HAVE_PANEL_H 1 #define HAVE_POLL 1 -#define HAVE_POLL_H 1 -#define HAVE_REGEX_H_FUNCS 1 +#define HAVE_PUTENV 1 #define HAVE_REMOVE 1 -#define HAVE_REMOVE 1 -#define HAVE_RESIZETERM 1 -#define HAVE_RESIZE_TERM 1 #define HAVE_SELECT 1 #define HAVE_SETBUF 1 #define HAVE_SETBUFFER 1 +#define HAVE_SETENV 1 #define HAVE_SETVBUF 1 #define HAVE_SIGACTION 1 #define HAVE_SIGVEC 1 -#define HAVE_SIZECHANGE 1 -#define HAVE_SLK_COLOR 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDLIB_H 1 #define HAVE_STRDUP 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 #define HAVE_STRSTR 1 -#define HAVE_SYMLINK 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_POLL_H 1 -#define HAVE_SYS_SELECT_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIMES_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TIME_SELECT 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_TCGETATTR 1 #define HAVE_TCGETPGRP 1 -#define HAVE_TERMIOS_H 1 #define HAVE_TIMES 1 -#define HAVE_TTYENT_H 1 -#define HAVE_TYPEINFO 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNLINK 1 -#define HAVE_USE_DEFAULT_COLORS 1 #define HAVE_VSNPRINTF 1 +#define HAVE_BSD_CGETENT 1 +#define CGETENT_CONST const +#define HAVE_ISASCII 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_TERMIOS_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_TCGETATTR 1 #define HAVE_VSSCANF 1 -#define HAVE_WCTYPE_H 1 -#define HAVE_WRESIZE 1 +#define HAVE_MKSTEMP 1 +#define HAVE_SIZECHANGE 1 +#define HAVE_WORKING_POLL 1 +#define HAVE_VA_COPY 1 +#define HAVE___VA_COPY 1 +#define HAVE_UNISTD_H 1 +#define HAVE_FORK 1 +#define HAVE_VFORK 1 +#define HAVE_WORKING_VFORK 1 +#define HAVE_WORKING_FORK 1 +#define USE_OPENPTY_HEADER <libutil.h> +#define USE_XTERM_PTY 1 +#define HAVE_TYPEINFO 1 +#define HAVE_IOSTREAM 1 #define IOSTREAM_NAMESPACE 1 -#define MIXEDCASE_FILENAMES 1 -#define NCURSES_EXT_FUNCS 1 -#define NCURSES_NO_PADDING 1 +#define CPP_HAS_STATIC_CAST 1 +#define HAVE_SLK_COLOR 1 +#define HAVE_PANEL_H 1 +#define HAVE_LIBPANEL 1 +#define HAVE_MENU_H 1 +#define HAVE_LIBMENU 1 +#define HAVE_FORM_H 1 +#define HAVE_LIBFORM 1 #define NCURSES_PATHSEP ':' -#define NCURSES_VERSION_STRING "5.7.20081102" -#define NDEBUG 1 -#define RETSIGTYPE void -#define SIG_ATOMIC_T volatile sig_atomic_t -#define SIZEOF_SIGNED_CHAR 1 -#define STDC_HEADERS 1 -#define SYSTEM_NAME "FreeBSD" -#define TERMPATH "/etc/termcap:/usr/share/misc/termcap" -#define TIME_WITH_SYS_TIME 1 -#define TYPEOF_CHTYPE int -#define USE_ASSUMED_COLOR 1 -#define USE_COLORFGBG 1 -#define USE_GETCAP 1 -#define USE_HASHMAP 1 -#define USE_LINKS 1 -#define USE_SIGWINCH 1 -#define USE_SYSMOUSE 1 -#define USE_TERMCAP 1 +#define NCURSES_VERSION_STRING "5.9.20140222" +#define NCURSES_OSPEED_COMPAT 1 + +/* + * Begin FreeBSD-specific changes + */ +/* Support ENABLE_WIDEC */ #ifdef ENABLE_WIDEC #define USE_WIDEC_SUPPORT 1 +#define NCURSES_WIDECHAR 1 +#define HAVE_PUTWC 1 #define HAVE_BTOWC 1 +#define HAVE_WCTOB 1 +#define HAVE_MBTOWC 1 +#define HAVE_WCTOMB 1 #define HAVE_MBLEN 1 #define HAVE_MBRLEN 1 #define HAVE_MBRTOWC 1 -#define HAVE_MBSRTOWCS 1 -#define HAVE_MBSTOWCS 1 -#define HAVE_MBTOWC 1 -#define HAVE_PUTWC 1 #define HAVE_WCSRTOMBS 1 +#define HAVE_MBSRTOWCS 1 #define HAVE_WCSTOMBS 1 -#define HAVE_WCTOB 1 -#define HAVE_WCTOMB 1 +#define HAVE_MBSTOWCS 1 #define NEED_WCHAR_H 1 +#define SIZEOF_WCHAR_T 4 #endif +/* + * End FreeBSD-specific changes + */ #include <ncurses_def.h> diff --git a/lib/ncurses/panel/Makefile b/lib/ncurses/panel/Makefile index 8e99767..7929aed 100644 --- a/lib/ncurses/panel/Makefile +++ b/lib/ncurses/panel/Makefile @@ -58,7 +58,7 @@ MLINKS= panel.3 bottom_panel.3 \ panel.3 top_panel.3 \ panel.3 update_panels.3 .else -NO_MAN= +MAN= .endif .include <bsd.lib.mk> diff --git a/lib/tests/Makefile b/lib/tests/Makefile new file mode 100644 index 0000000..935fd70 --- /dev/null +++ b/lib/tests/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/lib + +.PATH: ${.CURDIR:H:H}/tests +KYUAFILE= yes + +.include <bsd.test.mk> |