Merge ^/head r278499 through r278755.
This commit is contained in:
commit
569e61a4fc
@ -50,10 +50,6 @@
|
||||
.include <bsd.arch.inc.mk>
|
||||
.include <bsd.compiler.mk>
|
||||
|
||||
# We must do share/info early so that installation of info `dir'
|
||||
# entries works correctly. Do it first since it is less likely to
|
||||
# grow dependencies on include and lib than vice versa.
|
||||
#
|
||||
# We must do lib/ and libexec/ before bin/, because if installworld
|
||||
# installs a new /bin/sh, the 'make' command will *immediately*
|
||||
# use that new version. And the new (dynamically-linked) /bin/sh
|
||||
@ -63,7 +59,7 @@ SRCDIR?= ${.CURDIR}
|
||||
.if defined(SUBDIR_OVERRIDE)
|
||||
SUBDIR= ${SUBDIR_OVERRIDE}
|
||||
.else
|
||||
SUBDIR= share/info lib libexec
|
||||
SUBDIR= lib libexec
|
||||
SUBDIR+=bin
|
||||
.if ${MK_GAMES} != "no"
|
||||
SUBDIR+=games
|
||||
@ -193,9 +189,8 @@ OBJTREE= ${MAKEOBJDIRPREFIX}
|
||||
OBJTREE= ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH}
|
||||
.endif
|
||||
WORLDTMP= ${OBJTREE}${.CURDIR}/tmp
|
||||
# /usr/games added for fortune which depend on strfile
|
||||
BPATH= ${WORLDTMP}/legacy/usr/sbin:${WORLDTMP}/legacy/usr/bin:${WORLDTMP}/legacy/usr/games:${WORLDTMP}/legacy/bin
|
||||
XPATH= ${WORLDTMP}/usr/sbin:${WORLDTMP}/usr/bin:${WORLDTMP}/usr/games
|
||||
BPATH= ${WORLDTMP}/legacy/usr/sbin:${WORLDTMP}/legacy/usr/bin:${WORLDTMP}/legacy/bin
|
||||
XPATH= ${WORLDTMP}/usr/sbin:${WORLDTMP}/usr/bin
|
||||
STRICTTMPPATH= ${BPATH}:${XPATH}
|
||||
TMPPATH= ${STRICTTMPPATH}:${PATH}
|
||||
|
||||
@ -811,9 +806,6 @@ ITOOLS+=makewhatis
|
||||
|
||||
# Non-base distributions produced by the base system
|
||||
EXTRA_DISTRIBUTIONS= doc
|
||||
.if ${MK_GAMES} != "no"
|
||||
EXTRA_DISTRIBUTIONS+= games
|
||||
.endif
|
||||
.if defined(LIB32TMP) && ${MK_LIB32} != "no"
|
||||
EXTRA_DISTRIBUTIONS+= lib32
|
||||
.endif
|
||||
|
@ -38,7 +38,7 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20150210: new clang import which bumps version from 3.5.1 to 3.6.0.
|
||||
# 2015mmdd: new clang import which bumps version from 3.5.1 to 3.6.0.
|
||||
OLD_FILES+=usr/include/clang/3.5.1/__wmmintrin_aes.h
|
||||
OLD_FILES+=usr/include/clang/3.5.1/__wmmintrin_pclmul.h
|
||||
OLD_FILES+=usr/include/clang/3.5.1/altivec.h
|
||||
@ -93,6 +93,22 @@ OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a
|
||||
OLD_DIRS+=usr/lib/clang/3.5.1/lib/freebsd
|
||||
OLD_DIRS+=usr/lib/clang/3.5.1/lib
|
||||
OLD_DIRS+=usr/lib/clang/3.5.1
|
||||
# 20150212: /usr/games moving into /usr/bin
|
||||
OLD_FILES+=usr/games/bcd
|
||||
OLD_FILES+=usr/games/caesar
|
||||
OLD_FILES+=usr/games/factor
|
||||
OLD_FILES+=usr/games/fortune
|
||||
OLD_FILES+=usr/games/grdc
|
||||
OLD_FILES+=usr/games/morse
|
||||
OLD_FILES+=usr/games/number
|
||||
OLD_FILES+=usr/games/pom
|
||||
OLD_FILES+=usr/games/ppt
|
||||
OLD_FILES+=usr/games/primes
|
||||
OLD_FILES+=usr/games/random
|
||||
OLD_FILES+=usr/games/rot13
|
||||
OLD_FILES+=usr/games/strfile
|
||||
OLD_FILES+=usr/games/unstr
|
||||
OLD_DIRS+=usr/games
|
||||
# 20150209: liblzma header
|
||||
OLD_FILES+=usr/include/lzma/lzma.h
|
||||
# 20150124: spl.9 and friends
|
||||
|
15
UPDATING
15
UPDATING
@ -34,6 +34,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
2015mmdd:
|
||||
Clang and llvm have been upgraded to 3.6.0 release.
|
||||
|
||||
20150210:
|
||||
The autofs(4) ABI was changed in order to restore binary compatibility
|
||||
with 10.1-RELEASE. The automountd(8) daemon needs to be rebuilt to work
|
||||
with the new kernel.
|
||||
|
||||
20150131:
|
||||
The powerpc64 kernel has been changed to a position-independent
|
||||
executable. This can only be booted with a new version of loader(8),
|
||||
@ -290,6 +295,16 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
The lindev device has been removed since /dev/full has been made a
|
||||
standard device. __FreeBSD_version has been bumped.
|
||||
|
||||
20140424:
|
||||
The knob WITHOUT_VI was added to the base system, which controls
|
||||
building ex(1), vi(1), etc. Older releases of FreeBSD required ex(1)
|
||||
in order to reorder files share/termcap and didn't build ex(1) as a
|
||||
build tool, so building/installing with WITH_VI is highly advised for
|
||||
build hosts for older releases.
|
||||
|
||||
This issue has been fixed in stable/9 and stable/10 in r277022 and
|
||||
r276991, respectively.
|
||||
|
||||
20140418:
|
||||
The YES_HESIOD knob has been removed. It has been obsolete for
|
||||
a decade. Please move to using WITH_HESIOD instead or your builds
|
||||
|
@ -4,94 +4,87 @@
|
||||
jail_name_to_jid()
|
||||
{
|
||||
local check_name="$1"
|
||||
(
|
||||
line="$(jls -n 2> /dev/null | grep name=$check_name )"
|
||||
for nv in $line; do
|
||||
local name="${nv%=*}"
|
||||
if [ "${name}" = "jid" ]; then
|
||||
eval $nv
|
||||
echo $jid
|
||||
break
|
||||
fi
|
||||
done
|
||||
)
|
||||
jls -j "$check_name" -s 2>/dev/null | tr ' ' '\n' | grep jid= | sed -e 's/.*=//g'
|
||||
}
|
||||
|
||||
base=pgrep_j_test
|
||||
|
||||
if [ `id -u` -ne 0 ]; then
|
||||
echo "1..0 # skip Test needs uid 0."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "1..3"
|
||||
|
||||
sleep=$(pwd)/sleep.txt
|
||||
ln -sf /bin/sleep $sleep
|
||||
|
||||
name="pgrep -j <jid>"
|
||||
if [ `id -u` -eq 0 ]; then
|
||||
sleep=$(pwd)/sleep.txt
|
||||
ln -sf /bin/sleep $sleep
|
||||
jail -c path=/ name=${base}_1_1 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_1_1.pid $sleep 5 &
|
||||
sleep_amount=5
|
||||
jail -c path=/ name=${base}_1_1 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_1_1.pid $sleep $sleep_amount &
|
||||
|
||||
jail -c path=/ name=${base}_1_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_1_2.pid $sleep 5 &
|
||||
jail -c path=/ name=${base}_1_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_1_2.pid $sleep $sleep_amount &
|
||||
|
||||
for i in `seq 1 10`; do
|
||||
jid1=$(jail_name_to_jid ${base}_1_1)
|
||||
jid2=$(jail_name_to_jid ${base}_1_2)
|
||||
jid="${jid1},${jid2}"
|
||||
pid1="$(pgrep -f -x -j $jid "$sleep 5" | sort)"
|
||||
pid2=$(printf "%s\n%s" "$(cat ${PWD}/${base}_1_1.pid)" \
|
||||
$(cat ${PWD}/${base}_1_2.pid) | sort)
|
||||
if [ "$pid1" = "$pid2" ]; then
|
||||
echo "ok 1 - $name"
|
||||
else
|
||||
echo "not ok 1 - $name"
|
||||
fi
|
||||
[ -f ${PWD}/${base}_1_1.pid ] && kill $(cat ${PWD}/${base}_1_1.pid)
|
||||
[ -f ${PWD}/${base}_1_2.pid ] && kill $(cat ${PWD}/${base}_1_2.pid)
|
||||
rm -f $sleep
|
||||
case "$jid" in
|
||||
[0-9]+,[0-9]+)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
pid1="$(pgrep -f -x -j "$jid" "$sleep $sleep_amount" | sort)"
|
||||
pid2=$(printf "%s\n%s" "$(cat ${PWD}/${base}_1_1.pid)" \
|
||||
$(cat ${PWD}/${base}_1_2.pid) | sort)
|
||||
if [ "$pid1" = "$pid2" ]; then
|
||||
echo "ok 1 - $name"
|
||||
else
|
||||
echo "ok 1 - $name # skip Test needs uid 0."
|
||||
echo "not ok 1 - $name # pgrep output: '$(echo $pid1)', pidfile output: '$(echo $pid2)'"
|
||||
fi
|
||||
[ -f ${PWD}/${base}_1_1.pid ] && kill $(cat ${PWD}/${base}_1_1.pid)
|
||||
[ -f ${PWD}/${base}_1_2.pid ] && kill $(cat ${PWD}/${base}_1_2.pid)
|
||||
wait
|
||||
|
||||
name="pgrep -j any"
|
||||
if [ `id -u` -eq 0 ]; then
|
||||
sleep=$(pwd)/sleep.txt
|
||||
ln -sf /bin/sleep $sleep
|
||||
jail -c path=/ name=${base}_2_1 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_2_1.pid $sleep 5 &
|
||||
sleep_amount=6
|
||||
jail -c path=/ name=${base}_2_1 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_2_1.pid $sleep $sleep_amount &
|
||||
|
||||
jail -c path=/ name=${base}_2_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_2_2.pid $sleep 5 &
|
||||
jail -c path=/ name=${base}_2_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_2_2.pid $sleep $sleep_amount &
|
||||
|
||||
sleep 2
|
||||
pid1="$(pgrep -f -x -j any "$sleep 5" | sort)"
|
||||
pid2=$(printf "%s\n%s" "$(cat ${PWD}/${base}_2_1.pid)" \
|
||||
$(cat ${PWD}/${base}_2_2.pid) | sort)
|
||||
if [ "$pid1" = "$pid2" ]; then
|
||||
echo "ok 2 - $name"
|
||||
else
|
||||
echo "not ok 2 - $name"
|
||||
fi
|
||||
[ -f ${PWD}/${base}_2_1.pid ] && kill $(cat ${PWD}/${base}_2_1.pid)
|
||||
[ -f ${PWD}/${base}_2_2.pid ] && kill $(cat ${PWD}/${base}_2_2.pid)
|
||||
rm -f $sleep
|
||||
sleep 2
|
||||
pid1="$(pgrep -f -x -j any "$sleep $sleep_amount" | sort)"
|
||||
pid2=$(printf "%s\n%s" "$(cat ${PWD}/${base}_2_1.pid)" \
|
||||
$(cat ${PWD}/${base}_2_2.pid) | sort)
|
||||
if [ "$pid1" = "$pid2" ]; then
|
||||
echo "ok 2 - $name"
|
||||
else
|
||||
echo "ok 2 - $name # skip Test needs uid 0."
|
||||
echo "not ok 2 - $name # pgrep output: '$(echo $pid1)', pidfile output: '$(echo $pid2)'"
|
||||
fi
|
||||
[ -f ${PWD}/${base}_2_1.pid ] && kill $(cat ${PWD}/${base}_2_1.pid)
|
||||
[ -f ${PWD}/${base}_2_2.pid ] && kill $(cat ${PWD}/${base}_2_2.pid)
|
||||
wait
|
||||
|
||||
name="pgrep -j none"
|
||||
if [ `id -u` -eq 0 ]; then
|
||||
sleep=$(pwd)/sleep.txt
|
||||
ln -sf /bin/sleep $sleep
|
||||
daemon -p ${PWD}/${base}_3_1.pid $sleep 5 &
|
||||
jail -c path=/ name=${base}_3_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_3_2.pid $sleep 5 &
|
||||
sleep 2
|
||||
pid="$(pgrep -f -x -j none "$sleep 5")"
|
||||
if [ "$pid" = "$(cat ${PWD}/${base}_3_1.pid)" ]; then
|
||||
echo "ok 3 - $name"
|
||||
else
|
||||
echo "not ok 3 - $name"
|
||||
fi
|
||||
rm -f $sleep
|
||||
[ -f ${PWD}/${base}_3_1.pid ] && kill $(cat $PWD/${base}_3_1.pid)
|
||||
[ -f ${PWD}/${base}_3_2.pid ] && kill $(cat $PWD/${base}_3_2.pid)
|
||||
sleep_amount=7
|
||||
daemon -p ${PWD}/${base}_3_1.pid $sleep $sleep_amount &
|
||||
jail -c path=/ name=${base}_3_2 ip4.addr=127.0.0.1 \
|
||||
command=daemon -p ${PWD}/${base}_3_2.pid $sleep $sleep_amount &
|
||||
sleep 2
|
||||
pid="$(pgrep -f -x -j none "$sleep $sleep_amount")"
|
||||
if [ "$pid" = "$(cat ${PWD}/${base}_3_1.pid)" ]; then
|
||||
echo "ok 3 - $name"
|
||||
else
|
||||
echo "ok 3 - $name # skip Test needs uid 0."
|
||||
echo "not ok 3 - $name # pgrep output: '$(echo $pid1)', pidfile output: '$(echo $pid2)'"
|
||||
fi
|
||||
[ -f ${PWD}/${base}_3_1.pid ] && kill $(cat $PWD/${base}_3_1.pid)
|
||||
[ -f ${PWD}/${base}_3_2.pid ] && kill $(cat $PWD/${base}_3_2.pid)
|
||||
|
||||
rm -f $sleep
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
@ -69,7 +71,7 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
if (sigsetjmp(env, 1) == 0) {
|
||||
for (;;)
|
||||
(void) ioctl(-1, -1, NULL);
|
||||
(void) ioctl(-1, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -80,20 +82,19 @@ main(int argc, char *argv[])
|
||||
fds[n++] = open(file, O_WRONLY);
|
||||
fds[n++] = open(file, O_RDWR);
|
||||
|
||||
fds[n++] = open(file, O_RDWR | O_APPEND | O_CREAT | O_DSYNC |
|
||||
O_LARGEFILE | O_NOCTTY | O_NONBLOCK | O_NDELAY | O_RSYNC |
|
||||
O_SYNC | O_TRUNC | O_XATTR, 0666);
|
||||
fds[n++] = open(file, O_RDWR | O_APPEND | O_CREAT |
|
||||
O_NOCTTY | O_NONBLOCK | O_NDELAY | O_SYNC | O_TRUNC | 0666);
|
||||
|
||||
fds[n++] = open(file, O_RDWR);
|
||||
(void) lseek(fds[n - 1], 123, SEEK_SET);
|
||||
|
||||
/*
|
||||
* Once we have all the file descriptors in the state we want to test,
|
||||
* issue a bogus ioctl() on each fd with cmd -1 and arg NULL to whack
|
||||
* issue a bogus ioctl() on each fd with cmd 0 and arg NULL to whack
|
||||
* our DTrace script into recording the content of the fds[] array.
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
(void) ioctl(fds[i], -1, NULL);
|
||||
(void) ioctl(fds[i], 0, NULL);
|
||||
|
||||
assert(n <= sizeof (fds) / sizeof (fds[0]));
|
||||
exit(0);
|
||||
|
@ -36,7 +36,7 @@ syscall::ioctl:entry
|
||||
}
|
||||
|
||||
syscall::ioctl:entry
|
||||
/pid == $1 && arg0 != -1u && arg1 == -1u && arg2 == NULL/
|
||||
/pid == $1 && arg0 != -1u && arg1 == 0 && arg2 == NULL/
|
||||
{
|
||||
printf("fds[%d] fi_name = %s\n", arg0, fds[arg0].fi_name);
|
||||
printf("fds[%d] fi_dirname = %s\n", arg0, fds[arg0].fi_dirname);
|
||||
|
190
cddl/contrib/opensolaris/lib/libdtrace/arm/dt_isadep.c
Normal file
190
cddl/contrib/opensolaris/lib/libdtrace/arm/dt_isadep.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright 2014 Howard Su
|
||||
* Copyright 2015 George V. Neville-Neil
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <dt_impl.h>
|
||||
#include <dt_pid.h>
|
||||
|
||||
#if !defined(sun)
|
||||
#define PR_MODEL_ILP32 1
|
||||
#define PR_MODEL_LP64 2
|
||||
#include <libproc_compat.h>
|
||||
#endif
|
||||
|
||||
#define OP(x) ((x) >> 30)
|
||||
#define OP2(x) (((x) >> 22) & 0x07)
|
||||
#define COND(x) (((x) >> 25) & 0x0f)
|
||||
#define A(x) (((x) >> 29) & 0x01)
|
||||
|
||||
#define OP_BRANCH 0
|
||||
|
||||
#define OP2_BPcc 0x1
|
||||
#define OP2_Bicc 0x2
|
||||
#define OP2_BPr 0x3
|
||||
#define OP2_FBPfcc 0x5
|
||||
#define OP2_FBfcc 0x6
|
||||
|
||||
/*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));
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
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)
|
||||
{
|
||||
|
||||
uint32_t *text;
|
||||
int i;
|
||||
int srdepth = 0;
|
||||
|
||||
dt_dprintf("%s: unimplemented\n", __func__);
|
||||
return (DT_PROC_ERR);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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*/
|
||||
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));
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
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));
|
||||
}
|
||||
|
||||
return (ftp->ftps_noffs);
|
||||
}
|
@ -169,12 +169,12 @@ write_objects(iidesc_t *idp, ctf_buf_t *b)
|
||||
{
|
||||
ushort_t id = (idp ? idp->ii_dtype->t_id : 0);
|
||||
|
||||
ctf_buf_write(b, &id, sizeof (id));
|
||||
|
||||
if (target_requires_swap) {
|
||||
SWAP_16(id);
|
||||
}
|
||||
|
||||
ctf_buf_write(b, &id, sizeof (id));
|
||||
|
||||
debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@ _libzpool= libzpool
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
|
||||
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc"
|
||||
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc" || \
|
||||
${MACHINE_CPUARCH} == "arm"
|
||||
_drti= drti
|
||||
_libdtrace= libdtrace
|
||||
.endif
|
||||
|
@ -81,6 +81,10 @@ CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/mips
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/mips
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/mips
|
||||
.elif ${MACHINE_CPUARCH} == "arm"
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/arm
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/arm
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/arm
|
||||
.elif ${MACHINE_CPUARCH} == "powerpc"
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/powerpc
|
||||
|
@ -30,6 +30,12 @@ _plockstat= plockstat
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "arm"
|
||||
_dtrace= dtrace
|
||||
_dtruss= dtruss
|
||||
_lockstat= lockstat
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "mips"
|
||||
_dtrace= dtrace
|
||||
.endif
|
||||
|
@ -402,8 +402,8 @@ cat <<EOF
|
||||
.fini_array ${RELOCATING-0} :
|
||||
{
|
||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_start = .);}}
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array))
|
||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
|
||||
}
|
||||
${SMALL_DATA_CTOR-${RELOCATING+${CTOR}}}
|
||||
|
@ -49,7 +49,7 @@
|
||||
struct _libdwarf_globals {
|
||||
Dwarf_Handler errhand;
|
||||
Dwarf_Ptr errarg;
|
||||
int applyrela;
|
||||
int applyreloc;
|
||||
};
|
||||
|
||||
extern struct _libdwarf_globals _libdwarf;
|
||||
|
@ -33,8 +33,8 @@ dwarf_set_reloc_application(int apply)
|
||||
{
|
||||
int oldapply;
|
||||
|
||||
oldapply = _libdwarf.applyrela;
|
||||
_libdwarf.applyrela = apply;
|
||||
oldapply = _libdwarf.applyreloc;
|
||||
_libdwarf.applyreloc = apply;
|
||||
|
||||
return (oldapply);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $Id: dwarf_set_reloc_application.3 2075 2011-10-27 03:47:28Z jkoshy $
|
||||
.\"
|
||||
.Dd June 26, 2011
|
||||
.Dd February 11, 2015
|
||||
.Os
|
||||
.Dt DWARF_SET_RELOC_APPLICATION 3
|
||||
.Sh NAME
|
||||
@ -47,6 +47,8 @@ handled by the DWARF(3) library.
|
||||
If the argument
|
||||
.Ar apply
|
||||
holds a non-zero value, the library will process all the relevant
|
||||
.Dq ".rel"
|
||||
and
|
||||
.Dq ".rela"
|
||||
relocation sections and will apply the relocation records found to
|
||||
their corresponding DWARF sections.
|
||||
|
@ -31,5 +31,5 @@ ELFTC_VCSID("$Id: libdwarf.c 2070 2011-10-27 03:05:32Z jkoshy $");
|
||||
struct _libdwarf_globals _libdwarf = {
|
||||
.errhand = NULL,
|
||||
.errarg = NULL,
|
||||
.applyrela = 1
|
||||
.applyreloc = 1
|
||||
};
|
||||
|
@ -439,6 +439,7 @@ enum Dwarf_ISA {
|
||||
DW_ISA_SPARC,
|
||||
DW_ISA_X86,
|
||||
DW_ISA_X86_64,
|
||||
DW_ISA_AARCH64,
|
||||
DW_ISA_MAX
|
||||
};
|
||||
|
||||
|
@ -50,32 +50,46 @@ static const char *debug_name[] = {
|
||||
};
|
||||
|
||||
static void
|
||||
_dwarf_elf_apply_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
|
||||
_dwarf_elf_write_reloc(Dwarf_Debug dbg, Elf_Data *symtab_data, int endian,
|
||||
void *buf, uint64_t offset, GElf_Xword r_info, GElf_Sxword r_addend)
|
||||
{
|
||||
GElf_Sym sym;
|
||||
int size;
|
||||
|
||||
if (gelf_getsym(symtab_data, GELF_R_SYM(r_info), &sym) == NULL)
|
||||
return;
|
||||
if ((size = _dwarf_get_reloc_size(dbg, GELF_R_TYPE(r_info))) == 0)
|
||||
return; /* Unknown or non-absolute relocation. */
|
||||
if (endian == ELFDATA2MSB)
|
||||
_dwarf_write_msb(buf, &offset, sym.st_value + r_addend, size);
|
||||
else
|
||||
_dwarf_write_lsb(buf, &offset, sym.st_value + r_addend, size);
|
||||
}
|
||||
|
||||
static void
|
||||
_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
|
||||
Elf_Data *symtab_data, int endian)
|
||||
{
|
||||
Dwarf_Unsigned type;
|
||||
GElf_Rela rela;
|
||||
GElf_Sym sym;
|
||||
size_t symndx;
|
||||
uint64_t offset;
|
||||
int size, j;
|
||||
GElf_Rel rel;
|
||||
int j;
|
||||
|
||||
j = 0;
|
||||
while (gelf_getrela(rel_data, j++, &rela) != NULL) {
|
||||
symndx = GELF_R_SYM(rela.r_info);
|
||||
type = GELF_R_TYPE(rela.r_info);
|
||||
while (gelf_getrel(rel_data, j++, &rel) != NULL)
|
||||
_dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
|
||||
rel.r_offset, rel.r_info, 0);
|
||||
}
|
||||
|
||||
if (gelf_getsym(symtab_data, symndx, &sym) == NULL)
|
||||
continue;
|
||||
static void
|
||||
_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
|
||||
Elf_Data *symtab_data, int endian)
|
||||
{
|
||||
GElf_Rela rela;
|
||||
int j;
|
||||
|
||||
offset = rela.r_offset;
|
||||
size = _dwarf_get_reloc_size(dbg, type);
|
||||
|
||||
if (endian == ELFDATA2MSB)
|
||||
_dwarf_write_msb(buf, &offset, rela.r_addend, size);
|
||||
else
|
||||
_dwarf_write_lsb(buf, &offset, rela.r_addend, size);
|
||||
}
|
||||
j = 0;
|
||||
while (gelf_getrela(rel_data, j++, &rela) != NULL)
|
||||
_dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
|
||||
rela.r_offset, rela.r_info, rela.r_addend);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -104,7 +118,8 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
|
||||
return (DW_DLE_ELF);
|
||||
}
|
||||
|
||||
if (sh.sh_type != SHT_RELA || sh.sh_size == 0)
|
||||
if ((sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA) ||
|
||||
sh.sh_size == 0)
|
||||
continue;
|
||||
|
||||
if (sh.sh_info == shndx && sh.sh_link == symtab) {
|
||||
@ -125,8 +140,12 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
|
||||
}
|
||||
memcpy(ed->ed_alloc, ed->ed_data->d_buf,
|
||||
ed->ed_data->d_size);
|
||||
_dwarf_elf_apply_reloc(dbg, ed->ed_alloc, rel,
|
||||
symtab_data, eh.e_ident[EI_DATA]);
|
||||
if (sh.sh_type == SHT_REL)
|
||||
_dwarf_elf_apply_rel_reloc(dbg, ed->ed_alloc,
|
||||
rel, symtab_data, eh.e_ident[EI_DATA]);
|
||||
else
|
||||
_dwarf_elf_apply_rela_reloc(dbg, ed->ed_alloc,
|
||||
rel, symtab_data, eh.e_ident[EI_DATA]);
|
||||
|
||||
return (DW_DLE_NONE);
|
||||
}
|
||||
@ -282,7 +301,7 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error)
|
||||
}
|
||||
}
|
||||
|
||||
if (_libdwarf.applyrela) {
|
||||
if (_libdwarf.applyreloc) {
|
||||
if (_dwarf_elf_relocate(dbg, elf,
|
||||
&e->eo_data[j], elf_ndxscn(scn), symtab_ndx,
|
||||
symtab_data, error) != DW_DLE_NONE)
|
||||
|
@ -35,6 +35,8 @@ _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
|
||||
assert(dbg != NULL);
|
||||
|
||||
switch (dbg->dbgp_isa) {
|
||||
case DW_ISA_AARCH64:
|
||||
return (is64 ? R_AARCH64_ABS64 : R_AARCH64_ABS32);
|
||||
case DW_ISA_X86:
|
||||
return (R_386_32);
|
||||
case DW_ISA_X86_64:
|
||||
@ -62,6 +64,12 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type)
|
||||
switch (dbg->dbg_machine) {
|
||||
case EM_NONE:
|
||||
break;
|
||||
case EM_AARCH64:
|
||||
if (rel_type == R_AARCH64_ABS32)
|
||||
return (4);
|
||||
else if (rel_type == R_AARCH64_ABS64)
|
||||
return (8);
|
||||
break;
|
||||
case EM_ARM:
|
||||
if (rel_type == R_ARM_ABS32)
|
||||
return (4);
|
||||
|
@ -27,13 +27,13 @@
|
||||
|
||||
expect() {
|
||||
echo "${2}" >expout
|
||||
atf_check -s eq:0 -o file:expout -e empty /usr/games/factor ${1}
|
||||
atf_check -s eq:0 -o file:expout -e empty /usr/bin/factor ${1}
|
||||
}
|
||||
|
||||
atf_test_case overflow
|
||||
overflow_head() {
|
||||
atf_set "descr" "Tests for overflow conditions"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
atf_set "require.progs" "/usr/bin/factor"
|
||||
}
|
||||
overflow_body() {
|
||||
expect '8675309' '8675309: 8675309'
|
||||
@ -44,7 +44,7 @@ atf_test_case loop
|
||||
loop_head() {
|
||||
atf_set "descr" "Tests some cases that once locked the program" \
|
||||
"in an infinite loop"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
atf_set "require.progs" "/usr/bin/factor"
|
||||
}
|
||||
loop_body() {
|
||||
expect '99999999999991' '99999999999991: 7 13 769231 1428571'
|
||||
|
@ -58,6 +58,7 @@ char *str;
|
||||
* ever convert will be 2^32-1, which is 10
|
||||
* digits.
|
||||
*/
|
||||
_Static_assert(sizeof(int) <= 4, "buffer too small for this sized int");
|
||||
|
||||
char *itoa(val)
|
||||
|
||||
|
@ -27,7 +27,7 @@ default:\
|
||||
:copyright=/etc/COPYRIGHT:\
|
||||
:welcome=/etc/motd:\
|
||||
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\
|
||||
:path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin ~/bin:\
|
||||
:path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ~/bin:\
|
||||
:nologin=/var/run/nologin:\
|
||||
:cputime=unlimited:\
|
||||
:datasize=unlimited:\
|
||||
|
@ -7,7 +7,7 @@ operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
|
||||
bin:*:3:7::0:0:Binaries Commands and Source:/:/usr/sbin/nologin
|
||||
tty:*:4:65533::0:0:Tty Sandbox:/:/usr/sbin/nologin
|
||||
kmem:*:5:65533::0:0:KMem Sandbox:/:/usr/sbin/nologin
|
||||
games:*:7:13::0:0:Games pseudo-user:/usr/games:/usr/sbin/nologin
|
||||
games:*:7:13::0:0:Games pseudo-user:/:/usr/sbin/nologin
|
||||
news:*:8:8::0:0:News Subsystem:/:/usr/sbin/nologin
|
||||
man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/usr/sbin/nologin
|
||||
sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
|
||||
|
@ -21,8 +21,6 @@
|
||||
usr
|
||||
bin
|
||||
..
|
||||
games
|
||||
..
|
||||
lib
|
||||
clang
|
||||
3.6.0
|
||||
|
@ -7,8 +7,6 @@
|
||||
.
|
||||
bin
|
||||
..
|
||||
games
|
||||
..
|
||||
include
|
||||
..
|
||||
lib
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: LOGIN
|
||||
# REQUIRE: DAEMON utx
|
||||
# REQUIRE: DAEMON
|
||||
|
||||
# This is a dummy dependency to ensure user services such as xdm,
|
||||
# inetd, cron and kerberos are started after everything else, in case
|
||||
|
@ -6,7 +6,7 @@
|
||||
# PROVIDE: NETWORKING NETWORK
|
||||
# REQUIRE: netif netoptions routing ppp ipfw stf
|
||||
# REQUIRE: defaultroute routed route6d mroute6d resolv bridge
|
||||
# REQUIRE: static_arp static_ndp local_unbound
|
||||
# REQUIRE: static_arp static_ndp
|
||||
|
||||
# This is a dummy dependency, for services which require networking
|
||||
# to be operational before starting.
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
# PROVIDE: local_unbound
|
||||
# REQUIRE: FILESYSTEMS netif resolv
|
||||
# BEFORE: NETWORKING
|
||||
# KEYWORD: shutdown
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -252,5 +252,8 @@ netif_common()
|
||||
debug "The following interfaces were not configured: $_fail"
|
||||
}
|
||||
|
||||
# Load the old "network" config file also for compatibility.
|
||||
# This is needed for mfsBSD at least.
|
||||
load_rc_config network
|
||||
load_rc_config $name
|
||||
run_rc_command $*
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
# PROVIDE: utx
|
||||
# REQUIRE: DAEMON FILESYSTEMS
|
||||
# BEFORE: LOGIN
|
||||
# KEYWORD: shutdown
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -15,7 +15,7 @@ alias ll ls -lAF
|
||||
# A righteous umask
|
||||
umask 22
|
||||
|
||||
set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)
|
||||
set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin)
|
||||
|
||||
setenv EDITOR vi
|
||||
setenv PAGER more
|
||||
|
@ -6,4 +6,4 @@
|
||||
#
|
||||
|
||||
# Uncomment to display a random cookie each login:
|
||||
# if ( -x /usr/games/fortune ) /usr/games/fortune -s
|
||||
# if ( -x /usr/bin/fortune ) /usr/bin/fortune -s
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:~/bin
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:~/bin
|
||||
export PATH
|
||||
HOME=/root
|
||||
export HOME
|
||||
|
@ -1,7 +1,6 @@
|
||||
# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93
|
||||
# $FreeBSD$
|
||||
|
||||
BINDIR?= /usr/games
|
||||
BINDIR?= /usr/bin
|
||||
FILESDIR?= ${SHAREDIR}/games
|
||||
WARNS?= 6
|
||||
DISTRIBUTION?= games
|
||||
|
@ -30,4 +30,4 @@
|
||||
# @(#)rot13.sh 8.1 (Berkeley) 5/31/93
|
||||
# $FreeBSD$
|
||||
|
||||
exec /usr/games/caesar 13 "$@"
|
||||
exec /usr/bin/caesar 13 "$@"
|
||||
|
@ -15,7 +15,7 @@ FILESDIR= ${SHAREDIR}/games/fortune
|
||||
|
||||
.for f in ${DB}
|
||||
$f.dat: $f
|
||||
PATH=$$PATH:/usr/games:${.OBJDIR}/../strfile \
|
||||
PATH=$$PATH:/usr/bin:${.OBJDIR}/../strfile \
|
||||
strfile -Cs ${.ALLSRC} ${.TARGET}
|
||||
.endfor
|
||||
|
||||
|
@ -443,7 +443,7 @@ on this system. Example entries are in
|
||||
%
|
||||
You can use "pkg info" to see a list of packages you have installed.
|
||||
%
|
||||
You can use the 'fetch' command to retrieve files over ftp or http.
|
||||
You can use the 'fetch' command to retrieve files over ftp, http or https.
|
||||
|
||||
fetch http://www.FreeBSD.org/index.html
|
||||
|
||||
|
@ -166,7 +166,7 @@ __END_DECLS
|
||||
#define __SRW 0x0010 /* open for reading & writing */
|
||||
#define __SEOF 0x0020 /* found EOF */
|
||||
#define __SERR 0x0040 /* found error */
|
||||
#define __SMBF 0x0080 /* _buf is from malloc */
|
||||
#define __SMBF 0x0080 /* _bf._base is from malloc */
|
||||
#define __SAPP 0x0100 /* fdopen()ed in append mode */
|
||||
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
|
||||
#define __SOPT 0x0400 /* do fseek() optimization */
|
||||
|
@ -284,6 +284,12 @@ _libsmb= libsmb
|
||||
_libsmb= libsmb
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "arm"
|
||||
_libsmb= libsmb
|
||||
_libproc= libproc
|
||||
_librtld_db= librtld_db
|
||||
.endif
|
||||
|
||||
.if ${MK_OPENSSL} != "no"
|
||||
_libmp= libmp
|
||||
.endif
|
||||
|
@ -33,51 +33,48 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
|
||||
#include "spinlock.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
long _atomic_lock_stub(volatile long *);
|
||||
void _spinlock_stub(spinlock_t *);
|
||||
void _spinunlock_stub(spinlock_t *);
|
||||
void _spinlock_debug_stub(spinlock_t *, char *, int);
|
||||
|
||||
/*
|
||||
* Declare weak definitions in case the application is not linked
|
||||
* with libpthread.
|
||||
*/
|
||||
__weak_reference(_atomic_lock_stub, _atomic_lock);
|
||||
__weak_reference(_spinlock_stub, _spinlock);
|
||||
__weak_reference(_spinunlock_stub, _spinunlock);
|
||||
__weak_reference(_spinlock_debug_stub, _spinlock_debug);
|
||||
|
||||
/*
|
||||
* This function is a stub for the _atomic_lock function in libpthread.
|
||||
*/
|
||||
long
|
||||
_atomic_lock_stub(volatile long *lck __unused)
|
||||
{
|
||||
return (0L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is a stub for the spinlock function in libpthread.
|
||||
*/
|
||||
__weak_reference(_spinlock, _spinlock_debug);
|
||||
#pragma weak _spinlock
|
||||
void
|
||||
_spinlock_stub(spinlock_t *lck __unused)
|
||||
_spinlock(spinlock_t *lck)
|
||||
{
|
||||
|
||||
((void (*)(spinlock_t *lck))__libc_interposing[INTERPOS_spinlock])
|
||||
(lck);
|
||||
|
||||
}
|
||||
|
||||
#pragma weak _spinlock
|
||||
void
|
||||
_spinunlock(spinlock_t *lck)
|
||||
{
|
||||
|
||||
((void (*)(spinlock_t *lck))__libc_interposing[INTERPOS_spinunlock])
|
||||
(lck);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
__libc_spinlock_stub(spinlock_t *lck __unused)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a stub for the spinunlock function in libpthread.
|
||||
*/
|
||||
void
|
||||
_spinunlock_stub(spinlock_t *lck __unused)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a stub for the debug spinlock function in libpthread.
|
||||
*/
|
||||
void
|
||||
_spinlock_debug_stub(spinlock_t *lck __unused, char *fname __unused, int lineno __unused)
|
||||
__libc_spinunlock_stub(spinlock_t *lck __unused)
|
||||
{
|
||||
}
|
||||
|
@ -95,6 +95,9 @@ do { \
|
||||
_SPINUNLOCK(&__stdio_thread_lock); \
|
||||
} while (0)
|
||||
|
||||
void __libc_spinlock_stub(struct _spinlock *);
|
||||
void __libc_spinunlock_stub(struct _spinlock *);
|
||||
|
||||
/*
|
||||
* Indexes into the pthread jump table.
|
||||
*
|
||||
@ -216,6 +219,8 @@ enum {
|
||||
INTERPOS_write,
|
||||
INTERPOS_writev,
|
||||
INTERPOS__pthread_mutex_init_calloc_cb,
|
||||
INTERPOS_spinlock,
|
||||
INTERPOS_spinunlock,
|
||||
INTERPOS_MAX
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,7 @@ __FBSDID("$FreeBSD$");
|
||||
np->name = strdup(n); \
|
||||
np->path = NULL; \
|
||||
np->catd = NLERR; \
|
||||
np->refcount = 0; \
|
||||
np->lang = (l == NULL) ? NULL : \
|
||||
strdup(l); \
|
||||
np->caterrno = e; \
|
||||
|
@ -192,6 +192,7 @@ regcomp(regex_t * __restrict preg,
|
||||
struct parse *p = &pa;
|
||||
int i;
|
||||
size_t len;
|
||||
size_t maxlen;
|
||||
#ifdef REDEBUG
|
||||
# define GOODFLAGS(f) (f)
|
||||
#else
|
||||
@ -213,7 +214,23 @@ regcomp(regex_t * __restrict preg,
|
||||
g = (struct re_guts *)malloc(sizeof(struct re_guts));
|
||||
if (g == NULL)
|
||||
return(REG_ESPACE);
|
||||
/*
|
||||
* Limit the pattern space to avoid a 32-bit overflow on buffer
|
||||
* extension. Also avoid any signed overflow in case of conversion
|
||||
* so make the real limit based on a 31-bit overflow.
|
||||
*
|
||||
* Likely not applicable on 64-bit systems but handle the case
|
||||
* generically (who are we to stop people from using ~715MB+
|
||||
* patterns?).
|
||||
*/
|
||||
maxlen = ((size_t)-1 >> 1) / sizeof(sop) * 2 / 3;
|
||||
if (len >= maxlen) {
|
||||
free((char *)g);
|
||||
return(REG_ESPACE);
|
||||
}
|
||||
p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
|
||||
assert(p->ssize >= len);
|
||||
|
||||
p->strip = (sop *)malloc(p->ssize * sizeof(sop));
|
||||
p->slen = 0;
|
||||
if (p->strip == NULL) {
|
||||
|
@ -73,6 +73,8 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = {
|
||||
SLOT(write, __sys_write),
|
||||
SLOT(writev, __sys_writev),
|
||||
SLOT(_pthread_mutex_init_calloc_cb, _pthread_mutex_init_calloc_cb_stub),
|
||||
SLOT(spinlock, __libc_spinlock_stub),
|
||||
SLOT(spinunlock, __libc_spinunlock_stub),
|
||||
};
|
||||
#undef SLOT
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libc/iconv
|
||||
|
||||
LIB= iconv
|
||||
SHLIB_MAJOR= 4
|
||||
MAN= iconv.3 iconvctl.3 iconv_canonicalize.3 iconvlist.3 \
|
||||
__iconv_get_list.3
|
||||
MLNKS= iconv.3 iconv_open.3 \
|
||||
iconv.3 iconv_open_into.3 \
|
||||
iconv.3 iconv_close.3 \
|
||||
iconv.3 __iconv.3 \
|
||||
__iconv_get_list.3 __iconv_free_list.3
|
||||
SRCS= citrus_bcs.c citrus_bcs_strtol.c citrus_bcs_strtoul.c \
|
||||
citrus_csmapper.c citrus_db.c citrus_db_factory.c \
|
||||
citrus_db_hash.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
|
||||
|
||||
CFLAGS.gcc+= --param max-inline-insns-single=128
|
||||
CFLAGS+= -I ${.CURDIR}/../../include -I${.CURDIR}/../libc/include
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -51,6 +51,9 @@ __FBSDID("$FreeBSD$");
|
||||
#elif defined(__powerpc__)
|
||||
#define BREAKPOINT_INSTR 0x7fe00008 /* trap */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#elif defined(__arm__)
|
||||
#define BREAKPOINT_INSTR 0xe7ffffff /* bkpt */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#else
|
||||
#error "Add support for your architecture"
|
||||
#endif
|
||||
|
@ -56,6 +56,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
case REG_PC:
|
||||
#if defined(__amd64__)
|
||||
*regvalue = regs.r_rip;
|
||||
#elif defined(__arm__)
|
||||
*regvalue = regs.r_pc;
|
||||
#elif defined(__i386__)
|
||||
*regvalue = regs.r_eip;
|
||||
#elif defined(__mips__)
|
||||
@ -67,6 +69,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
case REG_SP:
|
||||
#if defined(__amd64__)
|
||||
*regvalue = regs.r_rsp;
|
||||
#elif defined(__arm__)
|
||||
*regvalue = regs.r_sp;
|
||||
#elif defined(__i386__)
|
||||
*regvalue = regs.r_esp;
|
||||
#elif defined(__mips__)
|
||||
@ -99,6 +103,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
case REG_PC:
|
||||
#if defined(__amd64__)
|
||||
regs.r_rip = regvalue;
|
||||
#elif defined(__arm__)
|
||||
regs.r_pc = regvalue;
|
||||
#elif defined(__i386__)
|
||||
regs.r_eip = regvalue;
|
||||
#elif defined(__mips__)
|
||||
@ -110,6 +116,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
case REG_SP:
|
||||
#if defined(__amd64__)
|
||||
regs.r_rsp = regvalue;
|
||||
#elif defined(__arm__)
|
||||
regs.r_sp = regvalue;
|
||||
#elif defined(__i386__)
|
||||
regs.r_esp = regvalue;
|
||||
#elif defined(__mips__)
|
||||
|
@ -82,6 +82,21 @@ fail:
|
||||
strlcpy(buf, symbol, len);
|
||||
}
|
||||
|
||||
static int
|
||||
find_dbg_obj(const char *path)
|
||||
{
|
||||
int fd;
|
||||
char dbg_path[PATH_MAX];
|
||||
|
||||
snprintf(dbg_path, sizeof(dbg_path),
|
||||
"/usr/lib/debug/%s.debug", path);
|
||||
fd = open(dbg_path, O_RDONLY);
|
||||
if (fd > 0)
|
||||
return (fd);
|
||||
else
|
||||
return (open(path, O_RDONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
proc_rdl2prmap(rd_loadobj_t *rdl, prmap_t *map)
|
||||
{
|
||||
@ -295,7 +310,7 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name,
|
||||
|
||||
if ((map = proc_addr2map(p, addr)) == NULL)
|
||||
return (-1);
|
||||
if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) {
|
||||
if ((fd = find_dbg_obj(map->pr_mapname)) < 0) {
|
||||
DPRINTF("ERROR: open %s failed", map->pr_mapname);
|
||||
goto err0;
|
||||
}
|
||||
@ -443,7 +458,7 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
|
||||
DPRINTFX("ERROR: couldn't find object %s", object);
|
||||
goto err0;
|
||||
}
|
||||
if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) {
|
||||
if ((fd = find_dbg_obj(map->pr_mapname)) < 0) {
|
||||
DPRINTF("ERROR: open %s failed", map->pr_mapname);
|
||||
goto err0;
|
||||
}
|
||||
@ -539,7 +554,7 @@ 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) {
|
||||
if ((fd = find_dbg_obj(map->pr_mapname)) < 0) {
|
||||
DPRINTF("ERROR: open %s failed", map->pr_mapname);
|
||||
goto err0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 2005 Robert N. M. Watson
|
||||
.\" Copyright (c) 2014 The FreeBSD Foundation, Inc.
|
||||
.\" Copyright (c) 2014,2015 The FreeBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Part of this documentation was written by
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 26, 2014
|
||||
.Dd February 12, 2015
|
||||
.Dt LIBTHR 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -200,45 +200,25 @@ Bigger values reduce the frequency of the FIFO discipline.
|
||||
The value must be between 0 and 255.
|
||||
.El
|
||||
.Sh INTERACTION WITH RUN-TIME LINKER
|
||||
The
|
||||
On load,
|
||||
.Nm
|
||||
library must appear before
|
||||
.Li libc
|
||||
in the global order of depended objects.
|
||||
.Pp
|
||||
Loading
|
||||
.Nm
|
||||
with the
|
||||
.Xr dlopen 3
|
||||
call in the process after the program binary is activated
|
||||
is not supported, and causes miscellaneous and hard-to-diagnose misbehaviour.
|
||||
This is due to
|
||||
.Nm
|
||||
interposing several important
|
||||
.Li libc
|
||||
symbols to provide thread-safe services.
|
||||
In particular,
|
||||
.Dv errno
|
||||
and the locking stubs from
|
||||
.Li libc
|
||||
are affected.
|
||||
This requirement is currently not enforced.
|
||||
.Pp
|
||||
If the program loads any modules at run-time, and those modules may require
|
||||
threading services, the main program binary must be linked with
|
||||
.Li libpthread ,
|
||||
even if it does not require any services from the library.
|
||||
installs interposing handlers into the hooks exported by
|
||||
.Li libc .
|
||||
The interposers provide real locking implementation instead of the
|
||||
stubs for single-threaded processes in
|
||||
.Li ,
|
||||
cancellation support and some modifications to the signal operations.
|
||||
.Pp
|
||||
.Nm
|
||||
cannot be unloaded; the
|
||||
.Xr dlclose 3
|
||||
function does not perform any action when called with a handle for
|
||||
.Nm .
|
||||
One of the reasons is that the interposing of
|
||||
One of the reasons is that the internal interposing of
|
||||
.Li libc
|
||||
functions cannot be undone.
|
||||
.Sh SIGNALS
|
||||
The implementation also interposes the user-installed
|
||||
The implementation interposes the user-installed
|
||||
.Xr signal 3
|
||||
handlers.
|
||||
This interposing is done to postpone signal delivery to threads which
|
||||
|
@ -928,6 +928,10 @@ int __thr_sigwait(const sigset_t *set, int *sig);
|
||||
int __thr_sigwaitinfo(const sigset_t *set, siginfo_t *info);
|
||||
int __thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
|
||||
|
||||
struct _spinlock;
|
||||
void __thr_spinunlock(struct _spinlock *lck);
|
||||
void __thr_spinlock(struct _spinlock *lck);
|
||||
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
|
||||
|
@ -61,7 +61,7 @@ static void init_spinlock(spinlock_t *lck);
|
||||
*/
|
||||
|
||||
void
|
||||
_spinunlock(spinlock_t *lck)
|
||||
__thr_spinunlock(spinlock_t *lck)
|
||||
{
|
||||
struct spinlock_extra *_extra;
|
||||
|
||||
@ -70,7 +70,7 @@ _spinunlock(spinlock_t *lck)
|
||||
}
|
||||
|
||||
void
|
||||
_spinlock(spinlock_t *lck)
|
||||
__thr_spinlock(spinlock_t *lck)
|
||||
{
|
||||
struct spinlock_extra *_extra;
|
||||
|
||||
@ -84,12 +84,6 @@ _spinlock(spinlock_t *lck)
|
||||
THR_UMUTEX_LOCK(_get_curthread(), &_extra->lock);
|
||||
}
|
||||
|
||||
void
|
||||
_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused)
|
||||
{
|
||||
_spinlock(lck);
|
||||
}
|
||||
|
||||
static void
|
||||
init_spinlock(spinlock_t *lck)
|
||||
{
|
||||
|
@ -597,6 +597,8 @@ __thr_interpose_libc(void)
|
||||
SLOT(wait4);
|
||||
SLOT(write);
|
||||
SLOT(writev);
|
||||
SLOT(spinlock);
|
||||
SLOT(spinunlock);
|
||||
#undef SLOT
|
||||
*(__libc_interposing_slot(
|
||||
INTERPOS__pthread_mutex_init_calloc_cb)) =
|
||||
|
@ -13,7 +13,6 @@ desc_base="Base system (MANDATORY)"
|
||||
desc_kernel="Kernel (MANDATORY)"
|
||||
desc_doc="Additional documentation"
|
||||
doc_default=off
|
||||
desc_games="Games (fortune, etc.)"
|
||||
desc_lib32="32-bit compatibility libraries"
|
||||
desc_ports="Ports tree"
|
||||
desc_src="System source code"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#-
|
||||
# Copyright (c) 2014 The FreeBSD Foundation
|
||||
# Copyright (c) 2014, 2015 The FreeBSD Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# This software was developed by Glen Barber under sponsorship
|
||||
@ -40,6 +40,7 @@ usage() {
|
||||
|
||||
main() {
|
||||
local arg
|
||||
VMCONFIG="/dev/null"
|
||||
while getopts "C:c:d:f:i:o:s:S:" arg; do
|
||||
case "${arg}" in
|
||||
C)
|
||||
@ -76,10 +77,9 @@ main() {
|
||||
-z "${WORLDDIR}" -o \
|
||||
-z "${DESTDIR}" -o \
|
||||
-z "${VMSIZE}" -o \
|
||||
-z "${VMIMAGE}" -o \
|
||||
-z "${VMCONFIG}" ];
|
||||
-z "${VMIMAGE}" ];
|
||||
then
|
||||
usage
|
||||
usage || exit 0
|
||||
fi
|
||||
|
||||
if [ -z "${VMBUILDCONF}" ] || [ ! -e "${VMBUILDCONF}" ]; then
|
||||
@ -89,7 +89,7 @@ main() {
|
||||
|
||||
. "${VMBUILDCONF}"
|
||||
|
||||
if [ ! -z "${VMCONFIG}" ] && [ -e "${VMCONFIG}" ]; then
|
||||
if [ ! -z "${VMCONFIG}" ] && [ ! -c "${VMCONFIG}" ]; then
|
||||
. "${VMCONFIG}"
|
||||
fi
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 13, 2012
|
||||
.Dd February 12, 2015
|
||||
.Dt SYSCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -37,11 +37,13 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl bdehiNnoRTqx
|
||||
.Op Fl B Ar bufsize
|
||||
.Op Fl f Ar filename
|
||||
.Ar name Ns Op = Ns Ar value
|
||||
.Ar ...
|
||||
.Nm
|
||||
.Op Fl bdehNnoRTqx
|
||||
.Op Fl B Ar bufsize
|
||||
.Fl a
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@ -68,6 +70,15 @@ the command line.
|
||||
Force the value of the variable(s) to be output in raw, binary format.
|
||||
No names are printed and no terminating newlines are output.
|
||||
This is mostly useful with a single variable.
|
||||
.It Fl B Ar bufsize
|
||||
Set the buffer size to read from the
|
||||
.Nm
|
||||
to
|
||||
.Ar bufsize .
|
||||
This is necessary for a
|
||||
.Nm
|
||||
that has variable length, and the probe value of 0 is a valid length, such as
|
||||
.Va kern.arandom .
|
||||
.It Fl d
|
||||
Print the description of the variable instead of its value.
|
||||
.It Fl e
|
||||
@ -128,7 +139,7 @@ Suppress some warnings generated by
|
||||
.Nm
|
||||
to standard error.
|
||||
.It Fl T
|
||||
Display only variables that are setable via loader (CTLFLAG_TUN).
|
||||
Display only variables that are settable via loader (CTLFLAG_TUN).
|
||||
.It Fl W
|
||||
Display only writable variables that are not statistical.
|
||||
Useful for determining the set of runtime tunable sysctls.
|
||||
|
@ -71,7 +71,7 @@ static const char rcsid[] =
|
||||
|
||||
static const char *conffile;
|
||||
|
||||
static int aflag, bflag, dflag, eflag, hflag, iflag;
|
||||
static int aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
|
||||
static int Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag;
|
||||
|
||||
static int oidfmt(int *, int, char *, u_int *);
|
||||
@ -112,8 +112,8 @@ usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s\n%s\n",
|
||||
"usage: sysctl [-bdehiNnoqTWx] [-f filename] name[=value] ...",
|
||||
" sysctl [-bdehNnoqTWx] -a");
|
||||
"usage: sysctl [-bdehiNnoqTWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
|
||||
" sysctl [-bdehNnoqTWx] [ -B <bufsize> ] -a");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ main(int argc, char **argv)
|
||||
setbuf(stdout,0);
|
||||
setbuf(stderr,0);
|
||||
|
||||
while ((ch = getopt(argc, argv, "Aabdef:hiNnoqTwWxX")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "AabB:def:hiNnoqTwWxX")) != -1) {
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
/* compatibility */
|
||||
@ -139,6 +139,9 @@ main(int argc, char **argv)
|
||||
case 'b':
|
||||
bflag = 1;
|
||||
break;
|
||||
case 'B':
|
||||
Bflag = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
@ -222,7 +225,7 @@ parse(const char *string, int lineno)
|
||||
unsigned int uintval;
|
||||
long longval;
|
||||
unsigned long ulongval;
|
||||
size_t newsize = 0;
|
||||
size_t newsize = Bflag;
|
||||
int64_t i64val;
|
||||
uint64_t u64val;
|
||||
int mib[CTL_MAXNAME];
|
||||
@ -815,9 +818,13 @@ show_var(int *oid, int nlen)
|
||||
return (0);
|
||||
}
|
||||
/* find an estimate of how much we need for this var */
|
||||
j = 0;
|
||||
i = sysctl(oid, nlen, 0, &j, 0, 0);
|
||||
j += j; /* we want to be sure :-) */
|
||||
if (Bflag)
|
||||
j = Bflag;
|
||||
else {
|
||||
j = 0;
|
||||
i = sysctl(oid, nlen, 0, &j, 0, 0);
|
||||
j += j; /* we want to be sure :-) */
|
||||
}
|
||||
|
||||
val = oval = malloc(j + 1);
|
||||
if (val == NULL) {
|
||||
|
@ -1,22 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $FreeBSD$
|
||||
|
||||
NO_OBJ=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
beforeinstall:
|
||||
.if !exists(${DESTDIR}${INFODIR})
|
||||
@echo "Warning: the directory ${DESTDIR}${INFODIR} does not exist!"
|
||||
@echo "Perhaps the variable INFODIR is set incorrectly"
|
||||
@echo "or your mtree database files are broken."
|
||||
@echo ""
|
||||
@echo "As a workaround you can create the directory by hand, e.g.:"
|
||||
@echo -n "install -d -o ${INFOOWN} -g ${INFOGRP} "
|
||||
@echo "-m 0755 ${DESTDIR}${INFODIR}"
|
||||
@exit 3;
|
||||
.endif
|
||||
.if !exists(${DESTDIR}${INFODIR}/dir)
|
||||
${INSTALL} -o ${INFOOWN} -g ${INFOGRP} -m 644 \
|
||||
dir-tmpl ${DESTDIR}${INFODIR}/dir
|
||||
.endif
|
@ -1,16 +0,0 @@
|
||||
-*- Text -*-
|
||||
This is the file .../info/dir, which contains the
|
||||
topmost node of the Info hierarchy, called (dir)Top.
|
||||
The first time you invoke Info you start off looking at this node.
|
||||
|
||||
File: dir, Node: Top This is the top of the INFO tree
|
||||
|
||||
This (the Directory node) gives a menu of major topics.
|
||||
Typing "q" exits, "?" lists all Info commands, "d" returns here,
|
||||
"h" gives a primer for first-timers,
|
||||
"mEmacs<Return>" visits the Emacs manual, etc.
|
||||
|
||||
In Emacs, you can click mouse button 2 on a menu item or cross reference
|
||||
to select it.
|
||||
|
||||
* Menu:
|
@ -170,7 +170,7 @@ flashes
|
||||
.Pp
|
||||
.Dl *_*__**_
|
||||
.Bd -literal
|
||||
/usr/games/morse -l "Soekris rocks" > /dev/led/error
|
||||
/usr/bin/morse -l "Soekris rocks" > /dev/led/error
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr morse 6
|
||||
|
@ -42,7 +42,7 @@ if_ral_load="YES"
|
||||
The
|
||||
.Nm
|
||||
driver supports PCI/PCIe/CardBus wireless adapters based on the Ralink RT2500,
|
||||
RT2501, RT2600, RT2700, RT2800 and RT3090 chipsets.
|
||||
RT2501, RT2600, RT2700, RT2800, RT3090 and RT3900E chipsets.
|
||||
.Pp
|
||||
The RT2500 chipset is the first generation of 802.11b/g adapters from Ralink.
|
||||
It consists of two integrated chips, an RT2560 MAC/BBP and an RT2525 radio
|
||||
@ -104,6 +104,13 @@ interfaces may be operated together with a
|
||||
.Cm hostap
|
||||
interface to construct a wireless repeater device.
|
||||
.Pp
|
||||
The RT3900E chipset is a single-chip 802.11n adapters from Ralink.
|
||||
The MAC/Baseband Processor can be an RT5390 or RT5392.
|
||||
The RT5390 chip operates in the 2GHz spectrum and supports 1 transmit path
|
||||
and 1 receiver path (1T1R).
|
||||
The RT5392 chip operates in the 2GHz spectrum and supports up to 2 transmit
|
||||
paths and 2 receiver paths (2T2R).
|
||||
.Pp
|
||||
The transmit speed is user-selectable or can be adapted automatically by the
|
||||
driver depending on the number of hardware transmission retries.
|
||||
For more information on configuring this device, see
|
||||
@ -142,6 +149,7 @@ chipsets, including:
|
||||
.It "Compex WLP54G" Ta RT2560 Ta PCI
|
||||
.It "Conceptronic C54RC" Ta RT2560 Ta CardBus
|
||||
.It "Conceptronic C54Ri" Ta RT2560 Ta PCI
|
||||
.It "D-Link DWA-525 rev A2" Ta RT5392 Ta PCI
|
||||
.It "Digitus DN-7001G-RA" Ta RT2560 Ta CardBus
|
||||
.It "Digitus DN-7006G-RA" Ta RT2560 Ta PCI
|
||||
.It "E-Tech WGPC02" Ta RT2560 Ta CardBus
|
||||
|
@ -24,15 +24,14 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 5, 2008
|
||||
.Dd February 10, 2015
|
||||
.Dt NULLFS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm nullfs
|
||||
.Nd "null file system"
|
||||
.Sh SYNOPSIS
|
||||
To enable support for
|
||||
.Nm ,
|
||||
To enable support for this driver,
|
||||
place the following line in the kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "options NULLFS"
|
||||
|
@ -37,7 +37,7 @@
|
||||
This section contains information about games.
|
||||
The games
|
||||
are located in
|
||||
.Pa /usr/games
|
||||
.Pa /usr/bin
|
||||
if installed.
|
||||
You can get a short overview about all the games with the
|
||||
command:
|
||||
@ -45,13 +45,18 @@ command:
|
||||
$ apropos '\\(6\\)'
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/games -compact
|
||||
.It Pa /usr/games
|
||||
.Bl -tag -width /usr/bin -compact
|
||||
.It Pa /usr/bin
|
||||
location of games
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr intro 1
|
||||
.Sh HISTORY
|
||||
In earlier versions of
|
||||
.Fx ,
|
||||
games were located in
|
||||
.Pa /usr/games .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
section manual page appeared in
|
||||
|
@ -187,8 +187,6 @@ common utilities, programming tools, and applications
|
||||
.It Pa compat/
|
||||
files needed to support binary compatibility with other operating systems,
|
||||
such as Linux
|
||||
.It Pa games/
|
||||
useful and semi-frivolous programs
|
||||
.It Pa include/
|
||||
standard C include files
|
||||
.Pp
|
||||
|
@ -286,7 +286,7 @@ _EXTRADEPEND:
|
||||
mv $$TMP ${DEPENDFILE}
|
||||
.if !defined(NO_EXTRADEPEND) && defined(SHLIB_NAME)
|
||||
.if defined(DPADD) && !empty(DPADD)
|
||||
echo ${SHLIB_NAME}: ${DPADD} >> ${DEPENDFILE}
|
||||
echo ${SHLIB_NAME_FULL}: ${DPADD} >> ${DEPENDFILE}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
|
@ -62,7 +62,7 @@ PROG_FULL=${PROG}.full
|
||||
${BINDIR} == "/bin" ||\
|
||||
${BINDIR} == "/libexec" ||\
|
||||
${BINDIR} == "/sbin" ||\
|
||||
${BINDIR:C%/usr/(bin|bsdinstall|games|libexec|lpr|sendmail|sm.bin|sbin)(/.*)?%/usr/bin%} == "/usr/bin"\
|
||||
${BINDIR:C%/usr/(bin|bsdinstall|libexec|lpr|sendmail|sm.bin|sbin)(/.*)?%/usr/bin%} == "/usr/bin"\
|
||||
)
|
||||
DEBUGFILEDIR= ${DEBUGDIR}${BINDIR}
|
||||
.else
|
||||
@ -168,15 +168,15 @@ CLEANFILES+= ${OBJS}
|
||||
_EXTRADEPEND:
|
||||
.if defined(LDFLAGS) && !empty(LDFLAGS:M-nostdlib)
|
||||
.if defined(DPADD) && !empty(DPADD)
|
||||
echo ${PROG}: ${DPADD} >> ${DEPENDFILE}
|
||||
echo ${PROG_FULL}: ${DPADD} >> ${DEPENDFILE}
|
||||
.endif
|
||||
.else
|
||||
echo ${PROG}: ${LIBC} ${DPADD} >> ${DEPENDFILE}
|
||||
echo ${PROG_FULL}: ${LIBC} ${DPADD} >> ${DEPENDFILE}
|
||||
.if defined(PROG_CXX)
|
||||
.if ${COMPILER_TYPE} == "clang" && empty(CXXFLAGS:M-stdlib=libstdc++)
|
||||
echo ${PROG}: ${LIBCPLUSPLUS} >> ${DEPENDFILE}
|
||||
echo ${PROG_FULL}: ${LIBCPLUSPLUS} >> ${DEPENDFILE}
|
||||
.else
|
||||
echo ${PROG}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE}
|
||||
echo ${PROG_FULL}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
@ -14,7 +14,7 @@ alias ll ls -lAF
|
||||
|
||||
# These are normally set through /etc/login.conf. You may override them here
|
||||
# if wanted.
|
||||
# set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)
|
||||
# set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin)
|
||||
# setenv BLOCKSIZE K
|
||||
# A righteous umask
|
||||
# umask 22
|
||||
|
@ -5,4 +5,4 @@
|
||||
# see also csh(1), environ(7).
|
||||
#
|
||||
|
||||
if ( -x /usr/games/fortune ) /usr/games/fortune freebsd-tips
|
||||
if ( -x /usr/bin/fortune ) /usr/bin/fortune freebsd-tips
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
# These are normally set through /etc/login.conf. You may override them here
|
||||
# if wanted.
|
||||
# PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:$HOME/bin; export PATH
|
||||
# PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin; export PATH
|
||||
# BLOCKSIZE=K; export BLOCKSIZE
|
||||
|
||||
# Setting TERM is normally done through /etc/ttys. Do only override
|
||||
@ -21,4 +21,4 @@ PAGER=more; export PAGER
|
||||
# set ENV to a file invoked each time sh is started for interactive use.
|
||||
ENV=$HOME/.shrc; export ENV
|
||||
|
||||
if [ -x /usr/games/fortune ] ; then /usr/games/fortune freebsd-tips ; fi
|
||||
if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune freebsd-tips ; fi
|
||||
|
@ -250,6 +250,26 @@ static const struct inst db_inst_0f0x[] = {
|
||||
/*0f*/ { "", FALSE, NONE, 0, 0 },
|
||||
};
|
||||
|
||||
static const struct inst db_inst_0f1x[] = {
|
||||
/*10*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*11*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*12*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*13*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*14*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*15*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*16*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*17*/ { "", FALSE, NONE, 0, 0 },
|
||||
|
||||
/*18*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*19*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1a*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1b*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1c*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1d*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1e*/ { "", FALSE, NONE, 0, 0 },
|
||||
/*1f*/ { "nopl", TRUE, SDEP, 0, "nopw" },
|
||||
};
|
||||
|
||||
static const struct inst db_inst_0f2x[] = {
|
||||
/*20*/ { "mov", TRUE, LONG, op2(CR,El), 0 },
|
||||
/*21*/ { "mov", TRUE, LONG, op2(DR,El), 0 },
|
||||
@ -431,7 +451,7 @@ static const struct inst db_inst_0fcx[] = {
|
||||
|
||||
static const struct inst * const db_inst_0f[] = {
|
||||
db_inst_0f0x,
|
||||
0,
|
||||
db_inst_0f1x,
|
||||
db_inst_0f2x,
|
||||
db_inst_0f3x,
|
||||
db_inst_0f4x,
|
||||
|
@ -837,6 +837,11 @@ u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */
|
||||
defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
|
||||
defined(CPU_CORTEXA) || defined(CPU_KRAIT)
|
||||
|
||||
/* Global cache line sizes, use 32 as default */
|
||||
int arm_dcache_min_line_size = 32;
|
||||
int arm_icache_min_line_size = 32;
|
||||
int arm_idcache_min_line_size = 32;
|
||||
|
||||
static void get_cachetype_cp15(void);
|
||||
|
||||
/* Additional cache information local to this file. Log2 of some of the
|
||||
@ -868,6 +873,12 @@ get_cachetype_cp15()
|
||||
goto out;
|
||||
|
||||
if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
|
||||
/* Resolve minimal cache line sizes */
|
||||
arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2);
|
||||
arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2);
|
||||
arm_idcache_min_line_size =
|
||||
min(arm_icache_min_line_size, arm_dcache_min_line_size);
|
||||
|
||||
__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
|
||||
: "=r" (clevel));
|
||||
arm_cache_level = clevel;
|
||||
|
@ -41,6 +41,12 @@ __FBSDID("$FreeBSD$");
|
||||
.word _C_LABEL(arm_cache_loc)
|
||||
.Lcache_type:
|
||||
.word _C_LABEL(arm_cache_type)
|
||||
.Larmv7_dcache_line_size:
|
||||
.word _C_LABEL(arm_dcache_min_line_size)
|
||||
.Larmv7_icache_line_size:
|
||||
.word _C_LABEL(arm_icache_min_line_size)
|
||||
.Larmv7_idcache_line_size:
|
||||
.word _C_LABEL(arm_idcache_min_line_size)
|
||||
.Lway_mask:
|
||||
.word 0x3ff
|
||||
.Lmax_index:
|
||||
@ -180,14 +186,9 @@ ENTRY(armv7_idcache_wbinv_all)
|
||||
RET
|
||||
END(armv7_idcache_wbinv_all)
|
||||
|
||||
/* XXX Temporary set it to 32 for MV cores, however this value should be
|
||||
* get from Cache Type register
|
||||
*/
|
||||
.Larmv7_line_size:
|
||||
.word 32
|
||||
|
||||
ENTRY(armv7_dcache_wb_range)
|
||||
ldr ip, .Larmv7_line_size
|
||||
ldr ip, .Larmv7_dcache_line_size
|
||||
ldr ip, [ip]
|
||||
sub r3, ip, #1
|
||||
and r2, r0, r3
|
||||
add r1, r1, r2
|
||||
@ -202,7 +203,8 @@ ENTRY(armv7_dcache_wb_range)
|
||||
END(armv7_dcache_wb_range)
|
||||
|
||||
ENTRY(armv7_dcache_wbinv_range)
|
||||
ldr ip, .Larmv7_line_size
|
||||
ldr ip, .Larmv7_dcache_line_size
|
||||
ldr ip, [ip]
|
||||
sub r3, ip, #1
|
||||
and r2, r0, r3
|
||||
add r1, r1, r2
|
||||
@ -221,7 +223,8 @@ END(armv7_dcache_wbinv_range)
|
||||
* must use wb-inv of the entire cache.
|
||||
*/
|
||||
ENTRY(armv7_dcache_inv_range)
|
||||
ldr ip, .Larmv7_line_size
|
||||
ldr ip, .Larmv7_dcache_line_size
|
||||
ldr ip, [ip]
|
||||
sub r3, ip, #1
|
||||
and r2, r0, r3
|
||||
add r1, r1, r2
|
||||
@ -236,7 +239,8 @@ ENTRY(armv7_dcache_inv_range)
|
||||
END(armv7_dcache_inv_range)
|
||||
|
||||
ENTRY(armv7_idcache_wbinv_range)
|
||||
ldr ip, .Larmv7_line_size
|
||||
ldr ip, .Larmv7_idcache_line_size
|
||||
ldr ip, [ip]
|
||||
sub r3, ip, #1
|
||||
and r2, r0, r3
|
||||
add r1, r1, r2
|
||||
@ -264,7 +268,8 @@ ENTRY_NP(armv7_icache_sync_all)
|
||||
END(armv7_icache_sync_all)
|
||||
|
||||
ENTRY_NP(armv7_icache_sync_range)
|
||||
ldr ip, .Larmv7_line_size
|
||||
ldr ip, .Larmv7_icache_line_size
|
||||
ldr ip, [ip]
|
||||
.Larmv7_sync_next:
|
||||
mcr CP15_ICIMVAU(r0)
|
||||
mcr CP15_DCCMVAC(r0)
|
||||
|
@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_output.h>
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
/*
|
||||
* Definitions for the instruction interpreter.
|
||||
*
|
||||
@ -453,131 +452,6 @@ db_stack_trace_cmd(struct unwind_state *state)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* APCS stack frames are awkward beasts, so I don't think even trying to use
|
||||
* a structure to represent them is a good idea.
|
||||
*
|
||||
* Here's the diagram from the APCS. Increasing address is _up_ the page.
|
||||
*
|
||||
* save code pointer [fp] <- fp points to here
|
||||
* return link value [fp, #-4]
|
||||
* return sp value [fp, #-8]
|
||||
* return fp value [fp, #-12]
|
||||
* [saved v7 value]
|
||||
* [saved v6 value]
|
||||
* [saved v5 value]
|
||||
* [saved v4 value]
|
||||
* [saved v3 value]
|
||||
* [saved v2 value]
|
||||
* [saved v1 value]
|
||||
* [saved a4 value]
|
||||
* [saved a3 value]
|
||||
* [saved a2 value]
|
||||
* [saved a1 value]
|
||||
*
|
||||
* The save code pointer points twelve bytes beyond the start of the
|
||||
* code sequence (usually a single STM) that created the stack frame.
|
||||
* We have to disassemble it if we want to know which of the optional
|
||||
* fields are actually present.
|
||||
*/
|
||||
|
||||
#ifndef __ARM_EABI__ /* The frame format is differend in AAPCS */
|
||||
static void
|
||||
db_stack_trace_cmd(db_expr_t addr, db_expr_t count, boolean_t kernel_only)
|
||||
{
|
||||
u_int32_t *frame, *lastframe;
|
||||
c_db_sym_t sym;
|
||||
const char *name;
|
||||
db_expr_t value;
|
||||
db_expr_t offset;
|
||||
int scp_offset;
|
||||
|
||||
frame = (u_int32_t *)addr;
|
||||
lastframe = NULL;
|
||||
scp_offset = -(get_pc_str_offset() >> 2);
|
||||
|
||||
while (count-- && frame != NULL && !db_pager_quit) {
|
||||
db_addr_t scp;
|
||||
u_int32_t savecode;
|
||||
int r;
|
||||
u_int32_t *rp;
|
||||
const char *sep;
|
||||
|
||||
/*
|
||||
* In theory, the SCP isn't guaranteed to be in the function
|
||||
* that generated the stack frame. We hope for the best.
|
||||
*/
|
||||
scp = frame[FR_SCP];
|
||||
|
||||
sym = db_search_symbol(scp, DB_STGY_ANY, &offset);
|
||||
if (sym == C_DB_SYM_NULL) {
|
||||
value = 0;
|
||||
name = "(null)";
|
||||
} else
|
||||
db_symbol_values(sym, &name, &value);
|
||||
db_printf("%s() at ", name);
|
||||
db_printsym(scp, DB_STGY_PROC);
|
||||
db_printf("\n");
|
||||
#ifdef __PROG26
|
||||
db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
|
||||
db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC);
|
||||
db_printf(")\n");
|
||||
#else
|
||||
db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
|
||||
db_printsym(frame[FR_RLV], DB_STGY_PROC);
|
||||
db_printf(")\n");
|
||||
#endif
|
||||
db_printf("\trsp=0x%08x rfp=0x%08x", frame[FR_RSP], frame[FR_RFP]);
|
||||
|
||||
savecode = ((u_int32_t *)scp)[scp_offset];
|
||||
if ((savecode & 0x0e100000) == 0x08000000) {
|
||||
/* Looks like an STM */
|
||||
rp = frame - 4;
|
||||
sep = "\n\t";
|
||||
for (r = 10; r >= 0; r--) {
|
||||
if (savecode & (1 << r)) {
|
||||
db_printf("%sr%d=0x%08x",
|
||||
sep, r, *rp--);
|
||||
sep = (frame - rp) % 4 == 2 ?
|
||||
"\n\t" : " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db_printf("\n");
|
||||
|
||||
/*
|
||||
* Switch to next frame up
|
||||
*/
|
||||
if (frame[FR_RFP] == 0)
|
||||
break; /* Top of stack */
|
||||
|
||||
lastframe = frame;
|
||||
frame = (u_int32_t *)(frame[FR_RFP]);
|
||||
|
||||
if (INKERNEL((int)frame)) {
|
||||
/* staying in kernel */
|
||||
if (frame <= lastframe) {
|
||||
db_printf("Bad frame pointer: %p\n", frame);
|
||||
break;
|
||||
}
|
||||
} else if (INKERNEL((int)lastframe)) {
|
||||
/* switch from user to kernel */
|
||||
if (kernel_only)
|
||||
break; /* kernel stack only */
|
||||
} else {
|
||||
/* in user */
|
||||
if (frame <= lastframe) {
|
||||
db_printf("Bad user frame pointer: %p\n",
|
||||
frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX stubs */
|
||||
void
|
||||
@ -600,24 +474,18 @@ db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
|
||||
int
|
||||
db_trace_thread(struct thread *thr, int count)
|
||||
{
|
||||
#ifdef __ARM_EABI__
|
||||
struct unwind_state state;
|
||||
#endif
|
||||
struct pcb *ctx;
|
||||
|
||||
if (thr != curthread) {
|
||||
ctx = kdb_thr_ctx(thr);
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
state.registers[FP] = ctx->pcb_regs.sf_r11;
|
||||
state.registers[SP] = ctx->pcb_regs.sf_sp;
|
||||
state.registers[LR] = ctx->pcb_regs.sf_lr;
|
||||
state.registers[PC] = ctx->pcb_regs.sf_pc;
|
||||
|
||||
db_stack_trace_cmd(&state);
|
||||
#else
|
||||
db_stack_trace_cmd(ctx->pcb_regs.sf_r11, -1, TRUE);
|
||||
#endif
|
||||
} else
|
||||
db_trace_self();
|
||||
return (0);
|
||||
@ -626,7 +494,6 @@ db_trace_thread(struct thread *thr, int count)
|
||||
void
|
||||
db_trace_self(void)
|
||||
{
|
||||
#ifdef __ARM_EABI__
|
||||
struct unwind_state state;
|
||||
uint32_t sp;
|
||||
|
||||
@ -639,10 +506,4 @@ db_trace_self(void)
|
||||
state.registers[PC] = (uint32_t)db_trace_self;
|
||||
|
||||
db_stack_trace_cmd(&state);
|
||||
#else
|
||||
db_addr_t addr;
|
||||
|
||||
addr = (db_addr_t)__builtin_frame_address(0);
|
||||
db_stack_trace_cmd(addr, -1, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
@ -115,6 +115,10 @@ int arm_pcache_unified;
|
||||
int arm_dcache_align;
|
||||
int arm_dcache_align_mask;
|
||||
|
||||
int arm_dcache_min_line_size = 32;
|
||||
int arm_icache_min_line_size = 32;
|
||||
int arm_idcache_min_line_size = 32;
|
||||
|
||||
u_int arm_cache_level;
|
||||
u_int arm_cache_type[14];
|
||||
u_int arm_cache_loc;
|
||||
@ -277,6 +281,13 @@ get_cachetype_cp15()
|
||||
goto out;
|
||||
|
||||
if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
|
||||
/* Resolve minimal cache line sizes */
|
||||
arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2);
|
||||
arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2);
|
||||
arm_idcache_min_line_size =
|
||||
(arm_dcache_min_line_size > arm_icache_min_line_size ?
|
||||
arm_icache_min_line_size : arm_dcache_min_line_size);
|
||||
|
||||
__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
|
||||
: "=r" (clevel));
|
||||
arm_cache_level = clevel;
|
||||
|
@ -48,11 +48,26 @@
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
#include "opt_kdtrace.h"
|
||||
#include <machine/asm.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/asmacros.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
.bss
|
||||
.align 4
|
||||
.global _C_LABEL(dtrace_invop_jump_addr)
|
||||
_C_LABEL(dtrace_invop_jump_addr):
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
.global _C_LABEL(dtrace_invop_calltrap_addr)
|
||||
_C_LABEL(dtrace_invop_calltrap_addr):
|
||||
.word 0
|
||||
.word 0
|
||||
#endif
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
|
@ -387,7 +387,7 @@ identify_arm_cpu(void)
|
||||
u_int8_t type, linesize;
|
||||
int i;
|
||||
|
||||
cpuid = cpu_id();
|
||||
cpuid = cpu_ident();
|
||||
|
||||
if (cpuid == 0) {
|
||||
printf("Processor failed probe - no CPU ID\n");
|
||||
|
@ -78,6 +78,9 @@
|
||||
* Created : 28/11/94
|
||||
*/
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
@ -427,6 +430,13 @@ dab_fatal(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
|
||||
{
|
||||
const char *mode;
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
if (!TRAP_USERMODE(tf)) {
|
||||
if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, far & FAULT_TYPE_MASK))
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
mode = TRAP_USERMODE(tf) ? "user" : "kernel";
|
||||
|
||||
disable_interrupts(PSR_I|PSR_F);
|
||||
|
@ -27,6 +27,12 @@ include "../ti/am335x/std.am335x"
|
||||
|
||||
makeoptions WITHOUT_MODULES="ahc"
|
||||
|
||||
# DTrace support
|
||||
options KDTRACE_HOOKS # Kernel DTrace hooks
|
||||
options DDB_CTF # all architectures - kernel ELF linker loads CTF data
|
||||
makeoptions WITH_CTF=1
|
||||
makeoptions MODULES_OVERRIDE="opensolaris dtrace dtrace/lockstat dtrace/profile dtrace/fbt"
|
||||
|
||||
options HZ=100
|
||||
options SCHED_4BSD # 4BSD scheduler
|
||||
options PREEMPTION # Enable kernel thread preemption
|
||||
|
@ -320,6 +320,9 @@
|
||||
#define CPU_CT_S (1U << 24) /* split cache */
|
||||
#define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */
|
||||
#define CPU_CT_FORMAT(x) ((x) >> 29)
|
||||
/* Cache type register definitions for ARM v7 */
|
||||
#define CPU_CT_IMINLINE(x) ((x) & 0xf) /* I$ min line size */
|
||||
#define CPU_CT_DMINLINE(x) (((x) >> 16) & 0xf) /* D$ min line size */
|
||||
|
||||
#define CPU_CT_CTYPE_WT 0 /* write-through */
|
||||
#define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */
|
||||
|
@ -175,7 +175,7 @@ struct cpu_functions {
|
||||
extern struct cpu_functions cpufuncs;
|
||||
extern u_int cputype;
|
||||
|
||||
#define cpu_id() cpufuncs.cf_id()
|
||||
#define cpu_ident() cpufuncs.cf_id()
|
||||
#define cpu_cpwait() cpufuncs.cf_cpwait()
|
||||
|
||||
#define cpu_control(c, e) cpufuncs.cf_control(c, e)
|
||||
|
@ -285,7 +285,7 @@ unit2npeid(int unit)
|
||||
};
|
||||
/* XXX check feature register instead */
|
||||
return (unit < 3 ? npeidmap[
|
||||
(cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435][unit] : -1);
|
||||
(cpu_ident() & CPU_ID_CPU_MASK) == CPU_ID_IXP435][unit] : -1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -74,7 +74,7 @@ board_init(void)
|
||||
{
|
||||
struct board_config **pbp;
|
||||
|
||||
cputype = cpu_id() & CPU_ID_CPU_MASK;
|
||||
cputype = cpu_ident() & CPU_ID_CPU_MASK;
|
||||
|
||||
SET_FOREACH(pbp, boards)
|
||||
/* XXX pass down redboot board type */
|
||||
|
@ -92,6 +92,7 @@ boot2.out: ${BTXCRT} boot2.o sio.o
|
||||
${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
|
||||
|
||||
boot2.o: boot2.s
|
||||
${CC} ${ACFLAGS} -c boot2.s
|
||||
|
||||
SRCS= boot2.c boot2.h
|
||||
|
||||
|
@ -4483,6 +4483,8 @@ ctl_init_log_page_index(struct ctl_lun *lun)
|
||||
lun->log_pages.index[1].page_len = k * 2;
|
||||
lun->log_pages.index[2].page_data = &lun->log_pages.lbp_page[0];
|
||||
lun->log_pages.index[2].page_len = 12*CTL_NUM_LBP_PARAMS;
|
||||
lun->log_pages.index[3].page_data = (uint8_t *)&lun->log_pages.stat_page;
|
||||
lun->log_pages.index[3].page_len = sizeof(lun->log_pages.stat_page);
|
||||
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
@ -4720,6 +4722,9 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
|
||||
lun->serseq = CTL_LUN_SERSEQ_OFF;
|
||||
|
||||
lun->ctl_softc = ctl_softc;
|
||||
#ifdef CTL_TIME_IO
|
||||
lun->last_busy = getsbinuptime();
|
||||
#endif
|
||||
TAILQ_INIT(&lun->ooa_queue);
|
||||
TAILQ_INIT(&lun->blocked_queue);
|
||||
STAILQ_INIT(&lun->error_list);
|
||||
@ -7084,6 +7089,67 @@ ctl_lbp_log_sense_handler(struct ctl_scsiio *ctsio,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_sap_log_sense_handler(struct ctl_scsiio *ctsio,
|
||||
struct ctl_page_index *page_index,
|
||||
int pc)
|
||||
{
|
||||
struct ctl_lun *lun;
|
||||
struct stat_page *data;
|
||||
uint64_t rn, wn, rb, wb;
|
||||
struct bintime rt, wt;
|
||||
int i;
|
||||
|
||||
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
data = (struct stat_page *)page_index->page_data;
|
||||
|
||||
scsi_ulto2b(SLP_SAP, data->sap.hdr.param_code);
|
||||
data->sap.hdr.param_control = SLP_LBIN;
|
||||
data->sap.hdr.param_len = sizeof(struct scsi_log_stat_and_perf) -
|
||||
sizeof(struct scsi_log_param_header);
|
||||
rn = wn = rb = wb = 0;
|
||||
bintime_clear(&rt);
|
||||
bintime_clear(&wt);
|
||||
for (i = 0; i < CTL_MAX_PORTS; i++) {
|
||||
rn += lun->stats.ports[i].operations[CTL_STATS_READ];
|
||||
wn += lun->stats.ports[i].operations[CTL_STATS_WRITE];
|
||||
rb += lun->stats.ports[i].bytes[CTL_STATS_READ];
|
||||
wb += lun->stats.ports[i].bytes[CTL_STATS_WRITE];
|
||||
bintime_add(&rt, &lun->stats.ports[i].time[CTL_STATS_READ]);
|
||||
bintime_add(&wt, &lun->stats.ports[i].time[CTL_STATS_WRITE]);
|
||||
}
|
||||
scsi_u64to8b(rn, data->sap.read_num);
|
||||
scsi_u64to8b(wn, data->sap.write_num);
|
||||
if (lun->stats.blocksize > 0) {
|
||||
scsi_u64to8b(wb / lun->stats.blocksize,
|
||||
data->sap.recvieved_lba);
|
||||
scsi_u64to8b(rb / lun->stats.blocksize,
|
||||
data->sap.transmitted_lba);
|
||||
}
|
||||
scsi_u64to8b((uint64_t)rt.sec * 1000 + rt.frac / (UINT64_MAX / 1000),
|
||||
data->sap.read_int);
|
||||
scsi_u64to8b((uint64_t)wt.sec * 1000 + wt.frac / (UINT64_MAX / 1000),
|
||||
data->sap.write_int);
|
||||
scsi_u64to8b(0, data->sap.weighted_num);
|
||||
scsi_u64to8b(0, data->sap.weighted_int);
|
||||
scsi_ulto2b(SLP_IT, data->it.hdr.param_code);
|
||||
data->it.hdr.param_control = SLP_LBIN;
|
||||
data->it.hdr.param_len = sizeof(struct scsi_log_idle_time) -
|
||||
sizeof(struct scsi_log_param_header);
|
||||
#ifdef CTL_TIME_IO
|
||||
scsi_u64to8b(lun->idle_time / SBT_1MS, data->it.idle_int);
|
||||
#endif
|
||||
scsi_ulto2b(SLP_TI, data->ti.hdr.param_code);
|
||||
data->it.hdr.param_control = SLP_LBIN;
|
||||
data->ti.hdr.param_len = sizeof(struct scsi_log_time_interval) -
|
||||
sizeof(struct scsi_log_param_header);
|
||||
scsi_ulto4b(3, data->ti.exponent);
|
||||
scsi_ulto4b(1, data->ti.integer);
|
||||
|
||||
page_index->page_len = sizeof(*data);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_log_sense(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
@ -11646,7 +11712,8 @@ ctl_clear_ua(struct ctl_softc *ctl_softc, uint32_t initidx,
|
||||
STAILQ_FOREACH(lun, &ctl_softc->lun_list, links) {
|
||||
mtx_lock(&lun->lun_lock);
|
||||
pu = lun->pending_ua[initidx / CTL_MAX_INIT_PER_PORT];
|
||||
pu[initidx % CTL_MAX_INIT_PER_PORT] &= ~ua_type;
|
||||
if (pu != NULL)
|
||||
pu[initidx % CTL_MAX_INIT_PER_PORT] &= ~ua_type;
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
}
|
||||
}
|
||||
@ -11689,6 +11756,12 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
|
||||
* Every I/O goes into the OOA queue for a
|
||||
* particular LUN, and stays there until completion.
|
||||
*/
|
||||
#ifdef CTL_TIME_IO
|
||||
if (TAILQ_EMPTY(&lun->ooa_queue)) {
|
||||
lun->idle_time += getsbinuptime() -
|
||||
lun->last_busy;
|
||||
}
|
||||
#endif
|
||||
TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr,
|
||||
ooa_links);
|
||||
}
|
||||
@ -12286,64 +12359,57 @@ ctl_abort_task(union ctl_io *io)
|
||||
printf("%s\n", sbuf_data(&sb));
|
||||
#endif
|
||||
|
||||
if ((xio->io_hdr.nexus.targ_port == io->io_hdr.nexus.targ_port)
|
||||
&& (xio->io_hdr.nexus.initid.id ==
|
||||
io->io_hdr.nexus.initid.id)) {
|
||||
/*
|
||||
* If the abort says that the task is untagged, the
|
||||
* task in the queue must be untagged. Otherwise,
|
||||
* we just check to see whether the tag numbers
|
||||
* match. This is because the QLogic firmware
|
||||
* doesn't pass back the tag type in an abort
|
||||
* request.
|
||||
*/
|
||||
#if 0
|
||||
if (((xio->scsiio.tag_type == CTL_TAG_UNTAGGED)
|
||||
&& (io->taskio.tag_type == CTL_TAG_UNTAGGED))
|
||||
|| (xio->scsiio.tag_num == io->taskio.tag_num)) {
|
||||
#endif
|
||||
/*
|
||||
* XXX KDM we've got problems with FC, because it
|
||||
* doesn't send down a tag type with aborts. So we
|
||||
* can only really go by the tag number...
|
||||
* This may cause problems with parallel SCSI.
|
||||
* Need to figure that out!!
|
||||
*/
|
||||
if (xio->scsiio.tag_num == io->taskio.tag_num) {
|
||||
xio->io_hdr.flags |= CTL_FLAG_ABORT;
|
||||
found = 1;
|
||||
if ((io->io_hdr.flags &
|
||||
CTL_FLAG_FROM_OTHER_SC) == 0 &&
|
||||
!(lun->flags & CTL_LUN_PRIMARY_SC)) {
|
||||
union ctl_ha_msg msg_info;
|
||||
if ((xio->io_hdr.nexus.targ_port != io->io_hdr.nexus.targ_port)
|
||||
|| (xio->io_hdr.nexus.initid.id != io->io_hdr.nexus.initid.id)
|
||||
|| (xio->io_hdr.flags & CTL_FLAG_ABORT))
|
||||
continue;
|
||||
|
||||
io->io_hdr.flags |=
|
||||
CTL_FLAG_SENT_2OTHER_SC;
|
||||
msg_info.hdr.nexus = io->io_hdr.nexus;
|
||||
msg_info.task.task_action =
|
||||
CTL_TASK_ABORT_TASK;
|
||||
msg_info.task.tag_num =
|
||||
io->taskio.tag_num;
|
||||
msg_info.task.tag_type =
|
||||
io->taskio.tag_type;
|
||||
msg_info.hdr.msg_type =
|
||||
CTL_MSG_MANAGE_TASKS;
|
||||
msg_info.hdr.original_sc = NULL;
|
||||
msg_info.hdr.serializing_sc = NULL;
|
||||
/*
|
||||
* If the abort says that the task is untagged, the
|
||||
* task in the queue must be untagged. Otherwise,
|
||||
* we just check to see whether the tag numbers
|
||||
* match. This is because the QLogic firmware
|
||||
* doesn't pass back the tag type in an abort
|
||||
* request.
|
||||
*/
|
||||
#if 0
|
||||
printf("Sent Abort to other side\n");
|
||||
if (((xio->scsiio.tag_type == CTL_TAG_UNTAGGED)
|
||||
&& (io->taskio.tag_type == CTL_TAG_UNTAGGED))
|
||||
|| (xio->scsiio.tag_num == io->taskio.tag_num)) {
|
||||
#endif
|
||||
if (CTL_HA_STATUS_SUCCESS !=
|
||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL,
|
||||
(void *)&msg_info,
|
||||
sizeof(msg_info), 0)) {
|
||||
}
|
||||
/*
|
||||
* XXX KDM we've got problems with FC, because it
|
||||
* doesn't send down a tag type with aborts. So we
|
||||
* can only really go by the tag number...
|
||||
* This may cause problems with parallel SCSI.
|
||||
* Need to figure that out!!
|
||||
*/
|
||||
if (xio->scsiio.tag_num == io->taskio.tag_num) {
|
||||
xio->io_hdr.flags |= CTL_FLAG_ABORT;
|
||||
found = 1;
|
||||
if ((io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) == 0 &&
|
||||
!(lun->flags & CTL_LUN_PRIMARY_SC)) {
|
||||
union ctl_ha_msg msg_info;
|
||||
|
||||
io->io_hdr.flags |= CTL_FLAG_SENT_2OTHER_SC;
|
||||
msg_info.hdr.nexus = io->io_hdr.nexus;
|
||||
msg_info.task.task_action = CTL_TASK_ABORT_TASK;
|
||||
msg_info.task.tag_num = io->taskio.tag_num;
|
||||
msg_info.task.tag_type = io->taskio.tag_type;
|
||||
msg_info.hdr.msg_type = CTL_MSG_MANAGE_TASKS;
|
||||
msg_info.hdr.original_sc = NULL;
|
||||
msg_info.hdr.serializing_sc = NULL;
|
||||
#if 0
|
||||
printf("Sent Abort to other side\n");
|
||||
#endif
|
||||
if (ctl_ha_msg_send(CTL_HA_CHAN_CTL,
|
||||
(void *)&msg_info, sizeof(msg_info), 0) !=
|
||||
CTL_HA_STATUS_SUCCESS) {
|
||||
}
|
||||
#if 0
|
||||
printf("ctl_abort_task: found I/O to abort\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
printf("ctl_abort_task: found I/O to abort\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
@ -13742,6 +13808,10 @@ ctl_process_done(union ctl_io *io)
|
||||
* Remove this from the OOA queue.
|
||||
*/
|
||||
TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, ooa_links);
|
||||
#ifdef CTL_TIME_IO
|
||||
if (TAILQ_EMPTY(&lun->ooa_queue))
|
||||
lun->last_busy = getsbinuptime();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Run through the blocked queue on this LUN and see if anything
|
||||
|
@ -181,6 +181,9 @@ int ctl_debugconf_sp_select_handler(struct ctl_scsiio *ctsio,
|
||||
int ctl_lbp_log_sense_handler(struct ctl_scsiio *ctsio,
|
||||
struct ctl_page_index *page_index,
|
||||
int pc);
|
||||
int ctl_sap_log_sense_handler(struct ctl_scsiio *ctsio,
|
||||
struct ctl_page_index *page_index,
|
||||
int pc);
|
||||
int ctl_config_move_done(union ctl_io *io);
|
||||
void ctl_datamove(union ctl_io *io);
|
||||
void ctl_done(union ctl_io *io);
|
||||
|
@ -1188,6 +1188,7 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
|
||||
struct ctl_be_block_softc *softc;
|
||||
struct ctl_lba_len_flags *lbalen;
|
||||
uint64_t len_left, lba;
|
||||
uint32_t pb, pbo, adj;
|
||||
int i, seglen;
|
||||
uint8_t *buf, *end;
|
||||
|
||||
@ -1241,6 +1242,11 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
|
||||
DPRINTF("WRITE SAME at LBA %jx len %u\n",
|
||||
(uintmax_t)lbalen->lba, lbalen->len);
|
||||
|
||||
pb = be_lun->blocksize << be_lun->pblockexp;
|
||||
if (be_lun->pblockoff > 0)
|
||||
pbo = pb - be_lun->blocksize * be_lun->pblockoff;
|
||||
else
|
||||
pbo = 0;
|
||||
len_left = (uint64_t)lbalen->len * be_lun->blocksize;
|
||||
for (i = 0, lba = 0; i < CTLBLK_MAX_SEGS && len_left > 0; i++) {
|
||||
|
||||
@ -1248,7 +1254,15 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
|
||||
* Setup the S/G entry for this chunk.
|
||||
*/
|
||||
seglen = MIN(CTLBLK_MAX_SEG, len_left);
|
||||
seglen -= seglen % be_lun->blocksize;
|
||||
if (pb > be_lun->blocksize) {
|
||||
adj = ((lbalen->lba + lba) * be_lun->blocksize +
|
||||
seglen - pbo) % pb;
|
||||
if (seglen > adj)
|
||||
seglen -= adj;
|
||||
else
|
||||
seglen -= seglen % be_lun->blocksize;
|
||||
} else
|
||||
seglen -= seglen % be_lun->blocksize;
|
||||
beio->sg_segs[i].len = seglen;
|
||||
beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
|
||||
|
||||
@ -1860,7 +1874,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
struct cdev *dev;
|
||||
struct cdevsw *devsw;
|
||||
char *value;
|
||||
int error, atomic, maxio;
|
||||
int error, atomic, maxio, unmap;
|
||||
off_t ps, pss, po, pos, us, uss, uo, uos;
|
||||
|
||||
params = &be_lun->params;
|
||||
@ -1885,7 +1899,6 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
maxio = CTLBLK_MAX_IO_SIZE;
|
||||
}
|
||||
be_lun->lun_flush = ctl_be_block_flush_dev;
|
||||
be_lun->unmap = ctl_be_block_unmap_dev;
|
||||
be_lun->getattr = ctl_be_block_getattr_dev;
|
||||
|
||||
error = VOP_GETATTR(be_lun->vn, &vattr, NOCRED);
|
||||
@ -2016,6 +2029,24 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
|
||||
be_lun->atomicblock = atomic / be_lun->blocksize;
|
||||
be_lun->opttxferlen = maxio / be_lun->blocksize;
|
||||
|
||||
if (be_lun->dispatch == ctl_be_block_dispatch_zvol) {
|
||||
unmap = 1;
|
||||
} else {
|
||||
struct diocgattr_arg arg;
|
||||
|
||||
strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name));
|
||||
arg.len = sizeof(arg.value.i);
|
||||
error = devsw->d_ioctl(dev, DIOCGATTR,
|
||||
(caddr_t)&arg, FREAD, curthread);
|
||||
unmap = (error == 0) ? arg.value.i : 0;
|
||||
}
|
||||
value = ctl_get_opt(&be_lun->ctl_be_lun.options, "unmap");
|
||||
if (value != NULL)
|
||||
unmap = (strcmp(value, "on") == 0);
|
||||
if (unmap)
|
||||
be_lun->unmap = ctl_be_block_unmap_dev;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -2168,7 +2199,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
|
||||
char num_thread_str[16];
|
||||
char tmpstr[32];
|
||||
char *value;
|
||||
int retval, num_threads, unmap;
|
||||
int retval, num_threads;
|
||||
int tmp_num_threads;
|
||||
|
||||
params = &req->reqdata.create;
|
||||
@ -2261,16 +2292,12 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
|
||||
}
|
||||
num_threads = tmp_num_threads;
|
||||
}
|
||||
unmap = (be_lun->dispatch == ctl_be_block_dispatch_zvol);
|
||||
value = ctl_get_opt(&be_lun->ctl_be_lun.options, "unmap");
|
||||
if (value != NULL)
|
||||
unmap = (strcmp(value, "on") == 0);
|
||||
|
||||
be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED;
|
||||
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
|
||||
if (be_lun->vn == NULL)
|
||||
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_OFFLINE;
|
||||
if (unmap)
|
||||
if (be_lun->unmap != NULL)
|
||||
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
|
||||
if (be_lun->dispatch != ctl_be_block_dispatch_dev)
|
||||
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_SERSEQ_READ;
|
||||
@ -2654,6 +2681,8 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
|
||||
* XXX: Note that this field is being updated without locking,
|
||||
* which might cause problems on 32-bit architectures.
|
||||
*/
|
||||
if (be_lun->unmap != NULL)
|
||||
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
|
||||
be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
|
||||
0 : (be_lun->size_blocks - 1);
|
||||
be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
|
||||
|
@ -588,10 +588,10 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
|
||||
be_lun->softc = softc;
|
||||
|
||||
unmap = 0;
|
||||
unmap = 1;
|
||||
value = ctl_get_opt(&be_lun->ctl_be_lun.options, "unmap");
|
||||
if (value != NULL && strcmp(value, "on") == 0)
|
||||
unmap = 1;
|
||||
unmap = (strcmp(value, "on") == 0);
|
||||
|
||||
be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
|
||||
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
|
||||
|
@ -342,6 +342,8 @@ static const struct ctl_page_index log_page_index_template[] = {
|
||||
CTL_PAGE_FLAG_NONE, NULL, NULL},
|
||||
{SLS_LOGICAL_BLOCK_PROVISIONING, 0, 0, NULL,
|
||||
CTL_PAGE_FLAG_NONE, ctl_lbp_log_sense_handler, NULL},
|
||||
{SLS_STAT_AND_PERF, 0, 0, NULL,
|
||||
CTL_PAGE_FLAG_NONE, ctl_sap_log_sense_handler, NULL},
|
||||
};
|
||||
|
||||
#define CTL_NUM_LOG_PAGES sizeof(log_page_index_template)/ \
|
||||
@ -351,6 +353,11 @@ struct ctl_log_pages {
|
||||
uint8_t pages_page[CTL_NUM_LOG_PAGES];
|
||||
uint8_t subpages_page[CTL_NUM_LOG_PAGES * 2];
|
||||
uint8_t lbp_page[12*CTL_NUM_LBP_PARAMS];
|
||||
struct stat_page {
|
||||
struct scsi_log_stat_and_perf sap;
|
||||
struct scsi_log_idle_time it;
|
||||
struct scsi_log_time_interval ti;
|
||||
} stat_page;
|
||||
struct ctl_page_index index[CTL_NUM_LOG_PAGES];
|
||||
};
|
||||
|
||||
@ -403,6 +410,10 @@ struct ctl_lun {
|
||||
struct ctl_lun_delay_info delay_info;
|
||||
int sync_interval;
|
||||
int sync_count;
|
||||
#ifdef CTL_TIME_IO
|
||||
sbintime_t idle_time;
|
||||
sbintime_t last_busy;
|
||||
#endif
|
||||
TAILQ_HEAD(ctl_ooaq, ctl_io_hdr) ooa_queue;
|
||||
TAILQ_HEAD(ctl_blockq,ctl_io_hdr) blocked_queue;
|
||||
STAILQ_ENTRY(ctl_lun) links;
|
||||
|
@ -785,18 +785,25 @@ ctl_copy_operation_abort(struct ctl_scsiio *ctsio)
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
tpc_resolve(struct tpc_list *list, uint16_t idx, uint32_t *ss)
|
||||
tpc_resolve(struct tpc_list *list, uint16_t idx, uint32_t *ss,
|
||||
uint32_t *pb, uint32_t *pbo)
|
||||
{
|
||||
|
||||
if (idx == 0xffff) {
|
||||
if (ss && list->lun->be_lun)
|
||||
*ss = list->lun->be_lun->blocksize;
|
||||
if (pb && list->lun->be_lun)
|
||||
*pb = list->lun->be_lun->blocksize <<
|
||||
list->lun->be_lun->pblockexp;
|
||||
if (pbo && list->lun->be_lun)
|
||||
*pbo = list->lun->be_lun->blocksize *
|
||||
list->lun->be_lun->pblockoff;
|
||||
return (list->lun->lun);
|
||||
}
|
||||
if (idx >= list->ncscd)
|
||||
return (UINT64_MAX);
|
||||
return (tpcl_resolve(list->lun->ctl_softc,
|
||||
list->init_port, &list->cscd[idx], ss));
|
||||
list->init_port, &list->cscd[idx], ss, pb, pbo));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -809,7 +816,7 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
uint64_t sl, dl;
|
||||
off_t srclba, dstlba, numbytes, donebytes, roundbytes;
|
||||
int numlba;
|
||||
uint32_t srcblock, dstblock;
|
||||
uint32_t srcblock, dstblock, pb, pbo, adj;
|
||||
|
||||
if (list->stage == 1) {
|
||||
while ((tior = TAILQ_FIRST(&list->allio)) != NULL) {
|
||||
@ -834,14 +841,16 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
|
||||
TAILQ_INIT(&list->allio);
|
||||
seg = (struct scsi_ec_segment_b2b *)list->seg[list->curseg];
|
||||
sl = tpc_resolve(list, scsi_2btoul(seg->src_cscd), &srcblock);
|
||||
dl = tpc_resolve(list, scsi_2btoul(seg->dst_cscd), &dstblock);
|
||||
sl = tpc_resolve(list, scsi_2btoul(seg->src_cscd), &srcblock, NULL, NULL);
|
||||
dl = tpc_resolve(list, scsi_2btoul(seg->dst_cscd), &dstblock, &pb, &pbo);
|
||||
if (sl >= CTL_MAX_LUNS || dl >= CTL_MAX_LUNS) {
|
||||
ctl_set_sense(list->ctsio, /*current_error*/ 1,
|
||||
/*sense_key*/ SSD_KEY_COPY_ABORTED,
|
||||
/*asc*/ 0x08, /*ascq*/ 0x04, SSD_ELEM_NONE);
|
||||
return (CTL_RETVAL_ERROR);
|
||||
}
|
||||
if (pbo > 0)
|
||||
pbo = pb - pbo;
|
||||
sdstp = &list->cscd[scsi_2btoul(seg->src_cscd)].dtsp;
|
||||
if (scsi_3btoul(sdstp->block_length) != 0)
|
||||
srcblock = scsi_3btoul(sdstp->block_length);
|
||||
@ -878,7 +887,16 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
prun = &run;
|
||||
list->tbdio = 1;
|
||||
while (donebytes < numbytes) {
|
||||
roundbytes = MIN(numbytes - donebytes, TPC_MAX_IO_SIZE);
|
||||
roundbytes = numbytes - donebytes;
|
||||
if (roundbytes > TPC_MAX_IO_SIZE) {
|
||||
roundbytes = TPC_MAX_IO_SIZE;
|
||||
roundbytes -= roundbytes % dstblock;
|
||||
if (pb > dstblock) {
|
||||
adj = (dstlba * dstblock + roundbytes - pbo) % pb;
|
||||
if (roundbytes > adj)
|
||||
roundbytes -= adj;
|
||||
}
|
||||
}
|
||||
|
||||
tior = malloc(sizeof(*tior), M_CTL, M_WAITOK | M_ZERO);
|
||||
TAILQ_INIT(&tior->run);
|
||||
@ -891,7 +909,7 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
/*read_op*/ 1,
|
||||
/*byte2*/ 0,
|
||||
/*minimum_cdb_size*/ 0,
|
||||
/*lba*/ srclba + donebytes / srcblock,
|
||||
/*lba*/ srclba,
|
||||
/*num_blocks*/ roundbytes / srcblock,
|
||||
/*tag_type*/ CTL_TAG_SIMPLE,
|
||||
/*control*/ 0);
|
||||
@ -910,7 +928,7 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
/*read_op*/ 0,
|
||||
/*byte2*/ 0,
|
||||
/*minimum_cdb_size*/ 0,
|
||||
/*lba*/ dstlba + donebytes / dstblock,
|
||||
/*lba*/ dstlba,
|
||||
/*num_blocks*/ roundbytes / dstblock,
|
||||
/*tag_type*/ CTL_TAG_SIMPLE,
|
||||
/*control*/ 0);
|
||||
@ -922,6 +940,8 @@ tpc_process_b2b(struct tpc_list *list)
|
||||
TAILQ_INSERT_TAIL(prun, tior, rlinks);
|
||||
prun = &tior->run;
|
||||
donebytes += roundbytes;
|
||||
srclba += roundbytes / srcblock;
|
||||
dstlba += roundbytes / dstblock;
|
||||
}
|
||||
|
||||
while ((tior = TAILQ_FIRST(&run)) != NULL) {
|
||||
@ -961,7 +981,7 @@ tpc_process_verify(struct tpc_list *list)
|
||||
|
||||
TAILQ_INIT(&list->allio);
|
||||
seg = (struct scsi_ec_segment_verify *)list->seg[list->curseg];
|
||||
sl = tpc_resolve(list, scsi_2btoul(seg->src_cscd), NULL);
|
||||
sl = tpc_resolve(list, scsi_2btoul(seg->src_cscd), NULL, NULL, NULL);
|
||||
if (sl >= CTL_MAX_LUNS) {
|
||||
ctl_set_sense(list->ctsio, /*current_error*/ 1,
|
||||
/*sense_key*/ SSD_KEY_COPY_ABORTED,
|
||||
@ -1019,7 +1039,7 @@ tpc_process_register_key(struct tpc_list *list)
|
||||
|
||||
TAILQ_INIT(&list->allio);
|
||||
seg = (struct scsi_ec_segment_register_key *)list->seg[list->curseg];
|
||||
dl = tpc_resolve(list, scsi_2btoul(seg->dst_cscd), NULL);
|
||||
dl = tpc_resolve(list, scsi_2btoul(seg->dst_cscd), NULL, NULL, NULL);
|
||||
if (dl >= CTL_MAX_LUNS) {
|
||||
ctl_set_sense(list->ctsio, /*current_error*/ 1,
|
||||
/*sense_key*/ SSD_KEY_COPY_ABORTED,
|
||||
@ -1090,7 +1110,7 @@ tpc_process_wut(struct tpc_list *list)
|
||||
int drange, srange;
|
||||
off_t doffset, soffset;
|
||||
off_t srclba, dstlba, numbytes, donebytes, roundbytes;
|
||||
uint32_t srcblock, dstblock;
|
||||
uint32_t srcblock, dstblock, pb, pbo, adj;
|
||||
|
||||
if (list->stage > 0) {
|
||||
/* Cleanup after previous rounds. */
|
||||
@ -1118,6 +1138,11 @@ tpc_process_wut(struct tpc_list *list)
|
||||
&drange, &doffset) != 0)
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
dstblock = list->lun->be_lun->blocksize;
|
||||
pb = dstblock << list->lun->be_lun->pblockexp;
|
||||
if (list->lun->be_lun->pblockoff > 0)
|
||||
pbo = pb - dstblock * list->lun->be_lun->pblockoff;
|
||||
else
|
||||
pbo = 0;
|
||||
|
||||
/* Check where we are on source ranges list. */
|
||||
srcblock = list->token->blocksize;
|
||||
@ -1131,12 +1156,20 @@ tpc_process_wut(struct tpc_list *list)
|
||||
}
|
||||
|
||||
srclba = scsi_8btou64(list->token->range[srange].lba) + soffset;
|
||||
numbytes = srcblock * omin(TPC_MAX_IOCHUNK_SIZE / srcblock,
|
||||
(scsi_4btoul(list->token->range[srange].length) - soffset));
|
||||
dstlba = scsi_8btou64(list->range[drange].lba) + doffset;
|
||||
numbytes = omin(numbytes,
|
||||
dstblock * omin(TPC_MAX_IOCHUNK_SIZE / dstblock,
|
||||
(scsi_4btoul(list->range[drange].length) - doffset)));
|
||||
numbytes = srcblock *
|
||||
(scsi_4btoul(list->token->range[srange].length) - soffset);
|
||||
numbytes = omin(numbytes, dstblock *
|
||||
(scsi_4btoul(list->range[drange].length) - doffset));
|
||||
if (numbytes > TPC_MAX_IOCHUNK_SIZE) {
|
||||
numbytes = TPC_MAX_IOCHUNK_SIZE;
|
||||
numbytes -= numbytes % dstblock;
|
||||
if (pb > dstblock) {
|
||||
adj = (dstlba * dstblock + numbytes - pbo) % pb;
|
||||
if (numbytes > adj)
|
||||
numbytes -= adj;
|
||||
}
|
||||
}
|
||||
|
||||
if (numbytes % srcblock != 0 || numbytes % dstblock != 0) {
|
||||
ctl_set_sense(list->ctsio, /*current_error*/ 1,
|
||||
@ -1157,7 +1190,16 @@ tpc_process_wut(struct tpc_list *list)
|
||||
list->tbdio = 1;
|
||||
TAILQ_INIT(&list->allio);
|
||||
while (donebytes < numbytes) {
|
||||
roundbytes = MIN(numbytes - donebytes, TPC_MAX_IO_SIZE);
|
||||
roundbytes = numbytes - donebytes;
|
||||
if (roundbytes > TPC_MAX_IO_SIZE) {
|
||||
roundbytes = TPC_MAX_IO_SIZE;
|
||||
roundbytes -= roundbytes % dstblock;
|
||||
if (pb > dstblock) {
|
||||
adj = (dstlba * dstblock + roundbytes - pbo) % pb;
|
||||
if (roundbytes > adj)
|
||||
roundbytes -= adj;
|
||||
}
|
||||
}
|
||||
|
||||
tior = malloc(sizeof(*tior), M_CTL, M_WAITOK | M_ZERO);
|
||||
TAILQ_INIT(&tior->run);
|
||||
@ -1170,7 +1212,7 @@ tpc_process_wut(struct tpc_list *list)
|
||||
/*read_op*/ 1,
|
||||
/*byte2*/ 0,
|
||||
/*minimum_cdb_size*/ 0,
|
||||
/*lba*/ srclba + donebytes / srcblock,
|
||||
/*lba*/ srclba,
|
||||
/*num_blocks*/ roundbytes / srcblock,
|
||||
/*tag_type*/ CTL_TAG_SIMPLE,
|
||||
/*control*/ 0);
|
||||
@ -1189,7 +1231,7 @@ tpc_process_wut(struct tpc_list *list)
|
||||
/*read_op*/ 0,
|
||||
/*byte2*/ 0,
|
||||
/*minimum_cdb_size*/ 0,
|
||||
/*lba*/ dstlba + donebytes / dstblock,
|
||||
/*lba*/ dstlba,
|
||||
/*num_blocks*/ roundbytes / dstblock,
|
||||
/*tag_type*/ CTL_TAG_SIMPLE,
|
||||
/*control*/ 0);
|
||||
@ -1201,6 +1243,8 @@ tpc_process_wut(struct tpc_list *list)
|
||||
TAILQ_INSERT_TAIL(prun, tior, rlinks);
|
||||
prun = &tior->run;
|
||||
donebytes += roundbytes;
|
||||
srclba += roundbytes / srcblock;
|
||||
dstlba += roundbytes / dstblock;
|
||||
}
|
||||
|
||||
while ((tior = TAILQ_FIRST(&run)) != NULL) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
void tpc_done(union ctl_io *io);
|
||||
|
||||
uint64_t tpcl_resolve(struct ctl_softc *softc, int init_port,
|
||||
struct scsi_ec_cscd *cscd, uint32_t *ss);
|
||||
struct scsi_ec_cscd *cscd, uint32_t *ss, uint32_t *ps, uint32_t *pso);
|
||||
union ctl_io * tpcl_alloc_io(void);
|
||||
int tpcl_queue(union ctl_io *io, uint64_t lun);
|
||||
|
||||
|
@ -309,7 +309,7 @@ tpcl_done(union ctl_io *io)
|
||||
|
||||
uint64_t
|
||||
tpcl_resolve(struct ctl_softc *softc, int init_port,
|
||||
struct scsi_ec_cscd *cscd, uint32_t *ss)
|
||||
struct scsi_ec_cscd *cscd, uint32_t *ss, uint32_t *ps, uint32_t *pso)
|
||||
{
|
||||
struct scsi_ec_cscd_id *cscdid;
|
||||
struct ctl_port *port;
|
||||
@ -337,6 +337,12 @@ tpcl_resolve(struct ctl_softc *softc, int init_port,
|
||||
lunid = lun->lun;
|
||||
if (ss && lun->be_lun)
|
||||
*ss = lun->be_lun->blocksize;
|
||||
if (ps && lun->be_lun)
|
||||
*ps = lun->be_lun->blocksize <<
|
||||
lun->be_lun->pblockexp;
|
||||
if (pso && lun->be_lun)
|
||||
*pso = lun->be_lun->blocksize *
|
||||
lun->be_lun->pblockoff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -561,6 +561,7 @@ struct scsi_log_sense
|
||||
#define SLS_ERROR_LASTN_PAGE 0x07
|
||||
#define SLS_LOGICAL_BLOCK_PROVISIONING 0x0c
|
||||
#define SLS_SELF_TEST_PAGE 0x10
|
||||
#define SLS_STAT_AND_PERF 0x19
|
||||
#define SLS_IE_PAGE 0x2f
|
||||
#define SLS_PAGE_CTRL_MASK 0xC0
|
||||
#define SLS_PAGE_CTRL_THRESHOLD 0x00
|
||||
@ -619,6 +620,45 @@ struct scsi_log_param_header {
|
||||
u_int8_t param_len;
|
||||
};
|
||||
|
||||
struct scsi_log_stat_and_perf {
|
||||
struct scsi_log_param_header hdr;
|
||||
#define SLP_SAP 0x0001
|
||||
uint8_t read_num[8];
|
||||
uint8_t write_num[8];
|
||||
uint8_t recvieved_lba[8];
|
||||
uint8_t transmitted_lba[8];
|
||||
uint8_t read_int[8];
|
||||
uint8_t write_int[8];
|
||||
uint8_t weighted_num[8];
|
||||
uint8_t weighted_int[8];
|
||||
};
|
||||
|
||||
struct scsi_log_idle_time {
|
||||
struct scsi_log_param_header hdr;
|
||||
#define SLP_IT 0x0002
|
||||
uint8_t idle_int[8];
|
||||
};
|
||||
|
||||
struct scsi_log_time_interval {
|
||||
struct scsi_log_param_header hdr;
|
||||
#define SLP_TI 0x0003
|
||||
uint8_t exponent[4];
|
||||
uint8_t integer[4];
|
||||
};
|
||||
|
||||
struct scsi_log_fua_stat_and_perf {
|
||||
struct scsi_log_param_header hdr;
|
||||
#define SLP_FUA_SAP 0x0004
|
||||
uint8_t fua_read_num[8];
|
||||
uint8_t fua_write_num[8];
|
||||
uint8_t fuanv_read_num[8];
|
||||
uint8_t fuanv_write_num[8];
|
||||
uint8_t fua_read_int[8];
|
||||
uint8_t fua_write_int[8];
|
||||
uint8_t fuanv_read_int[8];
|
||||
uint8_t fuanv_write_int[8];
|
||||
};
|
||||
|
||||
struct scsi_control_page {
|
||||
u_int8_t page_code;
|
||||
u_int8_t page_length;
|
||||
|
30
sys/cddl/contrib/opensolaris/uts/arm/dtrace/fasttrap_isa.c
Normal file
30
sys/cddl/contrib/opensolaris/uts/arm/dtrace/fasttrap_isa.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* XXX: Placeholder for ARM fasttrap code
|
||||
*/
|
94
sys/cddl/contrib/opensolaris/uts/arm/sys/fasttrap_isa.h
Normal file
94
sys/cddl/contrib/opensolaris/uts/arm/sys/fasttrap_isa.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _FASTTRAP_ISA_H
|
||||
#define _FASTTRAP_ISA_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is our reserved trap instruction: ta 0x38
|
||||
*/
|
||||
#define FASTTRAP_INSTR 0x91d02038
|
||||
|
||||
#define FASTTRAP_SUNWDTRACE_SIZE 128
|
||||
|
||||
typedef uint32_t fasttrap_instr_t;
|
||||
|
||||
typedef struct fasttrap_machtp {
|
||||
fasttrap_instr_t ftmt_instr; /* original instruction */
|
||||
uintptr_t ftmt_dest; /* destination of DCTI */
|
||||
uint8_t ftmt_type; /* emulation type */
|
||||
uint8_t ftmt_flags; /* emulation flags */
|
||||
uint8_t ftmt_cc; /* which cc to look at */
|
||||
uint8_t ftmt_code; /* branch condition */
|
||||
} fasttrap_machtp_t;
|
||||
|
||||
#define ftt_instr ftt_mtp.ftmt_instr
|
||||
#define ftt_dest ftt_mtp.ftmt_dest
|
||||
#define ftt_type ftt_mtp.ftmt_type
|
||||
#define ftt_flags ftt_mtp.ftmt_flags
|
||||
#define ftt_cc ftt_mtp.ftmt_cc
|
||||
#define ftt_code ftt_mtp.ftmt_code
|
||||
|
||||
#define FASTTRAP_T_COMMON 0x00 /* common case -- no emulation */
|
||||
#define FASTTRAP_T_CCR 0x01 /* integer condition code branch */
|
||||
#define FASTTRAP_T_FCC 0x02 /* floating-point branch */
|
||||
#define FASTTRAP_T_REG 0x03 /* register predicated branch */
|
||||
#define FASTTRAP_T_ALWAYS 0x04 /* branch always */
|
||||
#define FASTTRAP_T_CALL 0x05 /* call instruction */
|
||||
#define FASTTRAP_T_JMPL 0x06 /* jmpl instruction */
|
||||
#define FASTTRAP_T_RDPC 0x07 /* rdpc instruction */
|
||||
#define FASTTRAP_T_RETURN 0x08 /* return instruction */
|
||||
|
||||
/*
|
||||
* For performance rather than correctness.
|
||||
*/
|
||||
#define FASTTRAP_T_SAVE 0x10 /* save instruction (func entry only) */
|
||||
#define FASTTRAP_T_RESTORE 0x11 /* restore instruction */
|
||||
#define FASTTRAP_T_OR 0x12 /* mov instruction */
|
||||
#define FASTTRAP_T_SETHI 0x13 /* sethi instruction (includes nop) */
|
||||
|
||||
#define FASTTRAP_F_ANNUL 0x01 /* branch is annulled */
|
||||
#define FASTTRAP_F_RETMAYBE 0x02 /* not definitely a return site */
|
||||
|
||||
#define FASTTRAP_AFRAMES 3
|
||||
#define FASTTRAP_RETURN_AFRAMES 4
|
||||
#define FASTTRAP_ENTRY_AFRAMES 3
|
||||
#define FASTTRAP_OFFSET_AFRAMES 3
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FASTTRAP_ISA_H */
|
@ -11880,7 +11880,7 @@ err:
|
||||
int i;
|
||||
|
||||
*factor = 1;
|
||||
#if defined(__amd64__) || defined(__mips__) || defined(__powerpc__)
|
||||
#if defined(__amd64__) || defined(__arm__) || defined(__mips__) || defined(__powerpc__)
|
||||
/*
|
||||
* FreeBSD isn't good at limiting the amount of memory we
|
||||
* ask to malloc, so let's place a limit here before trying
|
||||
|
@ -2434,6 +2434,13 @@ extern void dtrace_helpers_destroy(proc_t *);
|
||||
#define DTRACE_INVOP_MFLR_R0 5
|
||||
#define DTRACE_INVOP_NOP 6
|
||||
|
||||
#elif defined(__arm__)
|
||||
|
||||
#define DTRACE_INVOP_PUSHM 1
|
||||
#define DTRACE_INVOP_POPM 2
|
||||
#define DTRACE_INVOP_B 3
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
197
sys/cddl/dev/dtrace/arm/dtrace_asm.S
Normal file
197
sys/cddl/dev/dtrace/arm/dtrace_asm.S
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#define _ASM
|
||||
#define _LOCORE
|
||||
#define LOCORE
|
||||
|
||||
#include <sys/cpuvar_defs.h>
|
||||
#include <sys/dtrace.h>
|
||||
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
/*
|
||||
void dtrace_membar_producer(void)
|
||||
*/
|
||||
ENTRY(dtrace_membar_producer)
|
||||
RET
|
||||
END(dtrace_membar_producer)
|
||||
|
||||
/*
|
||||
void dtrace_membar_consumer(void)
|
||||
*/
|
||||
ENTRY(dtrace_membar_consumer)
|
||||
RET
|
||||
END(dtrace_membar_consumer)
|
||||
|
||||
/*
|
||||
dtrace_icookie_t dtrace_interrupt_disable(void)
|
||||
*/
|
||||
ENTRY(dtrace_interrupt_disable)
|
||||
mrs r0, cpsr
|
||||
mov r1, r0
|
||||
orr r1, r1, #(PSR_I | PSR_F)
|
||||
msr cpsr_c, r1
|
||||
RET
|
||||
END(dtrace_interrupt_disable)
|
||||
|
||||
/*
|
||||
void dtrace_interrupt_enable(dtrace_icookie_t cookie)
|
||||
*/
|
||||
ENTRY(dtrace_interrupt_enable)
|
||||
and r0, r0, #(PSR_I | PSR_F)
|
||||
mrs r1, cpsr
|
||||
bic r1, r1, #(PSR_I | PSR_F)
|
||||
orr r1, r1, r0
|
||||
msr cpsr_c, r1
|
||||
RET
|
||||
END(dtrace_interrupt_enable)
|
||||
/*
|
||||
uint8_t
|
||||
dtrace_fuword8_nocheck(void *addr)
|
||||
*/
|
||||
ENTRY(dtrace_fuword8_nocheck)
|
||||
ldrb r3, [r0]
|
||||
mov r0, r3
|
||||
RET
|
||||
END(dtrace_fuword8_nocheck)
|
||||
|
||||
/*
|
||||
uint16_t
|
||||
dtrace_fuword16_nocheck(void *addr)
|
||||
*/
|
||||
ENTRY(dtrace_fuword16_nocheck)
|
||||
ldrh r3, [r0]
|
||||
mov r0, r3
|
||||
RET
|
||||
END(dtrace_fuword16_nocheck)
|
||||
|
||||
/*
|
||||
uint32_t
|
||||
dtrace_fuword32_nocheck(void *addr)
|
||||
*/
|
||||
ENTRY(dtrace_fuword32_nocheck)
|
||||
ldr r3, [r0]
|
||||
mov r0, r3
|
||||
RET
|
||||
END(dtrace_fuword32_nocheck)
|
||||
|
||||
/*
|
||||
uint64_t
|
||||
dtrace_fuword64_nocheck(void *addr)
|
||||
*/
|
||||
ENTRY(dtrace_fuword64_nocheck)
|
||||
ldm r0, {r2, r3}
|
||||
|
||||
mov r0, r2
|
||||
mov r1, r3
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
/* big endian */
|
||||
mov r0, r3
|
||||
mov r1, r2
|
||||
#else
|
||||
/* little endian */
|
||||
mov r0, r2
|
||||
mov r1, r3
|
||||
|
||||
#endif
|
||||
RET
|
||||
END(dtrace_fuword64_nocheck)
|
||||
|
||||
/*
|
||||
void
|
||||
dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size)
|
||||
*/
|
||||
ENTRY(dtrace_copy)
|
||||
stmfd sp!, {r4-r5} /* stack is 8 byte aligned */
|
||||
teq r2, #0x00000000
|
||||
mov r5, #0x00000000
|
||||
beq 2f
|
||||
|
||||
1: ldrb r4, [r0], #0x0001
|
||||
add r5, r5, #0x00000001
|
||||
strb r4, [r1], #0x0001
|
||||
teqne r5, r2
|
||||
bne 1b
|
||||
|
||||
2: ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */
|
||||
RET
|
||||
END(dtrace_copy)
|
||||
|
||||
/*
|
||||
void
|
||||
dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
|
||||
volatile uint16_t *flags)
|
||||
XXX: Check for flags?
|
||||
*/
|
||||
ENTRY(dtrace_copystr)
|
||||
stmfd sp!, {r4-r5} /* stack is 8 byte aligned */
|
||||
teq r2, #0x00000000
|
||||
mov r5, #0x00000000
|
||||
beq 2f
|
||||
|
||||
1: ldrb r4, [r0], #0x0001
|
||||
add r5, r5, #0x00000001
|
||||
teq r4, #0x00000000
|
||||
strb r4, [r1], #0x0001
|
||||
teqne r5, r2
|
||||
bne 1b
|
||||
|
||||
2: ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */
|
||||
RET
|
||||
END(dtrace_copystr)
|
||||
|
||||
/*
|
||||
void
|
||||
vpanic(const char *format, va_list alist)
|
||||
*/
|
||||
ENTRY(vpanic) /* Initial stack layout: */
|
||||
vpanic_common:
|
||||
RET
|
||||
END(vpanic)
|
||||
|
||||
/*
|
||||
void
|
||||
dtrace_vpanic(const char *format, va_list alist)
|
||||
*/
|
||||
ENTRY(dtrace_vpanic) /* Initial stack layout: */
|
||||
b vpanic
|
||||
RET
|
||||
END(dtrace_vpanic) /* Initial stack layout: */
|
||||
|
||||
/*
|
||||
uintptr_t
|
||||
dtrace_caller(int aframes)
|
||||
*/
|
||||
ENTRY(dtrace_caller)
|
||||
mov r0, #-1
|
||||
RET
|
||||
END(dtrace_caller)
|
356
sys/cddl/dev/dtrace/arm/dtrace_isa.c
Normal file
356
sys/cddl/dev/dtrace/arm/dtrace_isa.c
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/stack.h>
|
||||
#include <sys/pcpu.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/stack.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/ddb.h>
|
||||
#include <sys/kdb.h>
|
||||
|
||||
#include "regset.h"
|
||||
|
||||
/*
|
||||
* Wee need some reasonable default to prevent backtrace code
|
||||
* from wandering too far
|
||||
*/
|
||||
#define MAX_FUNCTION_SIZE 0x10000
|
||||
#define MAX_PROLOGUE_SIZE 0x100
|
||||
|
||||
|
||||
uint8_t dtrace_fuword8_nocheck(void *);
|
||||
uint16_t dtrace_fuword16_nocheck(void *);
|
||||
uint32_t dtrace_fuword32_nocheck(void *);
|
||||
uint64_t dtrace_fuword64_nocheck(void *);
|
||||
|
||||
void
|
||||
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
|
||||
uint32_t *intrpc)
|
||||
{
|
||||
u_int32_t *frame, *lastframe;
|
||||
int scp_offset;
|
||||
int depth = 0;
|
||||
pc_t caller = (pc_t) solaris_cpu[curcpu].cpu_dtrace_caller;
|
||||
|
||||
if (intrpc != 0)
|
||||
pcstack[depth++] = (pc_t) intrpc;
|
||||
|
||||
aframes++;
|
||||
|
||||
frame = (u_int32_t *)__builtin_frame_address(0);;
|
||||
lastframe = NULL;
|
||||
scp_offset = -(get_pc_str_offset() >> 2);
|
||||
|
||||
while ((frame != NULL) && (depth < pcstack_limit)) {
|
||||
db_addr_t scp;
|
||||
#if 0
|
||||
u_int32_t savecode;
|
||||
int r;
|
||||
u_int32_t *rp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In theory, the SCP isn't guaranteed to be in the function
|
||||
* that generated the stack frame. We hope for the best.
|
||||
*/
|
||||
scp = frame[FR_SCP];
|
||||
|
||||
if (aframes > 0) {
|
||||
aframes--;
|
||||
if ((aframes == 0) && (caller != 0)) {
|
||||
pcstack[depth++] = caller;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pcstack[depth++] = scp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
savecode = ((u_int32_t *)scp)[scp_offset];
|
||||
if ((savecode & 0x0e100000) == 0x08000000) {
|
||||
/* Looks like an STM */
|
||||
rp = frame - 4;
|
||||
for (r = 10; r >= 0; r--) {
|
||||
if (savecode & (1 << r)) {
|
||||
/* register r == *rp-- */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Switch to next frame up
|
||||
*/
|
||||
if (frame[FR_RFP] == 0)
|
||||
break; /* Top of stack */
|
||||
|
||||
lastframe = frame;
|
||||
frame = (u_int32_t *)(frame[FR_RFP]);
|
||||
|
||||
if (INKERNEL((int)frame)) {
|
||||
/* staying in kernel */
|
||||
if (frame <= lastframe) {
|
||||
/* bad frame pointer */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for (; depth < pcstack_limit; depth++) {
|
||||
pcstack[depth] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
|
||||
{
|
||||
printf("IMPLEMENT ME: %s\n", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
dtrace_getustackdepth(void)
|
||||
{
|
||||
printf("IMPLEMENT ME: %s\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
|
||||
{
|
||||
printf("IMPLEMENT ME: %s\n", __func__);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
uint64_t
|
||||
dtrace_getarg(int arg, int aframes)
|
||||
{
|
||||
/* struct arm_frame *fp = (struct arm_frame *)dtrace_getfp();*/
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
dtrace_getstackdepth(int aframes)
|
||||
{
|
||||
u_int32_t *frame, *lastframe;
|
||||
int scp_offset;
|
||||
int depth = 1;
|
||||
|
||||
frame = (u_int32_t *)__builtin_frame_address(0);;
|
||||
lastframe = NULL;
|
||||
scp_offset = -(get_pc_str_offset() >> 2);
|
||||
|
||||
while (frame != NULL) {
|
||||
db_addr_t scp;
|
||||
#if 0
|
||||
u_int32_t savecode;
|
||||
int r;
|
||||
u_int32_t *rp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In theory, the SCP isn't guaranteed to be in the function
|
||||
* that generated the stack frame. We hope for the best.
|
||||
*/
|
||||
scp = frame[FR_SCP];
|
||||
|
||||
depth++;
|
||||
|
||||
/*
|
||||
* Switch to next frame up
|
||||
*/
|
||||
if (frame[FR_RFP] == 0)
|
||||
break; /* Top of stack */
|
||||
|
||||
lastframe = frame;
|
||||
frame = (u_int32_t *)(frame[FR_RFP]);
|
||||
|
||||
if (INKERNEL((int)frame)) {
|
||||
/* staying in kernel */
|
||||
if (frame <= lastframe) {
|
||||
/* bad frame pointer */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (depth < aframes)
|
||||
return 0;
|
||||
else
|
||||
return depth - aframes;
|
||||
|
||||
}
|
||||
|
||||
ulong_t
|
||||
dtrace_getreg(struct trapframe *rp, uint_t reg)
|
||||
{
|
||||
printf("IMPLEMENT ME: %s\n", __func__);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
|
||||
{
|
||||
|
||||
if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = uaddr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
|
||||
volatile uint16_t *flags)
|
||||
{
|
||||
if (dtrace_copycheck(uaddr, kaddr, size))
|
||||
dtrace_copy(uaddr, kaddr, size);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
|
||||
volatile uint16_t *flags)
|
||||
{
|
||||
if (dtrace_copycheck(uaddr, kaddr, size))
|
||||
dtrace_copy(kaddr, uaddr, size);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
|
||||
volatile uint16_t *flags)
|
||||
{
|
||||
if (dtrace_copycheck(uaddr, kaddr, size))
|
||||
dtrace_copystr(uaddr, kaddr, size, flags);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
|
||||
volatile uint16_t *flags)
|
||||
{
|
||||
if (dtrace_copycheck(uaddr, kaddr, size))
|
||||
dtrace_copystr(kaddr, uaddr, size, flags);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dtrace_fuword8(void *uaddr)
|
||||
{
|
||||
if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
|
||||
return (0);
|
||||
}
|
||||
return (dtrace_fuword8_nocheck(uaddr));
|
||||
}
|
||||
|
||||
uint16_t
|
||||
dtrace_fuword16(void *uaddr)
|
||||
{
|
||||
if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
|
||||
return (0);
|
||||
}
|
||||
return (dtrace_fuword16_nocheck(uaddr));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dtrace_fuword32(void *uaddr)
|
||||
{
|
||||
if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
|
||||
return (0);
|
||||
}
|
||||
return (dtrace_fuword32_nocheck(uaddr));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
dtrace_fuword64(void *uaddr)
|
||||
{
|
||||
if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
|
||||
return (0);
|
||||
}
|
||||
return (dtrace_fuword64_nocheck(uaddr));
|
||||
}
|
||||
|
||||
#define __with_interrupts_disabled(expr) \
|
||||
do { \
|
||||
u_int cpsr_save, tmp; \
|
||||
\
|
||||
__asm __volatile( \
|
||||
"mrs %0, cpsr;" \
|
||||
"orr %1, %0, %2;" \
|
||||
"msr cpsr_fsxc, %1;" \
|
||||
: "=r" (cpsr_save), "=r" (tmp) \
|
||||
: "I" (PSR_I | PSR_F) \
|
||||
: "cc" ); \
|
||||
(expr); \
|
||||
__asm __volatile( \
|
||||
"msr cpsr_fsxc, %0" \
|
||||
: /* no output */ \
|
||||
: "r" (cpsr_save) \
|
||||
: "cc" ); \
|
||||
} while(0)
|
||||
|
||||
uint32_t dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
|
||||
{
|
||||
return atomic_cmpset_32((uint32_t*)target, (uint32_t)cmp, (uint32_t)new);
|
||||
|
||||
}
|
||||
|
||||
void * dtrace_casptr(volatile void *target, volatile void *cmp, volatile void *new)
|
||||
{
|
||||
return (void*)dtrace_cas32((uint32_t*)target, (uint32_t)cmp, (uint32_t)new);
|
||||
}
|
||||
|
261
sys/cddl/dev/dtrace/arm/dtrace_subr.c
Normal file
261
sys/cddl/dev/dtrace/arm/dtrace_subr.c
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/trap.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#define DELAYBRANCH(x) ((int)(x) < 0)
|
||||
|
||||
extern uintptr_t dtrace_in_probe_addr;
|
||||
extern int dtrace_in_probe;
|
||||
extern dtrace_id_t dtrace_probeid_error;
|
||||
extern int (*dtrace_invop_jump_addr)(struct trapframe *);
|
||||
|
||||
int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
|
||||
void dtrace_invop_init(void);
|
||||
void dtrace_invop_uninit(void);
|
||||
|
||||
typedef struct dtrace_invop_hdlr {
|
||||
int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
|
||||
struct dtrace_invop_hdlr *dtih_next;
|
||||
} dtrace_invop_hdlr_t;
|
||||
|
||||
dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax)
|
||||
{
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
|
||||
{
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
|
||||
hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
|
||||
hdlr->dtih_func = func;
|
||||
hdlr->dtih_next = dtrace_invop_hdlr;
|
||||
dtrace_invop_hdlr = hdlr;
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
|
||||
{
|
||||
dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL;
|
||||
|
||||
for (;;) {
|
||||
if (hdlr == NULL)
|
||||
panic("attempt to remove non-existent invop handler");
|
||||
|
||||
if (hdlr->dtih_func == func)
|
||||
break;
|
||||
|
||||
prev = hdlr;
|
||||
hdlr = hdlr->dtih_next;
|
||||
}
|
||||
|
||||
if (prev == NULL) {
|
||||
ASSERT(dtrace_invop_hdlr == hdlr);
|
||||
dtrace_invop_hdlr = hdlr->dtih_next;
|
||||
} else {
|
||||
ASSERT(dtrace_invop_hdlr != hdlr);
|
||||
prev->dtih_next = hdlr->dtih_next;
|
||||
}
|
||||
|
||||
kmem_free(hdlr, 0);
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
dtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit))
|
||||
{
|
||||
printf("IMPLEMENT ME: dtrace_toxic_ranges\n");
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
|
||||
{
|
||||
cpuset_t cpus;
|
||||
|
||||
if (cpu == DTRACE_CPUALL)
|
||||
cpus = all_cpus;
|
||||
else
|
||||
CPU_SETOF(cpu, &cpus);
|
||||
|
||||
smp_rendezvous_cpus(cpus, smp_no_rendevous_barrier, func,
|
||||
smp_no_rendevous_barrier, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
dtrace_sync_func(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_sync(void)
|
||||
{
|
||||
dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* DTrace needs a high resolution time function which can
|
||||
* be called from a probe context and guaranteed not to have
|
||||
* instrumented with probes itself.
|
||||
*
|
||||
* Returns nanoseconds since boot.
|
||||
*/
|
||||
uint64_t
|
||||
dtrace_gethrtime()
|
||||
{
|
||||
struct timespec curtime;
|
||||
|
||||
nanouptime(&curtime);
|
||||
|
||||
return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec);
|
||||
|
||||
}
|
||||
|
||||
uint64_t
|
||||
dtrace_gethrestime(void)
|
||||
{
|
||||
struct timespec curtime;
|
||||
|
||||
getnanotime(&curtime);
|
||||
|
||||
return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec);
|
||||
}
|
||||
|
||||
/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
|
||||
int
|
||||
dtrace_trap(struct trapframe *frame, u_int type)
|
||||
{
|
||||
/*
|
||||
* A trap can occur while DTrace executes a probe. Before
|
||||
* executing the probe, DTrace blocks re-scheduling and sets
|
||||
* a flag in it's per-cpu flags to indicate that it doesn't
|
||||
* want to fault. On returning from the probe, the no-fault
|
||||
* flag is cleared and finally re-scheduling is enabled.
|
||||
*
|
||||
* Check if DTrace has enabled 'no-fault' mode:
|
||||
*
|
||||
*/
|
||||
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
|
||||
/*
|
||||
* There are only a couple of trap types that are expected.
|
||||
* All the rest will be handled in the usual way.
|
||||
*/
|
||||
switch (type) {
|
||||
/* Page fault. */
|
||||
case FAULT_ALIGN:
|
||||
/* Flag a bad address. */
|
||||
cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = 0;
|
||||
|
||||
/*
|
||||
* Offset the instruction pointer to the instruction
|
||||
* following the one causing the fault.
|
||||
*/
|
||||
frame->tf_pc += sizeof(int);
|
||||
return (1);
|
||||
default:
|
||||
/* Handle all other traps in the usual way. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the trap in the usual way. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
|
||||
int fault, int fltoffs, uintptr_t illval)
|
||||
{
|
||||
|
||||
dtrace_probe(dtrace_probeid_error, (uint64_t)(uintptr_t)state,
|
||||
(uintptr_t)epid,
|
||||
(uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs);
|
||||
}
|
||||
|
||||
static int
|
||||
dtrace_invop_start(struct trapframe *frame)
|
||||
{
|
||||
printf("IMPLEMENT ME: %s\n", __func__);
|
||||
switch (dtrace_invop(frame->tf_pc, (uintptr_t *)frame, frame->tf_pc)) {
|
||||
case DTRACE_INVOP_PUSHM:
|
||||
// TODO:
|
||||
break;
|
||||
case DTRACE_INVOP_POPM:
|
||||
// TODO:
|
||||
break;
|
||||
case DTRACE_INVOP_B:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void dtrace_invop_init(void)
|
||||
{
|
||||
dtrace_invop_jump_addr = dtrace_invop_start;
|
||||
}
|
||||
|
||||
void dtrace_invop_uninit(void)
|
||||
{
|
||||
dtrace_invop_jump_addr = 0;
|
||||
}
|
57
sys/cddl/dev/dtrace/arm/regset.h
Normal file
57
sys/cddl/dev/dtrace/arm/regset.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
#ifndef _REGSET_H
|
||||
#define _REGSET_H
|
||||
|
||||
/*
|
||||
* #pragma ident "@(#)regset.h 1.11 05/06/08 SMI"
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define REG_LINK R14
|
||||
#define REG_SP R12
|
||||
#define REG_PS R0
|
||||
#define REG_R0 R0
|
||||
#define REG_R1 R1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _REGSET_H */
|
192
sys/cddl/dev/fbt/arm/fbt_isa.c
Normal file
192
sys/cddl/dev/fbt/arm/fbt_isa.c
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Portions Copyright 2006-2008 John Birrell jb@freebsd.org
|
||||
* Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org
|
||||
* Portions Copyright 2013 Howard Su howardsu@freebsd.org
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <sys/dtrace.h>
|
||||
|
||||
#include "fbt.h"
|
||||
|
||||
#define FBT_PATCHVAL 0xe06a0cfe /* illegal instruction */
|
||||
|
||||
#define FBT_PUSHM 0xe92d0000
|
||||
#define FBT_POPM 0xe8bd0000
|
||||
#define FBT_JUMP 0xea000000
|
||||
|
||||
#define FBT_ENTRY "entry"
|
||||
#define FBT_RETURN "return"
|
||||
|
||||
int
|
||||
fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
|
||||
{
|
||||
struct trapframe *frame = (struct trapframe *)stack;
|
||||
solaris_cpu_t *cpu = &solaris_cpu[curcpu];
|
||||
fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
|
||||
|
||||
for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
|
||||
if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
|
||||
fbt->fbtp_invop_cnt++;
|
||||
cpu->cpu_dtrace_caller = addr;
|
||||
|
||||
/* TODO: Need 5th parameter from stack */
|
||||
dtrace_probe(fbt->fbtp_id, frame->tf_r0,
|
||||
frame->tf_r1, frame->tf_r2,
|
||||
frame->tf_r3, 0);
|
||||
|
||||
cpu->cpu_dtrace_caller = 0;
|
||||
|
||||
return (fbt->fbtp_rval);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
|
||||
{
|
||||
|
||||
*fbt->fbtp_patchpoint = val;
|
||||
cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
|
||||
}
|
||||
|
||||
int
|
||||
fbt_provide_module_function(linker_file_t lf, int symindx,
|
||||
linker_symval_t *symval, void *opaque)
|
||||
{
|
||||
char *modname = opaque;
|
||||
const char *name = symval->name;
|
||||
fbt_probe_t *fbt, *retfbt;
|
||||
uint32_t *instr, *limit;
|
||||
int popm;
|
||||
|
||||
if (strncmp(name, "dtrace_", 7) == 0 &&
|
||||
strncmp(name, "dtrace_safe_", 12) != 0) {
|
||||
/*
|
||||
* Anything beginning with "dtrace_" may be called
|
||||
* from probe context unless it explicitly indicates
|
||||
* that it won't be called from probe context by
|
||||
* using the prefix "dtrace_safe_".
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (name[0] == '_' && name[1] == '_')
|
||||
return (0);
|
||||
|
||||
instr = (uint32_t *)symval->value;
|
||||
limit = (uint32_t *)(symval->value + symval->size);
|
||||
|
||||
for (; instr < limit; instr++)
|
||||
if ((*instr & 0xffff0000) == FBT_PUSHM &&
|
||||
(*instr & 0x4000) != 0)
|
||||
break;
|
||||
|
||||
if (instr >= limit)
|
||||
return (0);
|
||||
|
||||
fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
|
||||
fbt->fbtp_name = name;
|
||||
fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
|
||||
name, FBT_ENTRY, 3, fbt);
|
||||
fbt->fbtp_patchpoint = instr;
|
||||
fbt->fbtp_ctl = lf;
|
||||
fbt->fbtp_loadcnt = lf->loadcnt;
|
||||
fbt->fbtp_savedval = *instr;
|
||||
fbt->fbtp_patchval = FBT_PATCHVAL;
|
||||
fbt->fbtp_rval = DTRACE_INVOP_PUSHM;
|
||||
fbt->fbtp_symindx = symindx;
|
||||
|
||||
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
|
||||
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
|
||||
|
||||
lf->fbt_nentries++;
|
||||
|
||||
popm = FBT_POPM | ((*instr) & 0x3FFF) | 0x8000;
|
||||
|
||||
retfbt = NULL;
|
||||
again:
|
||||
for (; instr < limit; instr++) {
|
||||
if (*instr == popm)
|
||||
break;
|
||||
else if ((*instr & 0xff000000) == FBT_JUMP) {
|
||||
uint32_t *target, *start;
|
||||
int offset;
|
||||
|
||||
offset = (*instr & 0xffffff);
|
||||
offset <<= 8;
|
||||
offset /= 64;
|
||||
target = instr + (2 + offset);
|
||||
start = (uint32_t *)symval->value;
|
||||
if (target >= limit || target < start)
|
||||
break;
|
||||
instr++; /* skip delay slot */
|
||||
}
|
||||
}
|
||||
|
||||
if (instr >= limit)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We have a winner!
|
||||
*/
|
||||
fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
|
||||
fbt->fbtp_name = name;
|
||||
if (retfbt == NULL) {
|
||||
fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
|
||||
name, FBT_RETURN, 5, fbt);
|
||||
} else {
|
||||
retfbt->fbtp_next = fbt;
|
||||
fbt->fbtp_id = retfbt->fbtp_id;
|
||||
}
|
||||
retfbt = fbt;
|
||||
|
||||
fbt->fbtp_patchpoint = instr;
|
||||
fbt->fbtp_ctl = lf;
|
||||
fbt->fbtp_loadcnt = lf->loadcnt;
|
||||
fbt->fbtp_symindx = symindx;
|
||||
if ((*instr & 0xff000000) == FBT_JUMP)
|
||||
fbt->fbtp_rval = DTRACE_INVOP_B;
|
||||
else
|
||||
fbt->fbtp_rval = DTRACE_INVOP_POPM;
|
||||
fbt->fbtp_savedval = *instr;
|
||||
fbt->fbtp_patchval = FBT_PATCHVAL;
|
||||
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
|
||||
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
|
||||
|
||||
lf->fbt_nentries++;
|
||||
|
||||
instr++;
|
||||
goto again;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user