Merge ^/head r278499 through r278755.

This commit is contained in:
Dimitry Andric 2015-02-14 13:12:03 +00:00
commit 569e61a4fc
181 changed files with 4333 additions and 1430 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View 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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}}}

View File

@ -49,7 +49,7 @@
struct _libdwarf_globals {
Dwarf_Handler errhand;
Dwarf_Ptr errarg;
int applyrela;
int applyreloc;
};
extern struct _libdwarf_globals _libdwarf;

View File

@ -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);
}

View File

@ -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.

View File

@ -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
};

View File

@ -439,6 +439,7 @@ enum Dwarf_ISA {
DW_ISA_SPARC,
DW_ISA_X86,
DW_ISA_X86_64,
DW_ISA_AARCH64,
DW_ISA_MAX
};

View File

@ -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)

View File

@ -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);

View File

@ -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'

View File

@ -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)

View File

@ -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:\

View File

@ -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

View File

@ -21,8 +21,6 @@
usr
bin
..
games
..
lib
clang
3.6.0

View File

@ -7,8 +7,6 @@
.
bin
..
games
..
include
..
lib

View File

@ -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

View File

@ -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.

View File

@ -5,6 +5,7 @@
# PROVIDE: local_unbound
# REQUIRE: FILESYSTEMS netif resolv
# BEFORE: NETWORKING
# KEYWORD: shutdown
. /etc/rc.subr

View File

@ -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 $*

View File

@ -5,6 +5,7 @@
# PROVIDE: utx
# REQUIRE: DAEMON FILESYSTEMS
# BEFORE: LOGIN
# KEYWORD: shutdown
. /etc/rc.subr

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -30,4 +30,4 @@
# @(#)rot13.sh 8.1 (Berkeley) 5/31/93
# $FreeBSD$
exec /usr/games/caesar 13 "$@"
exec /usr/bin/caesar 13 "$@"

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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)
{
}

View File

@ -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
};

View File

@ -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; \

View File

@ -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) {

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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__)

View File

@ -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;
}

View File

@ -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

View File

@ -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 *);

View File

@ -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)
{

View File

@ -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)) =

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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) {

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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
}

View File

@ -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;

View File

@ -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

View File

@ -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");

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View 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
*/

View 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 */

View File

@ -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

View File

@ -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

View 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)

View 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);
}

View 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;
}

View 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 */

View 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