MFhead @ r277403
This commit is contained in:
commit
51dd214c84
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/building-blocks/; revision=277404
@ -38,6 +38,60 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20150118: new clang import which bumps version from 3.5.0 to 3.5.1.
|
||||
OLD_FILES+=usr/include/clang/3.5.0/__wmmintrin_aes.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/__wmmintrin_pclmul.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/altivec.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/ammintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/arm_acle.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/arm_neon.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/avx2intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/avxintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/bmi2intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/bmiintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/cpuid.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/emmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/f16cintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/fma4intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/fmaintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/ia32intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/immintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/lzcntintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/mm3dnow.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/mm_malloc.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/mmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/module.modulemap
|
||||
OLD_FILES+=usr/include/clang/3.5.0/nmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/pmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/popcntintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/prfchwintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/rdseedintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/rtmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/shaintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/smmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/tbmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/tmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/wmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/x86intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/xmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.5.0/xopintrin.h
|
||||
OLD_DIRS+=usr/include/clang/3.5.0
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan_cxx-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-arm.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.san-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.san-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan-x86_64.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan_cxx-i386.a
|
||||
OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a
|
||||
OLD_DIRS+=usr/lib/clang/3.5.0/lib/freebsd
|
||||
OLD_DIRS+=usr/lib/clang/3.5.0/lib
|
||||
OLD_DIRS+=usr/lib/clang/3.5.0
|
||||
# 20150102: removal of texinfo
|
||||
OLD_FILES+=usr/bin/info
|
||||
OLD_FILES+=usr/bin/infokey
|
||||
@ -307,8 +361,6 @@ OLD_DIRS+=usr/include/clang/3.4
|
||||
# 20140505: Bogusly installing src.opts.mk
|
||||
OLD_FILES+=usr/share/mk/src.opts.mk
|
||||
# 20140505: Reject PR kern/187551
|
||||
OLD_DIRS+=usr/tests/sbin/ifconfig
|
||||
OLD_FILES+=usr/tests/sbin/ifconfig/Kyuafile
|
||||
OLD_FILES+=usr/tests/sbin/ifconfig/fibs_test
|
||||
# 20140502: Removal of lindev(4)
|
||||
OLD_FILES+=usr/share/man/man4/lindev.4.gz
|
||||
@ -727,6 +779,7 @@ OLD_FILES+=var/named/etc/namedb/master/localhost-forward.db
|
||||
OLD_FILES+=var/named/etc/namedb/master/localhost-reverse.db
|
||||
#OLD_FILES+=var/named/etc/namedb/named.conf # intentionally left out
|
||||
OLD_FILES+=var/named/etc/namedb/named.root
|
||||
OLD_DIRS+=var/named/etc/namedb/working
|
||||
OLD_DIRS+=var/named/etc/namedb/slave
|
||||
OLD_DIRS+=var/named/var
|
||||
OLD_DIRS+=var/named/var/dump
|
||||
|
25
UPDATING
25
UPDATING
@ -31,6 +31,25 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20150118:
|
||||
Clang and llvm have been upgraded to 3.5.1 release. This is a bugfix
|
||||
only release, no new features have been added. Please see the 20141231
|
||||
entry below for information about prerequisites and upgrading, if you
|
||||
are not already using 3.5.0.
|
||||
|
||||
20150107:
|
||||
ELF tools addr2line, elfcopy (strip), nm, size, and strings are now
|
||||
taken from the ELF Tool Chain project rather than GNU binutils. They
|
||||
should be drop-in replacements, with the addition of arm64 support.
|
||||
The WITHOUT_ELFTOOLCHAIN_TOOLS= knob may be used to obtain the
|
||||
binutils tools, if necessary.
|
||||
|
||||
20150105:
|
||||
The default Unbound configuration now enables remote control
|
||||
using a local socket. Users who have already enabled the
|
||||
local_unbound service should regenerate their configuration
|
||||
by running "service local_unbound setup" as root.
|
||||
|
||||
20150102:
|
||||
The GNU texinfo and GNU info pages have been removed.
|
||||
To be able to view GNU info pages please install texinfo from ports.
|
||||
@ -114,7 +133,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
LOCAL_DIRS.
|
||||
|
||||
20141109:
|
||||
faith(4) and faithd(8) has been removed from base system. It
|
||||
faith(4) and faithd(8) have been removed from the base system. Faith
|
||||
has been obsolete for a very long time.
|
||||
|
||||
20141104:
|
||||
@ -137,7 +156,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
|
||||
20141102:
|
||||
pjdfstest has been integrated into kyua as an opt-in test suite.
|
||||
Please see share/doc/pjdfstest/README for a more details on how to
|
||||
Please see share/doc/pjdfstest/README for more details on how to
|
||||
execute it.
|
||||
|
||||
20141009:
|
||||
@ -159,7 +178,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
|
||||
20140729:
|
||||
The ofwfb driver, used to provide a graphics console on PowerPC when
|
||||
using vt(4), no longer allows mmap() of all of physical memory. This
|
||||
using vt(4), no longer allows mmap() of all physical memory. This
|
||||
will prevent Xorg on PowerPC with some ATI graphics cards from
|
||||
initializing properly unless x11-servers/xorg-server is updated to
|
||||
1.12.4_8 or newer.
|
||||
|
@ -1,6 +1,12 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PROG= cat
|
||||
|
||||
.if ${MK_TESTS} != "no"
|
||||
SUBDIR+= tests
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
18
bin/cat/tests/Makefile
Normal file
18
bin/cat/tests/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
|
||||
OBJTOP= ${.OBJDIR}/../../..
|
||||
SRCTOP= ${.CURDIR}/../../..
|
||||
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/bin/cat
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/bin/cat
|
||||
|
||||
NETBSD_ATF_TESTS_SH= cat_test
|
||||
|
||||
FILESDIR= ${TESTSDIR}
|
||||
|
||||
FILES= d_align.in
|
||||
FILES+= d_align.out
|
||||
|
||||
.include <netbsd-tests.test.mk>
|
||||
|
||||
.include <bsd.test.mk>
|
@ -93,7 +93,7 @@ GENHDRS+= iconv.h
|
||||
SRCS+= iconv_stub.c
|
||||
|
||||
iconv.h: ${.CURDIR}/iconv_stub.h
|
||||
cp -f ${.CURDIR}/iconv_stub.h ${.TARGET}
|
||||
${CP} ${.CURDIR}/iconv_stub.h ${.TARGET}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
|
@ -1,9 +1,15 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PROG= expr
|
||||
SRCS= expr.y
|
||||
YFLAGS=
|
||||
|
||||
NO_WMISSING_VARIABLE_DECLARATIONS=
|
||||
|
||||
.if ${MK_TESTS} != "no"
|
||||
SUBDIR+= tests
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
16
bin/expr/tests/Makefile
Normal file
16
bin/expr/tests/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
OBJTOP= ${.OBJDIR}/../../..
|
||||
SRCTOP= ${.CURDIR}/../../..
|
||||
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/bin/expr
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/bin/expr
|
||||
|
||||
NETBSD_ATF_TESTS_SH= expr_test
|
||||
|
||||
ATF_TESTS_SH_SED_expr_test+= -e 's/eval expr/eval expr --/g'
|
||||
ATF_TESTS_SH_SED_expr_test+= -e 's/"expr: integer overflow or underflow occurred for operation.*"/"expr: overflow"/g'
|
||||
|
||||
.include <netbsd-tests.test.mk>
|
||||
|
||||
.include <bsd.test.mk>
|
@ -43,11 +43,11 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <libgen.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
|
||||
@ -101,7 +101,7 @@ static int g_grabanon = 0;
|
||||
static const char *g_ofile = NULL;
|
||||
static FILE *g_ofp;
|
||||
static dtrace_hdl_t *g_dtp;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static char *g_etcfile = "/etc/system";
|
||||
static const char *g_etcbegin = "* vvvv Added by DTrace";
|
||||
static const char *g_etcend = "* ^^^^ Added by DTrace";
|
||||
@ -211,7 +211,7 @@ fatal(const char *fmt, ...)
|
||||
static void
|
||||
dfatal(const char *fmt, ...)
|
||||
{
|
||||
#if !defined(sun) && defined(NEED_ERRLOC)
|
||||
#if !defined(illumos) && defined(NEED_ERRLOC)
|
||||
char *p_errfile = NULL;
|
||||
int errline = 0;
|
||||
#endif
|
||||
@ -232,7 +232,7 @@ dfatal(const char *fmt, ...)
|
||||
(void) fprintf(stderr, "%s\n",
|
||||
dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
|
||||
}
|
||||
#if !defined(sun) && defined(NEED_ERRLOC)
|
||||
#if !defined(illumos) && defined(NEED_ERRLOC)
|
||||
dt_get_errloc(g_dtp, &p_errfile, &errline);
|
||||
if (p_errfile != NULL)
|
||||
printf("File '%s', line %d\n", p_errfile, errline);
|
||||
@ -397,7 +397,7 @@ dof_prune(const char *fname)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static void
|
||||
etcsystem_prune(void)
|
||||
{
|
||||
@ -508,7 +508,7 @@ etcsystem_add(void)
|
||||
|
||||
error("added forceload directives to %s\n", g_ofile);
|
||||
}
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
|
||||
static void
|
||||
print_probe_info(const dtrace_probeinfo_t *p)
|
||||
@ -643,7 +643,7 @@ anon_prog(const dtrace_cmd_t *dcp, dof_hdr_t *dof, int n)
|
||||
p = (uchar_t *)dof;
|
||||
q = p + dof->dofh_loadsz;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
oprintf("dof-data-%d=0x%x", n, *p++);
|
||||
|
||||
while (p < q)
|
||||
@ -793,7 +793,7 @@ compile_str(dtrace_cmd_t *dcp)
|
||||
static void
|
||||
prochandler(struct ps_prochandle *P, const char *msg, void *arg)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const psinfo_t *prp = Ppsinfo(P);
|
||||
int pid = Pstatus(P)->pr_pid;
|
||||
char name[SIG2STR_MAX];
|
||||
@ -807,13 +807,13 @@ prochandler(struct ps_prochandle *P, const char *msg, void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
switch (Pstate(P)) {
|
||||
#else
|
||||
switch (proc_state(P)) {
|
||||
#endif
|
||||
case PS_UNDEAD:
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Ideally we would like to always report pr_wstat here, but it
|
||||
* isn't possible given current /proc semantics. If we grabbed
|
||||
@ -831,7 +831,7 @@ prochandler(struct ps_prochandle *P, const char *msg, void *arg)
|
||||
notice("pid %d terminated by %d\n", pid,
|
||||
WTERMSIG(wstatus));
|
||||
#endif
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
} else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {
|
||||
notice("pid %d exited with status %d\n",
|
||||
pid, WEXITSTATUS(prp->pr_wstat));
|
||||
@ -1238,7 +1238,7 @@ installsighands(void)
|
||||
if (sigaction(SIGTERM, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
|
||||
(void) sigaction(SIGTERM, &act, NULL);
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (sigaction(SIGPIPE, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
|
||||
(void) sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
@ -1720,7 +1720,7 @@ main(int argc, char *argv[])
|
||||
|
||||
case DMODE_ANON:
|
||||
if (g_ofile == NULL)
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
g_ofile = "/kernel/drv/dtrace.conf";
|
||||
#else
|
||||
/*
|
||||
@ -1732,7 +1732,7 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
dof_prune(g_ofile); /* strip out any old DOF directives */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
etcsystem_prune(); /* string out any forceload directives */
|
||||
#endif
|
||||
|
||||
@ -1765,7 +1765,7 @@ main(int argc, char *argv[])
|
||||
* that itself contains a #pragma D option quiet.
|
||||
*/
|
||||
error("saved anonymous enabling in %s\n", g_ofile);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
etcsystem_add();
|
||||
error("run update_drv(1M) or reboot to enable changes\n");
|
||||
#endif
|
||||
|
@ -46,10 +46,9 @@
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#define GETOPT_EOF EOF
|
||||
#else
|
||||
/* FreeBSD */
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
@ -57,7 +56,7 @@
|
||||
#define GETOPT_EOF (-1)
|
||||
|
||||
typedef uintptr_t pc_t;
|
||||
#endif /* defined(sun) */
|
||||
#endif
|
||||
|
||||
#define LOCKSTAT_OPTSTR "x:bths:n:d:i:l:f:e:ckwWgCHEATID:RpPo:V"
|
||||
|
||||
@ -214,10 +213,9 @@ static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
|
||||
{ 'H', "Lock", "Unknown event (type 53)", "units" },
|
||||
{ 'H', "Lock", "Unknown event (type 54)", "units" },
|
||||
{ 'H', "Lock", "Unknown event (type 55)", "units" },
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
{ 'I', "CPU+PIL", "Profiling interrupt", "nsec",
|
||||
#else
|
||||
/* FreeBSD */
|
||||
{ 'I', "CPU+Pri_Class", "Profiling interrupt", "nsec",
|
||||
#endif
|
||||
"profile:::profile-97", NULL },
|
||||
@ -231,7 +229,7 @@ static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
|
||||
{ 'E', "Lock", "Lockstat record failure", "(N/A)" },
|
||||
};
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
static char *g_pri_class[] = {
|
||||
"",
|
||||
"Intr",
|
||||
@ -598,7 +596,7 @@ filter_add(char **filt, char *what, uintptr_t base, uintptr_t size)
|
||||
*filt[0] = '\0';
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) sprintf(c, "%s(%s >= 0x%p && %s < 0x%p)", *filt[0] != '\0' ?
|
||||
" || " : "", what, (void *)base, what, (void *)(base + size));
|
||||
#else
|
||||
@ -676,7 +674,7 @@ dprog_addevent(int event)
|
||||
* the number of nanoseconds) is the number of nanoseconds
|
||||
* late -- and it's stored in arg2.
|
||||
*/
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
arg0 = "(uintptr_t)curthread->t_cpu + \n"
|
||||
"\t curthread->t_cpu->cpu_profile_pil";
|
||||
#else
|
||||
@ -824,7 +822,7 @@ dprog_compile()
|
||||
}
|
||||
|
||||
static void
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
status_fire(void)
|
||||
#else
|
||||
status_fire(int i)
|
||||
@ -1423,7 +1421,7 @@ main(int argc, char **argv)
|
||||
exit(127);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
while (waitpid(child, &status, WEXITED) != child)
|
||||
#else
|
||||
while (waitpid(child, &status, 0) != child)
|
||||
@ -1468,7 +1466,7 @@ main(int argc, char **argv)
|
||||
dfail("failed to walk aggregate");
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if ((data_buf = memalign(sizeof (uint64_t),
|
||||
(g_nrecs + 1) * g_recsize)) == NULL)
|
||||
#else
|
||||
@ -1500,7 +1498,7 @@ main(int argc, char **argv)
|
||||
if (g_gflag) {
|
||||
lsrec_t *newlsp, *oldlsp;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
newlsp = memalign(sizeof (uint64_t),
|
||||
g_nrecs_used * LS_TIME * (g_stkdepth + 1));
|
||||
#else
|
||||
@ -1664,7 +1662,7 @@ format_symbol(char *buf, uintptr_t addr, int show_size)
|
||||
else if (symoff == 0)
|
||||
(void) sprintf(buf, "%s", symname);
|
||||
else if (symoff < 16 && bcmp(symname, "cpu[", 4) == 0) /* CPU+PIL */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) sprintf(buf, "%s+%ld", symname, (long)symoff);
|
||||
#else
|
||||
(void) sprintf(buf, "%s+%s", symname, g_pri_class[(int)symoff]);
|
||||
|
@ -42,12 +42,11 @@
|
||||
#include <libelf.h>
|
||||
#include <link.h>
|
||||
#include <elf.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/machelf.h>
|
||||
|
||||
#include <kstat.h>
|
||||
#else
|
||||
/* FreeBSD */
|
||||
#include <sys/elf.h>
|
||||
#include <sys/ksyms.h>
|
||||
#include <sys/param.h>
|
||||
@ -66,7 +65,7 @@ static syment_t *symbol_table;
|
||||
static int nsyms, maxsyms;
|
||||
static char maxsymname[64];
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#ifdef _ELF64
|
||||
#define elf_getshdr elf64_getshdr
|
||||
#else
|
||||
@ -105,7 +104,7 @@ remove_symbol(uintptr_t addr)
|
||||
sep->addr = 0;
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static void
|
||||
fake_up_certain_popular_kernel_symbols(void)
|
||||
{
|
||||
@ -133,8 +132,7 @@ fake_up_certain_popular_kernel_symbols(void)
|
||||
}
|
||||
(void) kstat_close(kc);
|
||||
}
|
||||
#else
|
||||
/* FreeBSD */
|
||||
#else /* !illumos */
|
||||
static void
|
||||
fake_up_certain_popular_kernel_symbols(void)
|
||||
{
|
||||
@ -151,7 +149,7 @@ fake_up_certain_popular_kernel_symbols(void)
|
||||
add_symbol(name, addr, sizeof (uintptr_t));
|
||||
}
|
||||
}
|
||||
#endif /* !defined(sun) */
|
||||
#endif /* illumos */
|
||||
|
||||
static int
|
||||
symcmp(const void *p1, const void *p2)
|
||||
@ -177,12 +175,12 @@ symtab_init(void)
|
||||
int fd;
|
||||
int i;
|
||||
int strindex = -1;
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
void *ksyms;
|
||||
size_t sz;
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#ifndef illumos
|
||||
if ((fd = open("/dev/ksyms", O_RDONLY)) == -1) {
|
||||
if (errno == ENOENT && modfind("ksyms") == -1) {
|
||||
kldload("ksyms");
|
||||
@ -196,12 +194,11 @@ symtab_init(void)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) elf_version(EV_CURRENT);
|
||||
|
||||
elf = elf_begin(fd, ELF_C_READ, NULL);
|
||||
#else
|
||||
/* FreeBSD */
|
||||
/*
|
||||
* XXX - libelf needs to be fixed so it will work with
|
||||
* non 'ordinary' files like /dev/ksyms. The following
|
||||
|
@ -40,7 +40,7 @@ die(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int err = errno;
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
const char *progname = getprogname();
|
||||
#endif
|
||||
|
||||
@ -54,7 +54,7 @@ die(char *format, ...)
|
||||
if (format[strlen(format) - 1] != '\n')
|
||||
(void) fprintf(stderr, ": %s\n", strerror(err));
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#ifndef illumos
|
||||
exit(0);
|
||||
#else
|
||||
exit(1);
|
||||
@ -65,7 +65,7 @@ void
|
||||
elfdie(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
const char *progname = getprogname();
|
||||
#endif
|
||||
|
||||
@ -79,7 +79,7 @@ elfdie(char *format, ...)
|
||||
if (format[strlen(format) - 1] != '\n')
|
||||
(void) fprintf(stderr, ": %s\n", elf_errmsg(elf_errno()));
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#ifndef illumos
|
||||
exit(0);
|
||||
#else
|
||||
exit(1);
|
||||
|
@ -40,7 +40,7 @@ extern int findelfsecidx(Elf *, char *);
|
||||
extern void die(char *, ...);
|
||||
extern void elfdie(char *, ...);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
extern const char *progname;
|
||||
#endif
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
#endif
|
||||
|
||||
@ -505,7 +505,7 @@ getsym(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size,
|
||||
{
|
||||
char name[256];
|
||||
GElf_Sym sym;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
prsyminfo_t info;
|
||||
#else
|
||||
prmap_t *map;
|
||||
@ -518,7 +518,7 @@ getsym(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size,
|
||||
(void) snprintf(buf, size, "%#lx", addr);
|
||||
return (0);
|
||||
}
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (info.prs_object == NULL)
|
||||
info.prs_object = "<unknown>";
|
||||
|
||||
@ -668,7 +668,7 @@ process_aggregate(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
|
||||
static void
|
||||
prochandler(struct ps_prochandle *P, const char *msg, void *arg)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const psinfo_t *prp = Ppsinfo(P);
|
||||
int pid = Pstatus(P)->pr_pid;
|
||||
#else
|
||||
@ -773,7 +773,7 @@ intr(int signo)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
ucred_t *ucp;
|
||||
#endif
|
||||
int err;
|
||||
@ -785,7 +785,7 @@ main(int argc, char **argv)
|
||||
|
||||
g_pname = basename(argv[0]);
|
||||
argv[0] = g_pname; /* rewrite argv[0] for getopt errors */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Make sure we have the required dtrace_proc privilege.
|
||||
*/
|
||||
@ -988,7 +988,7 @@ main(int argc, char **argv)
|
||||
|
||||
if (opt_v)
|
||||
(void) printf("%s: tracing enabled for pid %d\n", g_pname,
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(int)Pstatus(g_pr)->pr_pid);
|
||||
#else
|
||||
(int)proc_getpid(g_pr));
|
||||
|
@ -39,7 +39,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/machelf.h>
|
||||
#else
|
||||
#include <sys/elf.h>
|
||||
|
@ -48,7 +48,7 @@ extern "C" {
|
||||
|
||||
#ifndef _ASM
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/machelf.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
|
@ -65,7 +65,7 @@
|
||||
#include <zfs_prop.h>
|
||||
#include <zfs_deleg.h>
|
||||
#include <libuutil.h>
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
#include <aclutils.h>
|
||||
#include <directory.h>
|
||||
#include <idmap.h>
|
||||
@ -2391,7 +2391,7 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
|
||||
/* SMB */
|
||||
char sid[ZFS_MAXNAMELEN + 32];
|
||||
uid_t id;
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
int err;
|
||||
int flag = IDMAP_REQ_FLG_USE_CACHE;
|
||||
#endif
|
||||
@ -2402,17 +2402,17 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
|
||||
|
||||
if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) {
|
||||
type = USTYPE_SMB_GRP;
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
err = sid_to_id(sid, B_FALSE, &id);
|
||||
#endif
|
||||
} else {
|
||||
type = USTYPE_SMB_USR;
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
err = sid_to_id(sid, B_TRUE, &id);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (err == 0) {
|
||||
rid = id;
|
||||
if (!cb->cb_sid2posix) {
|
||||
@ -6110,7 +6110,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
||||
/*
|
||||
* Search for the given (major,minor) pair in the mount table.
|
||||
*/
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
rewind(mnttab_file);
|
||||
while ((ret = getextmntent(mnttab_file, &entry, 0)) == 0) {
|
||||
if (entry.mnt_major == major(statbuf.st_dev) &&
|
||||
|
@ -112,7 +112,7 @@ vdev_error(const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
static void
|
||||
libdiskmgt_error(int error)
|
||||
{
|
||||
@ -274,7 +274,7 @@ check_device(const char *path, boolean_t force, boolean_t isspare)
|
||||
|
||||
return (check_slice(path, force, B_FALSE, isspare));
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
/*
|
||||
* Check that a file is valid. All we can do in this case is check that it's
|
||||
@ -290,7 +290,7 @@ check_file(const char *file, boolean_t force, boolean_t isspare)
|
||||
pool_state_t state;
|
||||
boolean_t inuse;
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (dm_inuse_swap(file, &err)) {
|
||||
if (err)
|
||||
libdiskmgt_error(err);
|
||||
@ -377,7 +377,7 @@ check_device(const char *name, boolean_t force, boolean_t isspare)
|
||||
static boolean_t
|
||||
is_whole_disk(const char *arg)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
struct dk_gpt *label;
|
||||
int fd;
|
||||
char path[MAXPATHLEN];
|
||||
@ -915,7 +915,7 @@ check_replication(nvlist_t *config, nvlist_t *newroot)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Go through and find any whole disks in the vdev specification, labelling them
|
||||
* as appropriate. When constructing the vdev spec, we were unable to open this
|
||||
@ -1019,7 +1019,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
/*
|
||||
* Determine if the given path is a hot spare within the given configuration.
|
||||
@ -1098,7 +1098,7 @@ is_device_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
|
||||
* regardless of what libdiskmgt or zpool_in_use() says.
|
||||
*/
|
||||
if (replacing) {
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
&wholedisk) == 0 && wholedisk)
|
||||
(void) snprintf(buf, sizeof (buf), "%ss0",
|
||||
@ -1422,7 +1422,7 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (!flags.dryrun && make_disks(zhp, newroot) != 0) {
|
||||
nvlist_free(newroot);
|
||||
return (NULL);
|
||||
@ -1507,7 +1507,7 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Run through the vdev specification and label any whole disks found.
|
||||
*/
|
||||
|
@ -44,7 +44,7 @@ extern "C" {
|
||||
* safe in probe context.
|
||||
*/
|
||||
|
||||
#if defined(sun) && (defined(_KERNEL) || defined(_BOOT))
|
||||
#if defined(illumos) && (defined(_KERNEL) || defined(_BOOT))
|
||||
|
||||
#define isalnum(ch) (isalpha(ch) || isdigit(ch))
|
||||
#define isalpha(ch) (isupper(ch) || islower(ch))
|
||||
|
@ -34,14 +34,14 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#include <gelf.h>
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#ifdef _LP64
|
||||
static const char *_libctf_zlib = "/usr/lib/64/libz.so";
|
||||
#else
|
||||
@ -58,7 +58,7 @@ static struct {
|
||||
static size_t _PAGESIZE;
|
||||
static size_t _PAGEMASK;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma init(_libctf_init)
|
||||
#else
|
||||
void _libctf_init(void) __attribute__ ((constructor));
|
||||
@ -66,7 +66,7 @@ void _libctf_init(void) __attribute__ ((constructor));
|
||||
void
|
||||
_libctf_init(void)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const char *p = getenv("LIBCTF_DECOMPRESSOR");
|
||||
|
||||
if (p != NULL)
|
||||
@ -87,7 +87,7 @@ _libctf_init(void)
|
||||
void *
|
||||
ctf_zopen(int *errp)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
ctf_dprintf("decompressing CTF data using %s\n", _libctf_zlib);
|
||||
|
||||
if (zlib.z_dlp != NULL)
|
||||
|
@ -56,13 +56,13 @@
|
||||
*/
|
||||
|
||||
static const char *devnamep = "/dev/dtrace/helper";
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static const char *olddevname = "/devices/pseudo/dtrace@0:helper";
|
||||
#endif
|
||||
|
||||
static const char *modname; /* Name of this load object */
|
||||
static int gen; /* DOF helper generation */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
extern dof_hdr_t __SUNW_dof; /* DOF defined in the .SUNW_dof section */
|
||||
#endif
|
||||
static boolean_t dof_init_debug = B_FALSE; /* From DTRACE_DOF_INIT_DEBUG */
|
||||
@ -90,7 +90,7 @@ dprintf(int debug, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma init(dtrace_dof_init)
|
||||
#else
|
||||
static void dtrace_dof_init(void) __attribute__ ((constructor));
|
||||
@ -99,7 +99,7 @@ static void dtrace_dof_init(void) __attribute__ ((constructor));
|
||||
static void
|
||||
dtrace_dof_init(void)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dof_hdr_t *dof = &__SUNW_dof;
|
||||
#else
|
||||
dof_hdr_t *dof = NULL;
|
||||
@ -111,14 +111,14 @@ dtrace_dof_init(void)
|
||||
#endif
|
||||
dof_helper_t dh;
|
||||
Link_map *lmp = NULL;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
Lmid_t lmid;
|
||||
#else
|
||||
u_long lmid = 0;
|
||||
#endif
|
||||
int fd;
|
||||
const char *p;
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
Elf *e;
|
||||
Elf_Scn *scn = NULL;
|
||||
Elf_Data *dofdata = NULL;
|
||||
@ -141,7 +141,7 @@ dtrace_dof_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dlinfo(RTLD_SELF, RTLD_DI_LMID, &lmid) == -1) {
|
||||
dprintf(1, "couldn't discover link map ID\n");
|
||||
return;
|
||||
@ -152,7 +152,7 @@ dtrace_dof_init(void)
|
||||
modname = lmp->l_name;
|
||||
else
|
||||
modname++;
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
elf_version(EV_CURRENT);
|
||||
if ((efd = open(lmp->l_name, O_RDONLY, 0)) < 0) {
|
||||
dprintf(1, "couldn't open file for reading\n");
|
||||
@ -215,7 +215,7 @@ dtrace_dof_init(void)
|
||||
|
||||
if ((fd = open64(devnamep, O_RDWR)) < 0) {
|
||||
dprintf(1, "failed to open helper device %s", devnamep);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*
|
||||
* If the device path wasn't explicitly set, try again with
|
||||
* the old device path.
|
||||
@ -237,14 +237,14 @@ dtrace_dof_init(void)
|
||||
dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
|
||||
else {
|
||||
dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof);
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
gen = dh.gen;
|
||||
#endif
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
/* End of while loop */
|
||||
dof = dof_next;
|
||||
}
|
||||
@ -254,7 +254,7 @@ dtrace_dof_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma fini(dtrace_dof_fini)
|
||||
#else
|
||||
static void dtrace_dof_fini(void) __attribute__ ((destructor));
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <unistd.h>
|
||||
#include <dt_impl.h>
|
||||
#include <assert.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#include <sys/sysctl.h>
|
||||
@ -453,7 +453,7 @@ dt_aggregate_snap_cpu(dtrace_hdl_t *dtp, processorid_t cpu)
|
||||
|
||||
buf->dtbd_cpu = cpu;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_AGGSNAP, buf) == -1) {
|
||||
#else
|
||||
if (dt_ioctl(dtp, DTRACEIOC_AGGSNAP, &buf) == -1) {
|
||||
|
@ -1888,7 +1888,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
|
||||
char **argv = malloc(sizeof (char *) * (argc + 5));
|
||||
FILE *ofp = tmpfile();
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
char ipath[20], opath[20]; /* big enough for /dev/fd/ + INT_MAX + \0 */
|
||||
#endif
|
||||
char verdef[32]; /* big enough for -D__SUNW_D_VERSION=0x%08x + \0 */
|
||||
@ -1898,7 +1898,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
|
||||
|
||||
int wstat, estat;
|
||||
pid_t pid;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
off64_t off;
|
||||
#else
|
||||
off_t off = 0;
|
||||
@ -1929,7 +1929,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
|
||||
(void) fseeko64(ifp, off, SEEK_SET);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) snprintf(ipath, sizeof (ipath), "/dev/fd/%d", fileno(ifp));
|
||||
(void) snprintf(opath, sizeof (opath), "/dev/fd/%d", fileno(ofp));
|
||||
#endif
|
||||
@ -1940,7 +1940,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
|
||||
"-D__SUNW_D_VERSION=0x%08x", dtp->dt_vmax);
|
||||
argv[argc++] = verdef;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
switch (dtp->dt_stdcmode) {
|
||||
case DT_STDC_XA:
|
||||
case DT_STDC_XT:
|
||||
@ -1982,7 +1982,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (isatty(fileno(ifp)) == 0)
|
||||
lseek(fileno(ifp), off, SEEK_SET);
|
||||
dup2(fileno(ifp), 0);
|
||||
|
@ -35,12 +35,12 @@
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <dt_impl.h>
|
||||
#include <dt_pq.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <libproc_compat.h>
|
||||
#endif
|
||||
|
||||
@ -2958,7 +2958,7 @@ dt_get_buf(dtrace_hdl_t *dtp, int cpu, dtrace_bufdesc_t **bufp)
|
||||
buf->dtbd_size = size;
|
||||
buf->dtbd_cpu = cpu;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
|
||||
#else
|
||||
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
|
||||
|
@ -26,12 +26,12 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#include <strings.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
@ -145,7 +145,7 @@ dtrace_errno(dtrace_hdl_t *dtp)
|
||||
return (dtp->dt_errno);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
int
|
||||
dt_set_errno(dtrace_hdl_t *dtp, int err)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
@ -28,18 +28,18 @@
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/procfs_isa.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/objfs.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <sys/bitmap.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ioccom.h>
|
||||
@ -45,7 +45,7 @@
|
||||
#include <libctf.h>
|
||||
#include <dtrace.h>
|
||||
#include <gelf.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <synch.h>
|
||||
#endif
|
||||
|
||||
@ -142,7 +142,7 @@ typedef struct dt_module {
|
||||
GElf_Addr dm_bss_va; /* virtual address of BSS */
|
||||
GElf_Xword dm_bss_size; /* size in bytes of BSS */
|
||||
dt_idhash_t *dm_extern; /* external symbol definitions */
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
caddr_t dm_reloc_offset; /* Symbol relocation offset. */
|
||||
uintptr_t *dm_sec_offsets;
|
||||
#endif
|
||||
@ -296,7 +296,7 @@ struct dtrace_hdl {
|
||||
int dt_version; /* library version requested by client */
|
||||
int dt_ctferr; /* error resulting from last CTF failure */
|
||||
int dt_errno; /* error resulting from last failed operation */
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
const char *dt_errfile;
|
||||
int dt_errline;
|
||||
#endif
|
||||
@ -305,7 +305,7 @@ struct dtrace_hdl {
|
||||
int dt_fterr; /* saved errno from failed open of dt_ftfd */
|
||||
int dt_cdefs_fd; /* file descriptor for C CTF debugging cache */
|
||||
int dt_ddefs_fd; /* file descriptor for D CTF debugging cache */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
int dt_stdout_fd; /* file descriptor for saved stdout */
|
||||
#else
|
||||
FILE *dt_freopen_fp; /* file pointer for freopened stdout */
|
||||
@ -596,7 +596,7 @@ extern int dt_version_defined(dt_version_t);
|
||||
extern char *dt_cpp_add_arg(dtrace_hdl_t *, const char *);
|
||||
extern char *dt_cpp_pop_arg(dtrace_hdl_t *);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
extern int dt_set_errno(dtrace_hdl_t *, int);
|
||||
#else
|
||||
int _dt_set_errno(dtrace_hdl_t *, int, const char *, int);
|
||||
@ -606,7 +606,7 @@ void dt_get_errloc(dtrace_hdl_t *, const char **, int *);
|
||||
extern void dt_set_errmsg(dtrace_hdl_t *, const char *, const char *,
|
||||
const char *, int, const char *, va_list);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
extern int dt_ioctl(dtrace_hdl_t *, int, void *);
|
||||
#else
|
||||
extern int dt_ioctl(dtrace_hdl_t *, u_long, void *);
|
||||
|
@ -44,7 +44,7 @@
|
||||
* We need to undefine lex's input and unput macros so that references to these
|
||||
* call the functions provided at the end of this source file.
|
||||
*/
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#undef input
|
||||
#undef unput
|
||||
#else
|
||||
@ -79,7 +79,7 @@
|
||||
#endif
|
||||
|
||||
static int id_or_type(const char *);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static int input(void);
|
||||
static void unput(int);
|
||||
#endif
|
||||
@ -740,7 +740,7 @@ yyinit(dt_pcb_t *pcb)
|
||||
yypcb = pcb;
|
||||
yylineno = 1;
|
||||
yypragma = NULL;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
yysptr = yysbuf;
|
||||
#endif
|
||||
}
|
||||
@ -838,7 +838,7 @@ id_or_type(const char *s)
|
||||
return (ttok);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static int
|
||||
input(void)
|
||||
{
|
||||
@ -880,4 +880,4 @@ unput(int c)
|
||||
*yysptr++ = c;
|
||||
yytchar = c;
|
||||
}
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <elf.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#else
|
||||
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
@ -47,7 +47,7 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <wait.h>
|
||||
#else
|
||||
#include <sys/wait.h>
|
||||
@ -322,7 +322,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
|
||||
char *strtab;
|
||||
int i, j, nrel;
|
||||
size_t strtabsz = 1;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
uint32_t count = 0;
|
||||
#else
|
||||
uint64_t count = 0;
|
||||
@ -434,7 +434,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
|
||||
#elif defined(__i386) || defined(__amd64)
|
||||
rel->r_offset = s->dofs_offset +
|
||||
dofr[j].dofr_offset;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
rel->r_info = ELF64_R_INFO(count + dep->de_global,
|
||||
R_AMD64_64);
|
||||
#else
|
||||
@ -711,7 +711,7 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
|
||||
|
||||
shp = &elf_file.shdr[ESHDR_DOF];
|
||||
shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
shp->sh_flags = SHF_ALLOC;
|
||||
#else
|
||||
shp->sh_flags = SHF_WRITE | SHF_ALLOC;
|
||||
@ -1613,7 +1613,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
||||
return (dt_link_error(dtp, elf, fd, bufs,
|
||||
"failed to allocate space for probe"));
|
||||
}
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
/*
|
||||
* Our linker doesn't understand the SUNW_IGNORE ndx and
|
||||
* will try to use this relocation when we build the
|
||||
@ -1647,7 +1647,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
||||
* already been processed by an earlier link
|
||||
* invocation.
|
||||
*/
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#define SHN_SUNW_IGNORE SHN_ABS
|
||||
#endif
|
||||
if (rsym.st_shndx != SHN_SUNW_IGNORE) {
|
||||
@ -1663,7 +1663,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
||||
(void) elf_end(elf);
|
||||
(void) close(fd);
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (nsym > 0)
|
||||
#endif
|
||||
while ((pair = bufs) != NULL) {
|
||||
@ -1684,7 +1684,7 @@ int
|
||||
dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
const char *file, int objc, char *const objv[])
|
||||
{
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
char tfile[PATH_MAX];
|
||||
#endif
|
||||
char drti[PATH_MAX];
|
||||
@ -1694,7 +1694,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
size_t len;
|
||||
int eprobes = 0, ret = 0;
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (access(file, R_OK) == 0) {
|
||||
fprintf(stderr, "dtrace: target object (%s) already exists. "
|
||||
"Please remove the target\ndtrace: object and rebuild all "
|
||||
@ -1770,7 +1770,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL)
|
||||
return (-1); /* errno is set for us */
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Create a temporary file and then unlink it if we're going to
|
||||
* combine it with drti.o later. We can still refer to it in child
|
||||
@ -1816,7 +1816,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
}
|
||||
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (!dtp->dt_lazyload)
|
||||
(void) unlink(file);
|
||||
#endif
|
||||
@ -1826,7 +1826,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
else
|
||||
status = dump_elf32(dtp, dof, fd);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
|
||||
return (dt_link_error(dtp, NULL, -1, NULL,
|
||||
"failed to write %s: %s", file, strerror(errno)));
|
||||
@ -1839,7 +1839,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
#endif
|
||||
|
||||
if (!dtp->dt_lazyload) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s";
|
||||
|
||||
if (dtp->dt_oflags & DTRACE_O_LP64) {
|
||||
@ -1912,7 +1912,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
||||
done:
|
||||
dtrace_dof_destroy(dtp, dof);
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
unlink(tfile);
|
||||
#endif
|
||||
return (ret);
|
||||
|
@ -156,7 +156,7 @@ dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
|
||||
enabled->dtepd_epid = id;
|
||||
enabled->dtepd_nrecs = 1;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled) == -1) {
|
||||
#else
|
||||
if (dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled) == -1) {
|
||||
@ -180,7 +180,7 @@ dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
|
||||
if ((enabled = nenabled) == NULL)
|
||||
return (dt_set_errno(dtp, EDT_NOMEM));
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled);
|
||||
#else
|
||||
rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled);
|
||||
@ -356,7 +356,7 @@ dt_aggid_add(dtrace_hdl_t *dtp, dtrace_aggid_t id)
|
||||
agg->dtagd_id = id;
|
||||
agg->dtagd_nrecs = 1;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg) == -1) {
|
||||
#else
|
||||
if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg) == -1) {
|
||||
@ -379,7 +379,7 @@ dt_aggid_add(dtrace_hdl_t *dtp, dtrace_aggid_t id)
|
||||
if ((agg = nagg) == NULL)
|
||||
return (dt_set_errno(dtp, EDT_NOMEM));
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg);
|
||||
#else
|
||||
rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg);
|
||||
|
@ -27,7 +27,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/modctl.h>
|
||||
#include <sys/kobj.h>
|
||||
#include <sys/kobj_impl.h>
|
||||
@ -41,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <project.h>
|
||||
#endif
|
||||
#include <strings.h>
|
||||
@ -51,7 +51,7 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <fcntl.h>
|
||||
#include <libproc_compat.h>
|
||||
#endif
|
||||
@ -572,7 +572,7 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
|
||||
if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
|
||||
return (0);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
ctsp->cts_data = dp->d_buf;
|
||||
#else
|
||||
if ((ctsp->cts_data = malloc(dp->d_size)) == NULL)
|
||||
@ -921,7 +921,7 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
|
||||
ctf_close(dmp->dm_ctfp);
|
||||
dmp->dm_ctfp = NULL;
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (dmp->dm_ctdata.cts_data != NULL) {
|
||||
free(dmp->dm_ctdata.cts_data);
|
||||
}
|
||||
@ -1115,7 +1115,7 @@ dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
|
||||
* including the path.
|
||||
*/
|
||||
static void
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_module_update(dtrace_hdl_t *dtp, const char *name)
|
||||
#else
|
||||
dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
|
||||
@ -1132,7 +1132,7 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
|
||||
Elf_Data *dp;
|
||||
Elf_Scn *sp;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) snprintf(fname, sizeof (fname),
|
||||
"%s/%s/object", OBJFS_ROOT, name);
|
||||
#else
|
||||
@ -1242,7 +1242,7 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
|
||||
}
|
||||
|
||||
dmp->dm_flags |= DT_DM_KERNEL;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);
|
||||
#else
|
||||
/*
|
||||
@ -1265,7 +1265,7 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
|
||||
if (dmp->dm_info.objfs_info_primary)
|
||||
dmp->dm_flags |= DT_DM_PRIMARY;
|
||||
@ -1291,7 +1291,7 @@ dtrace_update(dtrace_hdl_t *dtp)
|
||||
dmp != NULL; dmp = dt_list_next(dmp))
|
||||
dt_module_unload(dtp, dmp);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Open /system/object and attempt to create a libdtrace module for
|
||||
* each kernel module that is loaded on the current system.
|
||||
@ -1331,11 +1331,11 @@ dtrace_update(dtrace_hdl_t *dtp)
|
||||
dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();
|
||||
dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);
|
||||
dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();
|
||||
#endif
|
||||
dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();
|
||||
#endif
|
||||
dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();
|
||||
|
@ -26,11 +26,10 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/modctl.h>
|
||||
#include <sys/systeminfo.h>
|
||||
#else
|
||||
/* FreeBSD */
|
||||
#include <sys/param.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/linker.h>
|
||||
@ -39,7 +38,7 @@
|
||||
|
||||
#include <libelf.h>
|
||||
#include <strings.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
@ -60,7 +59,7 @@
|
||||
#include <dt_printf.h>
|
||||
#include <dt_string.h>
|
||||
#include <dt_provider.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <sys/sysctl.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
@ -164,7 +163,7 @@ const dt_version_t _dtrace_versions[] = {
|
||||
/*
|
||||
* Global variables that are formatted on FreeBSD based on the kernel file name.
|
||||
*/
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
static char curthread_str[MAXPATHLEN];
|
||||
static char intmtx_str[MAXPATHLEN];
|
||||
static char threadmtx_str[MAXPATHLEN];
|
||||
@ -246,7 +245,7 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
{ "curthread", DT_IDENT_SCALAR, 0, DIF_VAR_CURTHREAD,
|
||||
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_PRIVATE,
|
||||
DTRACE_CLASS_COMMON }, DT_VERS_1_0,
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
&dt_idops_type, "genunix`kthread_t *" },
|
||||
#else
|
||||
&dt_idops_type, curthread_str },
|
||||
@ -297,13 +296,13 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
{ "index", DT_IDENT_FUNC, 0, DIF_SUBR_INDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||
&dt_idops_func, "int(const char *, const char *, [int])" },
|
||||
{ "inet_ntoa", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA, DT_ATTR_STABCMN,
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
DT_VERS_1_5, &dt_idops_func, "string(ipaddr_t *)" },
|
||||
#else
|
||||
DT_VERS_1_5, &dt_idops_func, "string(in_addr_t *)" },
|
||||
#endif
|
||||
{ "inet_ntoa6", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA6, DT_ATTR_STABCMN,
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
DT_VERS_1_5, &dt_idops_func, "string(in6_addr_t *)" },
|
||||
#else
|
||||
DT_VERS_1_5, &dt_idops_func, "string(struct in6_addr *)" },
|
||||
@ -328,7 +327,7 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
&dt_idops_func, "void(@)" },
|
||||
{ "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||
&dt_idops_func, "uintptr_t *(void *, size_t)" },
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
{ "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "string(void *, char, size_t)" },
|
||||
#endif
|
||||
@ -342,7 +341,7 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
{ "msgsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGSIZE,
|
||||
DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "size_t(mblk_t *)" },
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
{ "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
|
||||
DT_ATTR_EVOLCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "int(genunix`kmutex_t *)" },
|
||||
@ -413,7 +412,7 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
&dt_idops_func, "int()" },
|
||||
{ "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||
&dt_idops_func, "int(const char *, const char *, [int])" },
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
{ "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER,
|
||||
DT_ATTR_EVOLCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "int(genunix`krwlock_t *)" },
|
||||
@ -471,7 +470,7 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
&dt_idops_func, "string(const char *, int, [int])" },
|
||||
{ "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "void(@)" },
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
{ "sx_isexclusive", DT_IDENT_FUNC, 0, DIF_SUBR_SX_ISEXCLUSIVE,
|
||||
DT_ATTR_EVOLCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, sxlock_str },
|
||||
@ -531,12 +530,12 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
{ "walltimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_WALLTIMESTAMP,
|
||||
DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||
&dt_idops_type, "int64_t" },
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
{ "zonename", DT_IDENT_SCALAR, 0, DIF_VAR_ZONENAME,
|
||||
DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
|
||||
#endif
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
{ "cpu", DT_IDENT_SCALAR, 0, DIF_VAR_CPU,
|
||||
DT_ATTR_STABCMN, DT_VERS_1_6_3, &dt_idops_type, "int" },
|
||||
#endif
|
||||
@ -780,7 +779,7 @@ const dtrace_pattr_t _dtrace_prvdesc = {
|
||||
{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
|
||||
};
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const char *_dtrace_defcpp = "/usr/ccs/lib/cpp"; /* default cpp(1) to invoke */
|
||||
const char *_dtrace_defld = "/usr/ccs/bin/ld"; /* default ld(1) to invoke */
|
||||
#else
|
||||
@ -789,7 +788,7 @@ const char *_dtrace_defld = "ld"; /* default ld(1) to invoke */
|
||||
#endif
|
||||
|
||||
const char *_dtrace_libdir = "/usr/lib/dtrace"; /* default library directory */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const char *_dtrace_provdir = "/dev/dtrace/provider"; /* provider directory */
|
||||
#else
|
||||
const char *_dtrace_provdir = "/dev/dtrace"; /* provider directory */
|
||||
@ -814,7 +813,7 @@ typedef struct dt_fdlist {
|
||||
uint_t df_size; /* size of df_fds[] */
|
||||
} dt_fdlist_t;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma init(_dtrace_init)
|
||||
#else
|
||||
void _dtrace_init(void) __attribute__ ((constructor));
|
||||
@ -850,7 +849,7 @@ dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
|
||||
dt_provmod_t *prov;
|
||||
char path[PATH_MAX];
|
||||
int fd;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
struct dirent *dp, *ep;
|
||||
DIR *dirp;
|
||||
|
||||
@ -897,7 +896,7 @@ dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
|
||||
}
|
||||
|
||||
(void) closedir(dirp);
|
||||
#else
|
||||
#else /* !illumos */
|
||||
char *p;
|
||||
char *p1;
|
||||
char *p_providers = NULL;
|
||||
@ -982,7 +981,7 @@ dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
|
||||
}
|
||||
if (p_providers != NULL)
|
||||
free(p_providers);
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -999,7 +998,7 @@ dt_provmod_destroy(dt_provmod_t **provmod)
|
||||
*provmod = NULL;
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static const char *
|
||||
dt_get_sysinfo(int cmd, char *buf, size_t len)
|
||||
{
|
||||
@ -1112,7 +1111,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
err = errno;
|
||||
}
|
||||
#endif
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
|
||||
#else
|
||||
ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
|
||||
@ -1154,7 +1153,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
|
||||
bzero(dtp, sizeof (dtrace_hdl_t));
|
||||
dtp->dt_oflags = flags;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
|
||||
#else
|
||||
dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
|
||||
@ -1170,7 +1169,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
dtp->dt_fterr = fterr;
|
||||
dtp->dt_cdefs_fd = -1;
|
||||
dtp->dt_ddefs_fd = -1;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dtp->dt_stdout_fd = -1;
|
||||
#else
|
||||
dtp->dt_freopen_fp = NULL;
|
||||
@ -1202,7 +1201,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
|
||||
dtp->dt_cpp_argv[0] = (char *)strbasename(dtp->dt_cpp_path);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) snprintf(isadef, sizeof (isadef), "-D__SUNW_D_%u",
|
||||
(uint_t)(sizeof (void *) * NBBY));
|
||||
|
||||
@ -1242,7 +1241,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
return (set_open_errno(dtp, errp, EDT_NOMEM));
|
||||
#endif
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#ifdef __x86
|
||||
/*
|
||||
* On x86 systems, __i386 is defined for <sys/isa_defs.h> for 32-bit
|
||||
@ -1282,7 +1281,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
* 'kern.bootfile' sysctl value tells us exactly which file is being
|
||||
* used as the kernel.
|
||||
*/
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
{
|
||||
char bootfile[MAXPATHLEN];
|
||||
char *p;
|
||||
@ -1644,7 +1643,7 @@ dtrace_close(dtrace_hdl_t *dtp)
|
||||
(void) close(dtp->dt_cdefs_fd);
|
||||
if (dtp->dt_ddefs_fd != -1)
|
||||
(void) close(dtp->dt_ddefs_fd);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dtp->dt_stdout_fd != -1)
|
||||
(void) close(dtp->dt_stdout_fd);
|
||||
#else
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
@ -871,7 +871,7 @@ dt_options_load(dtrace_hdl_t *dtp)
|
||||
bzero(&hdr, sizeof (dof_hdr_t));
|
||||
hdr.dofh_loadsz = sizeof (dof_hdr_t);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
|
||||
#else
|
||||
dof = &hdr;
|
||||
@ -889,7 +889,7 @@ dt_options_load(dtrace_hdl_t *dtp)
|
||||
for (i = 0; i < DTRACEOPT_MAX; i++)
|
||||
dtp->dt_options[i] = DTRACEOPT_UNSET;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
|
||||
#else
|
||||
if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
|
||||
|
@ -102,7 +102,7 @@
|
||||
#include <setjmp.h>
|
||||
#include <strings.h>
|
||||
#include <assert.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <libgen.h>
|
||||
@ -44,7 +44,7 @@
|
||||
#include <dt_program.h>
|
||||
#include <dt_pid.h>
|
||||
#include <dt_string.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <libproc_compat.h>
|
||||
#endif
|
||||
#include <dt_module.h>
|
||||
@ -74,7 +74,7 @@ typedef struct dt_pid_probe {
|
||||
static void
|
||||
dt_pid_objname(char *buf, size_t len, Lmid_t lmid, const char *obj)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (lmid == LM_ID_BASE)
|
||||
(void) strncpy(buf, obj, len);
|
||||
else
|
||||
@ -126,7 +126,7 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func)
|
||||
int isdash = strcmp("-", func) == 0;
|
||||
pid_t pid;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid = Pstatus(pp->dpp_pr)->pr_pid;
|
||||
#else
|
||||
pid = proc_getpid(pp->dpp_pr);
|
||||
@ -270,7 +270,7 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj)
|
||||
if (obj == NULL)
|
||||
return (0);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
|
||||
#endif
|
||||
|
||||
@ -279,7 +279,7 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj)
|
||||
pp->dpp_obj = obj;
|
||||
else
|
||||
pp->dpp_obj++;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym,
|
||||
NULL) == 0)
|
||||
pp->dpp_stret[0] = sym.st_value;
|
||||
@ -337,7 +337,7 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj)
|
||||
GELF_ST_INFO(STB_LOCAL, STT_FUNC);
|
||||
sym.st_other = 0;
|
||||
sym.st_value = 0;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel ==
|
||||
PR_MODEL_ILP32 ? -1U : -1ULL;
|
||||
#else
|
||||
@ -404,7 +404,7 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj)
|
||||
if (gmatch(obj, pp->dpp_mod))
|
||||
return (dt_pid_per_mod(pp, pmp, obj));
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
|
||||
#else
|
||||
pp->dpp_lmid = 0;
|
||||
@ -418,7 +418,7 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj)
|
||||
if (gmatch(pp->dpp_obj, pp->dpp_mod))
|
||||
return (dt_pid_per_mod(pp, pmp, obj));
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
|
||||
#endif
|
||||
|
||||
@ -468,7 +468,7 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P)
|
||||
else
|
||||
obj++;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Plmid(P, pmp->pr_vaddr, &lmid);
|
||||
#endif
|
||||
|
||||
@ -599,13 +599,13 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
|
||||
dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
|
||||
|
||||
dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sip.prs_lmid, mname);
|
||||
#else
|
||||
0, mname);
|
||||
#endif
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (fd == -1 &&
|
||||
(fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) {
|
||||
dt_dprintf("pr_open of helper device failed: %s\n",
|
||||
@ -618,7 +618,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (fd != -1)
|
||||
(void) pr_close(P, fd);
|
||||
#endif
|
||||
@ -634,13 +634,13 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
|
||||
int ret = 0;
|
||||
|
||||
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Pupdate_maps(P);
|
||||
if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) {
|
||||
ret = -1;
|
||||
(void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT,
|
||||
"failed to instantiate probes for pid %d: %s",
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(int)Pstatus(P)->pr_pid, strerror(errno));
|
||||
#else
|
||||
(int)proc_getpid(P), strerror(errno));
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <strings.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
@ -25,7 +25,7 @@
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#else
|
||||
#define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
@ -33,7 +33,7 @@
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
@ -467,7 +467,7 @@ pfprint_time(dtrace_hdl_t *dtp, FILE *fp, const char *format,
|
||||
* Below, we turn this into the canonical adb/mdb /[yY] format,
|
||||
* "1973 Dec 3 17:20:00".
|
||||
*/
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) ctime_r(&sec, src, sizeof (src));
|
||||
#else
|
||||
(void) ctime_r(&sec, src);
|
||||
@ -518,7 +518,7 @@ pfprint_port(dtrace_hdl_t *dtp, FILE *fp, const char *format,
|
||||
char buf[256];
|
||||
struct servent *sv, res;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if ((sv = getservbyport_r(port, NULL, &res, buf, sizeof (buf))) != NULL)
|
||||
#else
|
||||
if (getservbyport_r(port, NULL, &res, buf, sizeof (buf), &sv) > 0)
|
||||
@ -544,7 +544,7 @@ pfprint_inetaddr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
|
||||
s[size] = '\0';
|
||||
|
||||
if (strchr(s, ':') == NULL && inet_pton(AF_INET, s, inetaddr) != -1) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if ((host = gethostbyaddr_r(inetaddr, NS_INADDRSZ,
|
||||
AF_INET, &res, buf, sizeof (buf), &e)) != NULL)
|
||||
#else
|
||||
@ -694,7 +694,7 @@ static const dt_pfconv_t _dtrace_conversions[] = {
|
||||
{ "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr },
|
||||
{ "T", "s", "int64_t", pfcheck_time, pfprint_time822 },
|
||||
{ "u", "u", pfproto_xint, pfcheck_xint, pfprint_uint },
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
{ "wc", "wc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */
|
||||
{ "ws", "ws", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
|
||||
#else
|
||||
@ -1657,7 +1657,7 @@ dtrace_freopen(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
|
||||
if (rval == -1 || fp == NULL)
|
||||
return (rval);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (pfd->pfd_preflen != 0 &&
|
||||
strcmp(pfd->pfd_prefix, DT_FREOPEN_RESTORE) == 0) {
|
||||
/*
|
||||
@ -1739,7 +1739,7 @@ dtrace_freopen(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
|
||||
}
|
||||
|
||||
(void) fclose(nfp);
|
||||
#else
|
||||
#else /* !illumos */
|
||||
/*
|
||||
* The 'standard output' (which is not necessarily stdout)
|
||||
* treatment on FreeBSD is implemented differently than on
|
||||
@ -1814,7 +1814,7 @@ dtrace_freopen(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
|
||||
|
||||
/* Remember that the output has been redirected to the new file. */
|
||||
dtp->dt_freopen_fp = nfp;
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
@ -77,7 +77,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/lwp.h>
|
||||
#endif
|
||||
#include <strings.h>
|
||||
@ -89,7 +89,7 @@
|
||||
#include <dt_pid.h>
|
||||
#include <dt_impl.h>
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <sys/syscall.h>
|
||||
#include <libproc_compat.h>
|
||||
#define SYS_forksys SYS_fork
|
||||
@ -143,7 +143,7 @@ dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
|
||||
static void
|
||||
dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
|
||||
#else
|
||||
unsigned long pc;
|
||||
@ -152,14 +152,14 @@ dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
|
||||
|
||||
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
proc_regget(dpr->dpr_proc, REG_PC, &pc);
|
||||
proc_bkptregadj(&pc);
|
||||
#endif
|
||||
|
||||
for (dbp = dt_list_next(&dpr->dpr_bps);
|
||||
dbp != NULL; dbp = dt_list_next(dbp)) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (psp->pr_reg[R_PC] == dbp->dbp_addr)
|
||||
break;
|
||||
#else
|
||||
@ -170,7 +170,7 @@ dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
|
||||
|
||||
if (dbp == NULL) {
|
||||
dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
|
||||
#else
|
||||
(int)dpr->dpr_pid, pc);
|
||||
@ -342,7 +342,7 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname)
|
||||
}
|
||||
|
||||
(void) dt_proc_bpcreate(dpr, rdn.u.bptaddr,
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(dt_bkpt_f *)dt_proc_rdevent, (void *)evname);
|
||||
#else
|
||||
/* XXX ugly */
|
||||
@ -357,7 +357,7 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname)
|
||||
static void
|
||||
dt_proc_attach(dt_proc_t *dpr, int exec)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const pstatus_t *psp = Pstatus(dpr->dpr_proc);
|
||||
#endif
|
||||
rd_err_e err;
|
||||
@ -366,23 +366,23 @@ dt_proc_attach(dt_proc_t *dpr, int exec)
|
||||
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
|
||||
|
||||
if (exec) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (psp->pr_lwp.pr_errno != 0)
|
||||
return; /* exec failed: nothing needs to be done */
|
||||
#endif
|
||||
|
||||
dt_proc_bpdestroy(dpr, B_FALSE);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
Preset_maps(dpr->dpr_proc);
|
||||
#endif
|
||||
}
|
||||
if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL &&
|
||||
(err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT");
|
||||
#endif
|
||||
dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT");
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY");
|
||||
#endif
|
||||
} else {
|
||||
@ -507,7 +507,7 @@ dt_proc_control(void *arg)
|
||||
struct ps_prochandle *P = dpr->dpr_proc;
|
||||
int pid = dpr->dpr_pid;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
int pfd = Pctlfd(P);
|
||||
|
||||
const long wstop = PCWSTOP;
|
||||
@ -529,7 +529,7 @@ dt_proc_control(void *arg)
|
||||
*/
|
||||
(void) pthread_mutex_lock(&dpr->dpr_lock);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) Punsetflags(P, PR_ASYNC); /* require synchronous mode */
|
||||
(void) Psetflags(P, PR_BPTADJ); /* always adjust eip on x86 */
|
||||
(void) Punsetflags(P, PR_FORK); /* do not inherit on fork */
|
||||
@ -562,7 +562,7 @@ dt_proc_control(void *arg)
|
||||
* If PR_KLC is set, we created the process; otherwise we grabbed it.
|
||||
* Check for an appropriate stop request and wait for dt_proc_continue.
|
||||
*/
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (Pstatus(P)->pr_flags & PR_KLC)
|
||||
#else
|
||||
if (proc_getflags(P) & PR_KLC)
|
||||
@ -590,7 +590,7 @@ dt_proc_control(void *arg)
|
||||
while (!dpr->dpr_quit) {
|
||||
const lwpstatus_t *psp;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
|
||||
continue; /* check dpr_quit and continue waiting */
|
||||
#else
|
||||
@ -602,7 +602,7 @@ dt_proc_control(void *arg)
|
||||
|
||||
(void) pthread_mutex_lock(&dpr->dpr_lock);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pwait_locked:
|
||||
if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) {
|
||||
(void) pthread_mutex_unlock(&dpr->dpr_lock);
|
||||
@ -612,7 +612,7 @@ dt_proc_control(void *arg)
|
||||
|
||||
switch (Pstate(P)) {
|
||||
case PS_STOP:
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
psp = &Pstatus(P)->pr_lwp;
|
||||
#else
|
||||
psp = proc_getlwpstatus(P);
|
||||
@ -661,7 +661,7 @@ dt_proc_control(void *arg)
|
||||
break;
|
||||
|
||||
case PS_LOST:
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (Preopen(P) == 0)
|
||||
goto pwait_locked;
|
||||
#endif
|
||||
@ -734,7 +734,7 @@ dt_proc_t *
|
||||
dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)
|
||||
{
|
||||
dt_proc_hash_t *dph = dtp->dt_procs;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid_t pid = Pstatus(P)->pr_pid;
|
||||
#else
|
||||
pid_t pid = proc_getpid(P);
|
||||
@ -772,14 +772,14 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
|
||||
* an external debugger and we were waiting in dt_proc_waitrun().
|
||||
* Leave the process in this condition using PRELEASE_HANG.
|
||||
*/
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) {
|
||||
#else
|
||||
if (!(proc_getflags(dpr->dpr_proc) & (PR_KLC | PR_RLC))) {
|
||||
#endif
|
||||
dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid);
|
||||
rflag = PRELEASE_HANG;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
} else if (Pstatus(dpr->dpr_proc)->pr_flags & PR_KLC) {
|
||||
#else
|
||||
} else if (proc_getflags(dpr->dpr_proc) & PR_KLC) {
|
||||
@ -808,7 +808,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
|
||||
*/
|
||||
(void) pthread_mutex_lock(&dpr->dpr_lock);
|
||||
dpr->dpr_quit = B_TRUE;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
|
||||
#else
|
||||
pthread_kill(dpr->dpr_tid, SIGTHR);
|
||||
@ -880,7 +880,7 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
|
||||
|
||||
(void) sigfillset(&nset);
|
||||
(void) sigdelset(&nset, SIGABRT); /* unblocked for assert() */
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
(void) sigdelset(&nset, SIGCANCEL); /* see dt_proc_destroy() */
|
||||
#else
|
||||
(void) sigdelset(&nset, SIGUSR1); /* see dt_proc_destroy() */
|
||||
@ -912,7 +912,7 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
|
||||
* small amount of useful information to help figure it out.
|
||||
*/
|
||||
if (dpr->dpr_done) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
const psinfo_t *prp = Ppsinfo(dpr->dpr_proc);
|
||||
int stat = prp ? prp->pr_wstat : 0;
|
||||
int pid = dpr->dpr_pid;
|
||||
@ -963,7 +963,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
|
||||
(void) pthread_mutex_init(&dpr->dpr_lock, NULL);
|
||||
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
|
||||
#else
|
||||
if ((err = proc_create(file, argv, pcf, child_arg,
|
||||
@ -974,7 +974,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
|
||||
}
|
||||
|
||||
dpr->dpr_hdl = dtp;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid;
|
||||
#else
|
||||
dpr->dpr_pid = proc_getpid(dpr->dpr_proc);
|
||||
@ -1039,7 +1039,7 @@ dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor)
|
||||
(void) pthread_mutex_init(&dpr->dpr_lock, NULL);
|
||||
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) {
|
||||
#else
|
||||
if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) {
|
||||
@ -1174,7 +1174,7 @@ dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
|
||||
struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
|
||||
|
||||
if (P != NULL && idp != NULL && idp->di_id == 0) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */
|
||||
#else
|
||||
idp->di_id = proc_getpid(P); /* $target = created pid */
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
#include <limits.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
@ -25,7 +25,7 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#include <sys/isa_defs.h>
|
||||
@ -38,7 +38,7 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#include <sys/sysctl.h>
|
||||
@ -477,7 +477,7 @@ dt_dprintf(const char *format, ...)
|
||||
}
|
||||
|
||||
int
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
dt_ioctl(dtrace_hdl_t *dtp, int val, void *arg)
|
||||
#else
|
||||
dt_ioctl(dtrace_hdl_t *dtp, u_long val, void *arg)
|
||||
@ -485,7 +485,7 @@ dt_ioctl(dtrace_hdl_t *dtp, u_long val, void *arg)
|
||||
{
|
||||
const dtrace_vector_t *v = dtp->dt_vector;
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
/* Avoid sign extension. */
|
||||
val &= 0xffffffff;
|
||||
#endif
|
||||
@ -506,7 +506,7 @@ dt_status(dtrace_hdl_t *dtp, processorid_t cpu)
|
||||
const dtrace_vector_t *v = dtp->dt_vector;
|
||||
|
||||
if (v == NULL) {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
return (p_online(cpu, P_STATUS));
|
||||
#else
|
||||
int maxid = 0;
|
||||
@ -583,7 +583,7 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...)
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
/*
|
||||
* On FreeBSD, check if output is currently being re-directed
|
||||
* to another file. If so, output to that file instead of the
|
||||
@ -845,7 +845,7 @@ dt_popcb(const ulong_t *bp, ulong_t n)
|
||||
return (popc + dt_popc(bp[maxw] & ((1UL << maxb) - 1)));
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
struct _rwlock;
|
||||
struct _lwp_mutex;
|
||||
|
||||
@ -867,7 +867,7 @@ dt_rw_write_held(pthread_rwlock_t *lock)
|
||||
int
|
||||
dt_mutex_held(pthread_mutex_t *lock)
|
||||
{
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
extern int _mutex_held(struct _lwp_mutex *);
|
||||
return (_mutex_held((struct _lwp_mutex *)lock));
|
||||
#else
|
||||
|
@ -82,7 +82,7 @@ dtrace_sleep(dtrace_hdl_t *dtp)
|
||||
return; /* sleep duration has already past */
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
tv.tv_sec = (earliest - now) / NANOSEC;
|
||||
tv.tv_nsec = (earliest - now) % NANOSEC;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <stdio.h>
|
||||
#include <gelf.h>
|
||||
#include <libproc.h>
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#include <rtld_db.h>
|
||||
#endif
|
||||
|
||||
@ -554,7 +554,7 @@ extern int dtrace_probe_info(dtrace_hdl_t *,
|
||||
* entry point to obtain a library handle.
|
||||
*/
|
||||
struct dtrace_vector {
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
int (*dtv_ioctl)(void *, int, void *);
|
||||
#else
|
||||
int (*dtv_ioctl)(void *, u_long, void *);
|
||||
@ -605,7 +605,7 @@ extern int _dtrace_debug;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#define _SC_CPUID_MAX _SC_NPROCESSORS_CONF
|
||||
#define _SC_NPROCESSORS_MAX _SC_NPROCESSORS_CONF
|
||||
#endif
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <dis_tables.h>
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
#define PR_MODEL_ILP32 1
|
||||
#define PR_MODEL_LP64 2
|
||||
#include <libproc_compat.h>
|
||||
@ -88,7 +88,7 @@ dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
{
|
||||
ulong_t i;
|
||||
int size;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid_t pid = Pstatus(P)->pr_pid;
|
||||
char dmodel = Pstatus(P)->pr_dmodel;
|
||||
#else
|
||||
@ -144,7 +144,7 @@ dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
uint8_t *text;
|
||||
ulong_t i, end;
|
||||
int size;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid_t pid = Pstatus(P)->pr_pid;
|
||||
char dmodel = Pstatus(P)->pr_dmodel;
|
||||
#else
|
||||
@ -305,7 +305,7 @@ dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
uint8_t *text;
|
||||
ulong_t i;
|
||||
int size;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid_t pid = Pstatus(P)->pr_pid;
|
||||
char dmodel = Pstatus(P)->pr_dmodel;
|
||||
#else
|
||||
@ -388,7 +388,7 @@ dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
uint8_t *text;
|
||||
int size;
|
||||
ulong_t i, end = symp->st_size;
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
pid_t pid = Pstatus(P)->pr_pid;
|
||||
char dmodel = Pstatus(P)->pr_dmodel;
|
||||
#else
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#pragma weak gmatch = _gmatch
|
||||
|
||||
#include "gen_synonyms.h"
|
||||
@ -38,7 +38,7 @@
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <widec.h>
|
||||
#include "_range.h"
|
||||
#else
|
||||
|
@ -789,10 +789,10 @@ extern boolean_t libzfs_fru_compare(libzfs_handle_t *, const char *,
|
||||
extern boolean_t libzfs_fru_notself(libzfs_handle_t *, const char *);
|
||||
extern int zpool_fru_set(zpool_handle_t *, uint64_t, const char *);
|
||||
|
||||
#ifndef sun
|
||||
#ifndef illumos
|
||||
extern int zmount(const char *, const char *, int, char *, char *, int, char *,
|
||||
int);
|
||||
#endif /* !sun */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1112,7 +1112,7 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
|
||||
}
|
||||
case ZFS_PROP_MLSLABEL:
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Verify the mlslabel string and convert to
|
||||
* internal hex label string.
|
||||
@ -1161,11 +1161,11 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
|
||||
"invalid mlslabel '%s'"), strval);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
m_label_free(new_sl); /* OK if null */
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"mlslabel is not supported on FreeBSD"));
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
#endif /* !sun */
|
||||
#endif /* illumos */
|
||||
goto error;
|
||||
|
||||
}
|
||||
@ -2423,7 +2423,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
|
||||
case ZFS_PROP_MLSLABEL:
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
m_label_t *new_sl = NULL;
|
||||
char *ascii = NULL; /* human readable label */
|
||||
|
||||
@ -2457,9 +2457,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
|
||||
(void) strlcpy(propbuf, ascii, proplen);
|
||||
free(ascii);
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
propbuf[0] = '\0';
|
||||
#endif /* !sun */
|
||||
#endif /* illumos */
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2569,7 +2569,7 @@ static int
|
||||
idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
|
||||
char **domainp, idmap_rid_t *ridp)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
idmap_get_handle_t *get_hdl = NULL;
|
||||
idmap_stat status;
|
||||
int err = EINVAL;
|
||||
@ -2594,10 +2594,10 @@ idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
|
||||
if (get_hdl)
|
||||
idmap_get_destroy(get_hdl);
|
||||
return (err);
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
assert(!"invalid code path");
|
||||
return (EINVAL); // silence compiler warning
|
||||
#endif /* !sun */
|
||||
#endif /* illumos */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2632,7 +2632,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
|
||||
cp = strchr(propname, '@') + 1;
|
||||
|
||||
if (strchr(cp, '@')) {
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* It's a SID name (eg "user@domain") that needs to be
|
||||
* turned into S-1-domainID-RID.
|
||||
@ -2678,9 +2678,9 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
|
||||
cp = numericsid;
|
||||
*ridp = rid;
|
||||
/* will be further decoded below */
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
return (ENOENT);
|
||||
#endif /* !sun */
|
||||
#endif /* illumos */
|
||||
}
|
||||
|
||||
if (strncmp(cp, "S-1-", 4) == 0) {
|
||||
@ -4184,7 +4184,7 @@ zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
static int
|
||||
zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
|
||||
zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
|
||||
@ -4266,7 +4266,7 @@ zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
|
||||
return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
|
||||
oldname, newname));
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
int
|
||||
zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
|
||||
|
@ -494,7 +494,7 @@ find_shares_object(differ_info_t *di)
|
||||
(void) strlcat(fullpath, ZDIFF_SHARESDIR, MAXPATHLEN);
|
||||
|
||||
if (stat64(fullpath, &sb) != 0) {
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
(void) snprintf(di->errbuf, sizeof (di->errbuf),
|
||||
dgettext(TEXT_DOMAIN, "Cannot stat %s"), fullpath);
|
||||
return (zfs_error(di->zhp->zfs_hdl, EZFS_DIFF, di->errbuf));
|
||||
|
@ -952,7 +952,7 @@ slice_cache_compare(const void *arg1, const void *arg2)
|
||||
return (rv > 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
static void
|
||||
check_one_slice(avl_tree_t *r, char *diskname, uint_t partno,
|
||||
diskaddr_t size, uint_t blksz)
|
||||
@ -975,12 +975,12 @@ check_one_slice(avl_tree_t *r, char *diskname, uint_t partno,
|
||||
(node = avl_find(r, &tmpnode, NULL)))
|
||||
node->rn_nozpool = B_TRUE;
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
static void
|
||||
nozpool_all_slices(avl_tree_t *r, const char *sname)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
char diskname[MAXNAMELEN];
|
||||
char *ptr;
|
||||
int i;
|
||||
@ -996,10 +996,10 @@ nozpool_all_slices(avl_tree_t *r, const char *sname)
|
||||
ptr[0] = 'p';
|
||||
for (i = 0; i <= FD_NUMPART; i++)
|
||||
check_one_slice(r, diskname, i, 0, 1);
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
static void
|
||||
check_slices(avl_tree_t *r, int fd, const char *sname)
|
||||
{
|
||||
@ -1033,7 +1033,7 @@ check_slices(avl_tree_t *r, int fd, const char *sname)
|
||||
efi_free(gpt);
|
||||
}
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
static void
|
||||
zpool_open_func(void *arg)
|
||||
@ -1063,7 +1063,7 @@ zpool_open_func(void *arg)
|
||||
return;
|
||||
}
|
||||
/* this file is too small to hold a zpool */
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (S_ISREG(statbuf.st_mode) &&
|
||||
statbuf.st_size < SPA_MINDEVSIZE) {
|
||||
(void) close(fd);
|
||||
@ -1075,12 +1075,12 @@ zpool_open_func(void *arg)
|
||||
*/
|
||||
check_slices(rn->rn_avl, fd, rn->rn_name);
|
||||
}
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
if (statbuf.st_size < SPA_MINDEVSIZE) {
|
||||
(void) close(fd);
|
||||
return;
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
if ((zpool_read_label(fd, &config)) != 0) {
|
||||
(void) close(fd);
|
||||
|
@ -139,7 +139,7 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
|
||||
|
||||
*tab = '\0';
|
||||
if (strcmp(buf, mountpoint) == 0) {
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* the protocol field is the third field
|
||||
* skip over second field
|
||||
@ -172,7 +172,7 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
|
||||
return (SHARED_NOT_SHARED);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Returns true if the specified directory is empty. If we can't open the
|
||||
* directory at all, return true so that the mount can fail with a more
|
||||
@ -297,7 +297,7 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef sun /* FreeBSD: overlay mounts are not checked. */
|
||||
#ifdef illumos /* FreeBSD: overlay mounts are not checked. */
|
||||
/*
|
||||
* Determine if the mountpoint is empty. If so, refuse to perform the
|
||||
* mount. We don't perform this check if MS_OVERLAY is specified, which
|
||||
@ -507,7 +507,7 @@ zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
|
||||
* initialized in _zfs_init_libshare() are actually present.
|
||||
*/
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
static sa_handle_t (*_sa_init)(int);
|
||||
static void (*_sa_fini)(sa_handle_t);
|
||||
static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
|
||||
@ -534,7 +534,7 @@ static void (*_sa_update_sharetab_ts)(sa_handle_t);
|
||||
static void
|
||||
_zfs_init_libshare(void)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
void *libshare;
|
||||
char path[MAXPATHLEN];
|
||||
char isa[MAXISALEN];
|
||||
@ -605,7 +605,7 @@ zfs_init_libshare(libzfs_handle_t *zhandle, int service)
|
||||
{
|
||||
int ret = SA_OK;
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (_sa_init == NULL)
|
||||
ret = SA_CONFIG_ERR;
|
||||
|
||||
@ -646,7 +646,7 @@ void
|
||||
zfs_uninit_libshare(libzfs_handle_t *zhandle)
|
||||
{
|
||||
if (zhandle != NULL && zhandle->libzfs_sharehdl != NULL) {
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (_sa_fini != NULL)
|
||||
_sa_fini(zhandle->libzfs_sharehdl);
|
||||
#endif
|
||||
@ -663,7 +663,7 @@ zfs_uninit_libshare(libzfs_handle_t *zhandle)
|
||||
int
|
||||
zfs_parse_options(char *options, zfs_share_proto_t proto)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (_sa_parse_legacy_options != NULL) {
|
||||
return (_sa_parse_legacy_options(NULL, options,
|
||||
proto_table[proto].p_name));
|
||||
@ -674,7 +674,7 @@ zfs_parse_options(char *options, zfs_share_proto_t proto)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* zfs_sa_find_share(handle, path)
|
||||
*
|
||||
@ -716,7 +716,7 @@ zfs_sa_disable_share(sa_share_t share, char *proto)
|
||||
return (_sa_disable_share(share, proto));
|
||||
return (SA_CONFIG_ERR);
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
/*
|
||||
* Share the given filesystem according to the options in the specified
|
||||
@ -767,7 +767,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
|
||||
continue;
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
|
||||
if (share == NULL) {
|
||||
/*
|
||||
@ -856,7 +856,7 @@ static int
|
||||
unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
|
||||
zfs_share_proto_t proto)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
sa_share_t share;
|
||||
int err;
|
||||
char *mntpt;
|
||||
|
@ -409,7 +409,7 @@ bootfs_name_valid(const char *pool, char *bootfs)
|
||||
static boolean_t
|
||||
pool_uses_efi(nvlist_t *config)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
||||
@ -421,7 +421,7 @@ pool_uses_efi(nvlist_t *config)
|
||||
if (pool_uses_efi(child[c]))
|
||||
return (B_TRUE);
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
@ -575,7 +575,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
||||
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
|
||||
ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* bootfs property cannot be set on a disk which has
|
||||
* been EFI labeled.
|
||||
@ -588,7 +588,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
||||
zpool_close(zhp);
|
||||
goto error;
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
zpool_close(zhp);
|
||||
break;
|
||||
|
||||
@ -1916,6 +1916,7 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef illumos
|
||||
/*
|
||||
* This provides a very minimal check whether a given string is likely a
|
||||
* c#t#d# style string. Users of this are expected to do their own
|
||||
@ -1947,6 +1948,7 @@ ctd_check_path(char *str) {
|
||||
}
|
||||
return (CTD_CHECK(str));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find a vdev that matches the search criteria specified. We use the
|
||||
@ -2002,6 +2004,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
|
||||
*
|
||||
* Otherwise, all other searches are simple string compares.
|
||||
*/
|
||||
#ifdef illumos
|
||||
if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 &&
|
||||
ctd_check_path(val)) {
|
||||
uint64_t wholedisk = 0;
|
||||
@ -2041,6 +2044,9 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
|
||||
break;
|
||||
}
|
||||
} else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
|
||||
#else
|
||||
if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
|
||||
#endif
|
||||
char *type, *idx, *end, *p;
|
||||
uint64_t id, vdev_id;
|
||||
|
||||
@ -2378,7 +2384,7 @@ zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
|
||||
static int
|
||||
zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
char path[MAXPATHLEN];
|
||||
char errbuf[1024];
|
||||
int fd, error;
|
||||
@ -2408,7 +2414,7 @@ zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
|
||||
"relabel '%s': unable to read disk capacity"), name);
|
||||
return (zfs_error(hdl, EZFS_NOCAP, errbuf));
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -3464,7 +3470,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
||||
devid_str_free(newdevid);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
if (strncmp(path, "/dev/dsk/", 9) == 0)
|
||||
path += 9;
|
||||
|
||||
@ -3489,10 +3495,10 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
||||
}
|
||||
return (tmp);
|
||||
}
|
||||
#else /* !sun */
|
||||
#else /* !illumos */
|
||||
if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
|
||||
path += sizeof(_PATH_DEV) - 1;
|
||||
#endif /* !sun */
|
||||
#endif /* illumos */
|
||||
} else {
|
||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
|
||||
|
||||
@ -3882,7 +3888,7 @@ zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
|
||||
free(mntpnt);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Read the EFI label from the config, if a label does not exist then
|
||||
* pass back the error to the caller. If the caller has passed a non-NULL
|
||||
@ -3947,7 +3953,7 @@ find_start_block(nvlist_t *config)
|
||||
}
|
||||
return (MAXOFFSET_T);
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
|
||||
/*
|
||||
* Label an individual disk. The name provided is the short name,
|
||||
@ -3956,7 +3962,7 @@ find_start_block(nvlist_t *config)
|
||||
int
|
||||
zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
|
||||
{
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
char path[MAXPATHLEN];
|
||||
struct dk_gpt *vtoc;
|
||||
int fd;
|
||||
@ -4061,7 +4067,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
|
||||
|
||||
(void) close(fd);
|
||||
efi_free(vtoc);
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -949,7 +949,7 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
|
||||
case EIO:
|
||||
case ENOLINK:
|
||||
case ENOSPC:
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
case ENOSTR:
|
||||
#endif
|
||||
case ENXIO:
|
||||
|
@ -687,7 +687,7 @@ libzfs_fini(libzfs_handle_t *hdl)
|
||||
(void) fclose(hdl->libzfs_sharetab);
|
||||
zfs_uninit_libshare(hdl);
|
||||
zpool_free_handles(hdl);
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
libzfs_fru_clear(hdl, B_TRUE);
|
||||
#endif
|
||||
namespace_clear(hdl);
|
||||
@ -739,7 +739,7 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef sun
|
||||
#ifdef illumos
|
||||
rewind(hdl->libzfs_mnttab);
|
||||
while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) {
|
||||
if (makedevice(entry.mnt_major, entry.mnt_minor) ==
|
||||
@ -759,7 +759,7 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* illumos */
|
||||
if (ret != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <synch.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
@ -49,7 +49,7 @@ void
|
||||
barrier_init(barrier_t *bar, int nthreads)
|
||||
{
|
||||
pthread_mutex_init(&bar->bar_lock, NULL);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sema_init(&bar->bar_sem, 0, USYNC_THREAD, NULL);
|
||||
#else
|
||||
sem_init(&bar->bar_sem, 0, 0);
|
||||
@ -66,7 +66,7 @@ barrier_wait(barrier_t *bar)
|
||||
|
||||
if (++bar->bar_numin < bar->bar_nthr) {
|
||||
pthread_mutex_unlock(&bar->bar_lock);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sema_wait(&bar->bar_sem);
|
||||
#else
|
||||
sem_wait(&bar->bar_sem);
|
||||
@ -80,7 +80,7 @@ barrier_wait(barrier_t *bar)
|
||||
/* reset for next use */
|
||||
bar->bar_numin = 0;
|
||||
for (i = 1; i < bar->bar_nthr; i++)
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sema_post(&bar->bar_sem);
|
||||
#else
|
||||
sem_post(&bar->bar_sem);
|
||||
|
@ -33,7 +33,7 @@
|
||||
* APIs for the barrier synchronization primitive.
|
||||
*/
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <synch.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
|
@ -155,7 +155,7 @@ main(int argc, char **argv)
|
||||
int keep_stabs = 0;
|
||||
int c;
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sighold(SIGINT);
|
||||
sighold(SIGQUIT);
|
||||
sighold(SIGTERM);
|
||||
@ -221,7 +221,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
set_terminate_cleanup(terminate_cleanup);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sigset(SIGINT, handle_sig);
|
||||
sigset(SIGQUIT, handle_sig);
|
||||
sigset(SIGTERM, handle_sig);
|
||||
|
@ -176,20 +176,20 @@
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <synch.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
#include <sys/sysconf.h>
|
||||
#endif
|
||||
|
||||
@ -232,7 +232,7 @@ usage(void)
|
||||
progname, progname);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
static void
|
||||
bigheap(void)
|
||||
{
|
||||
@ -280,7 +280,7 @@ bigheap(void)
|
||||
|
||||
(void) memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mha, 0, 0);
|
||||
}
|
||||
#endif
|
||||
#endif /* illumos */
|
||||
|
||||
static void
|
||||
finalize_phase_one(workqueue_t *wq)
|
||||
@ -707,7 +707,7 @@ start_threads(workqueue_t *wq)
|
||||
(void *(*)(void *))worker_thread, wq);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
sigset(SIGINT, handle_sig);
|
||||
sigset(SIGQUIT, handle_sig);
|
||||
sigset(SIGTERM, handle_sig);
|
||||
|
@ -1390,7 +1390,7 @@ die_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Signed enc, size_t sz)
|
||||
mult = 2;
|
||||
col = 1;
|
||||
} else if (enc == DW_ATE_imaginary_float
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
|| enc == DW_ATE_SUN_imaginary_float
|
||||
#endif
|
||||
)
|
||||
@ -1441,7 +1441,7 @@ die_base_from_dwarf(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, size_t sz)
|
||||
case DW_ATE_float:
|
||||
case DW_ATE_complex_float:
|
||||
case DW_ATE_imaginary_float:
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
case DW_ATE_SUN_imaginary_float:
|
||||
case DW_ATE_SUN_interval_float:
|
||||
#endif
|
||||
|
@ -349,7 +349,7 @@ equiv_node(tdesc_t *ctdp, tdesc_t *mtdp, equiv_data_t *ed)
|
||||
int (*equiv)(tdesc_t *, tdesc_t *, equiv_data_t *);
|
||||
int mapping;
|
||||
|
||||
if (ctdp->t_emark > ed->ed_clear_mark &&
|
||||
if (ctdp->t_emark > ed->ed_clear_mark ||
|
||||
mtdp->t_emark > ed->ed_clear_mark)
|
||||
return (ctdp->t_emark == mtdp->t_emark);
|
||||
|
||||
|
@ -576,7 +576,7 @@ write_file(Elf *src, const char *srcname, Elf *dst, const char *dstname,
|
||||
shdr.sh_name);
|
||||
}
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (gelf_update_shdr(dscn, &shdr) == 0)
|
||||
elfterminate(dstname, "Cannot update sect %s", sname);
|
||||
#endif
|
||||
@ -585,7 +585,7 @@ write_file(Elf *src, const char *srcname, Elf *dst, const char *dstname,
|
||||
elfterminate(srcname, "Cannot get sect %s data", sname);
|
||||
if ((ddata = elf_newdata(dscn)) == NULL)
|
||||
elfterminate(dstname, "Can't make sect %s data", sname);
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
bcopy(sdata, ddata, sizeof (Elf_Data));
|
||||
#else
|
||||
/*
|
||||
@ -645,7 +645,7 @@ write_file(Elf *src, const char *srcname, Elf *dst, const char *dstname,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(sun)
|
||||
#ifndef illumos
|
||||
if (ddata->d_buf == NULL && sdata->d_buf != NULL) {
|
||||
ddata->d_buf = xmalloc(shdr.sh_size);
|
||||
bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
|
||||
|
@ -173,7 +173,7 @@ tdesc_namecmp(void *arg1, void *arg2)
|
||||
return (!streq(tdp1->t_name, tdp2->t_name));
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
/*ARGSUSED1*/
|
||||
static int
|
||||
tdesc_print(void *data, void *private __unused)
|
||||
|
@ -171,7 +171,7 @@ aborterr(const char *format, ...)
|
||||
whine("ERROR", format, ap);
|
||||
va_end(ap);
|
||||
|
||||
#if defined(sun)
|
||||
#ifdef illumos
|
||||
abort();
|
||||
#else
|
||||
exit(0);
|
||||
|
1
contrib/binutils/bfd/doc/bfdver.texi
Normal file
1
contrib/binutils/bfd/doc/bfdver.texi
Normal file
@ -0,0 +1 @@
|
||||
@set VERSION "2.17.50 [FreeBSD] 2007-07-03"
|
13924
contrib/binutils/gas/doc/as.txt
Normal file
13924
contrib/binutils/gas/doc/as.txt
Normal file
File diff suppressed because it is too large
Load Diff
90
contrib/binutils/gas/doc/asconfig.texi
Normal file
90
contrib/binutils/gas/doc/asconfig.texi
Normal file
@ -0,0 +1,90 @@
|
||||
@c $FreeBSD: stable/10/gnu/usr.bin/binutils/doc/asconfig.texi 218822 2011-02-18 20:54:12Z dim $
|
||||
@c Copyright 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002,
|
||||
@c 2003, 2005
|
||||
@c Free Software Foundation, Inc.
|
||||
@c This file is part of the documentation for the GAS manual
|
||||
|
||||
@c Configuration settings for all-inclusive version of manual
|
||||
|
||||
@c switches:------------------------------------------------------------
|
||||
@c Properties of the manual
|
||||
@c ========================
|
||||
@c Discuss all architectures?
|
||||
@clear ALL-ARCH
|
||||
@c A generic form of manual (not tailored to specific target)?
|
||||
@clear GENERIC
|
||||
@c Include text on assembler internals?
|
||||
@set INTERNALS
|
||||
@c Many object formats supported in this config?
|
||||
@clear MULTI-OBJ
|
||||
|
||||
@c Object formats of interest
|
||||
@c ==========================
|
||||
@clear AOUT
|
||||
@clear COFF
|
||||
@set ELF
|
||||
@clear SOM
|
||||
|
||||
@c CPUs of interest
|
||||
@c ================
|
||||
@clear ALPHA
|
||||
@clear ARC
|
||||
@set ARM
|
||||
@clear BFIN
|
||||
@clear CRIS
|
||||
@clear D10V
|
||||
@clear D30V
|
||||
@clear H8/300
|
||||
@clear HPPA
|
||||
@clear I370
|
||||
@set I80386
|
||||
@clear I860
|
||||
@clear I960
|
||||
@set IA64
|
||||
@clear IP2K
|
||||
@clear M32C
|
||||
@clear M32R
|
||||
@clear xc16x
|
||||
@clear M68HC11
|
||||
@clear M680X0
|
||||
@clear MCORE
|
||||
@set MIPS
|
||||
@clear MMIX
|
||||
@clear MS1
|
||||
@clear MSP430
|
||||
@clear PDP11
|
||||
@clear PJ
|
||||
@set PPC
|
||||
@clear SH
|
||||
@set SPARC
|
||||
@clear TIC54X
|
||||
@clear V850
|
||||
@clear VAX
|
||||
@clear XTENSA
|
||||
@clear Z80
|
||||
@clear Z8000
|
||||
|
||||
@c Does this version of the assembler use the difference-table kludge?
|
||||
@clear DIFF-TBL-KLUGE
|
||||
|
||||
@c Do all machines described use IEEE floating point?
|
||||
@clear IEEEFLOAT
|
||||
|
||||
@c Is a word 32 bits, or 16?
|
||||
@set W32
|
||||
@clear W16
|
||||
|
||||
@c Do symbols have different characters than usual?
|
||||
@clear SPECIAL-SYMS
|
||||
|
||||
@c strings:------------------------------------------------------------
|
||||
@c Name of the assembler:
|
||||
@set AS as
|
||||
@c Name of C compiler:
|
||||
@set GCC gcc
|
||||
@c Name of linker:
|
||||
@set LD ld
|
||||
@c Text for target machine (best not used in generic case; but just in case...)
|
||||
@set TARGET machine specific
|
||||
@c Name of object format NOT SET in generic version
|
||||
@set OBJ-NAME ELF
|
@ -317,13 +317,6 @@ Either @samp{#} or @samp{$} can be used to indicate immediate operands.
|
||||
@cindex register names, ARM
|
||||
*TODO* Explain about ARM register naming, and the predefined names.
|
||||
|
||||
@node ARM Floating Point
|
||||
@section Floating Point
|
||||
|
||||
@cindex floating point, ARM (@sc{ieee})
|
||||
@cindex ARM floating point (@sc{ieee})
|
||||
The ARM family uses @sc{ieee} floating-point numbers.
|
||||
|
||||
@node ARM-Relocations
|
||||
@subsection ARM relocation generation
|
||||
|
||||
@ -365,6 +358,13 @@ respectively. For example to load the 32-bit address of foo into r0:
|
||||
MOVT r0, #:upper16:foo
|
||||
@end smallexample
|
||||
|
||||
@node ARM Floating Point
|
||||
@section Floating Point
|
||||
|
||||
@cindex floating point, ARM (@sc{ieee})
|
||||
@cindex ARM floating point (@sc{ieee})
|
||||
The ARM family uses @sc{ieee} floating-point numbers.
|
||||
|
||||
@node ARM Directives
|
||||
@section ARM Machine Directives
|
||||
|
||||
|
@ -196,7 +196,7 @@ the @samp{mad} and @samp{madu} instruction, and to not schedule @samp{nop}
|
||||
instructions around accesses to the @samp{HI} and @samp{LO} registers.
|
||||
@samp{-no-m4650} turns off this option.
|
||||
|
||||
@itemx -m3900
|
||||
@item -m3900
|
||||
@itemx -no-m3900
|
||||
@itemx -m4100
|
||||
@itemx -no-m4100
|
||||
|
25
contrib/binutils/ld/configdoc.texi
Normal file
25
contrib/binutils/ld/configdoc.texi
Normal file
@ -0,0 +1,25 @@
|
||||
@c ------------------------------ CONFIGURATION VARS:
|
||||
@c 1. Inclusiveness of this manual
|
||||
@set GENERIC
|
||||
|
||||
@c 2. Specific target machines
|
||||
@set ARM
|
||||
@set H8300
|
||||
@set HPPA
|
||||
@set I960
|
||||
@set M68HC11
|
||||
@set MMIX
|
||||
@set MSP430
|
||||
@set POWERPC
|
||||
@set POWERPC64
|
||||
@set Renesas
|
||||
@set SPU
|
||||
@set TICOFF
|
||||
@set WIN32
|
||||
@set XTENSA
|
||||
|
||||
@c 3. Properties of this configuration
|
||||
@clear SingleFormat
|
||||
@set UsesEnvVars
|
||||
@c ------------------------------ end CONFIGURATION VARS
|
||||
|
@ -1725,7 +1725,7 @@ the linker script being used by the linker.
|
||||
|
||||
@kindex --version-script=@var{version-scriptfile}
|
||||
@cindex version script, symbol versions
|
||||
@itemx --version-script=@var{version-scriptfile}
|
||||
@item --version-script=@var{version-scriptfile}
|
||||
Specify the name of a version script to the linker. This is typically
|
||||
used when creating shared libraries to specify additional information
|
||||
about the version hierarchy for the library being created. This option
|
||||
|
6564
contrib/binutils/ld/ld.txt
Normal file
6564
contrib/binutils/ld/ld.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,3 +22,15 @@ D: Maintain Solaris & AuroraUX ports of Compiler-RT
|
||||
N: Howard Hinnant
|
||||
E: hhinnant@apple.com
|
||||
D: Architect and primary author of compiler-rt
|
||||
|
||||
N: Guan-Hong Liu
|
||||
E: koviankevin@hotmail.com
|
||||
D: IEEE Quad-precision functions
|
||||
|
||||
N: Joerg Sonnenberger
|
||||
E: joerg@NetBSD.org
|
||||
D: Maintains NetBSD port.
|
||||
|
||||
N: Matt Thomas
|
||||
E: matt@NetBSD.org
|
||||
D: ARM improvements.
|
||||
|
@ -14,7 +14,7 @@ Full text of the relevant licenses is included below.
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2009-2013 by the contributors listed in CREDITS.TXT
|
||||
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@ -55,7 +55,7 @@ SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 2009-2013 by the contributors listed in CREDITS.TXT
|
||||
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -89,9 +89,3 @@ other licenses gives permission to use the names of the LLVM Team or the
|
||||
University of Illinois to endorse or promote products derived from this
|
||||
Software.
|
||||
|
||||
The following pieces of software have additional or alternate copyrights,
|
||||
licenses, and/or restrictions:
|
||||
|
||||
Program Directory
|
||||
------- ---------
|
||||
mach_override lib/interception/mach_override
|
||||
|
@ -9,335 +9,3 @@ terms of the license agreement found in LICENSE.txt.
|
||||
|
||||
================================
|
||||
|
||||
This is a replacement library for libgcc. Each function is contained
|
||||
in its own file. Each function has a corresponding unit test under
|
||||
test/Unit.
|
||||
|
||||
A rudimentary script to test each file is in the file called
|
||||
test/Unit/test.
|
||||
|
||||
Here is the specification for this library:
|
||||
|
||||
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
|
||||
|
||||
Here is a synopsis of the contents of this library:
|
||||
|
||||
typedef int si_int;
|
||||
typedef unsigned su_int;
|
||||
|
||||
typedef long long di_int;
|
||||
typedef unsigned long long du_int;
|
||||
|
||||
// Integral bit manipulation
|
||||
|
||||
di_int __ashldi3(di_int a, si_int b); // a << b
|
||||
ti_int __ashlti3(ti_int a, si_int b); // a << b
|
||||
|
||||
di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill)
|
||||
ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill)
|
||||
di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
|
||||
ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill)
|
||||
|
||||
si_int __clzsi2(si_int a); // count leading zeros
|
||||
si_int __clzdi2(di_int a); // count leading zeros
|
||||
si_int __clzti2(ti_int a); // count leading zeros
|
||||
si_int __ctzsi2(si_int a); // count trailing zeros
|
||||
si_int __ctzdi2(di_int a); // count trailing zeros
|
||||
si_int __ctzti2(ti_int a); // count trailing zeros
|
||||
|
||||
si_int __ffsdi2(di_int a); // find least significant 1 bit
|
||||
si_int __ffsti2(ti_int a); // find least significant 1 bit
|
||||
|
||||
si_int __paritysi2(si_int a); // bit parity
|
||||
si_int __paritydi2(di_int a); // bit parity
|
||||
si_int __parityti2(ti_int a); // bit parity
|
||||
|
||||
si_int __popcountsi2(si_int a); // bit population
|
||||
si_int __popcountdi2(di_int a); // bit population
|
||||
si_int __popcountti2(ti_int a); // bit population
|
||||
|
||||
uint32_t __bswapsi2(uint32_t a); // a byteswapped, arm only
|
||||
uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only
|
||||
|
||||
// Integral arithmetic
|
||||
|
||||
di_int __negdi2 (di_int a); // -a
|
||||
ti_int __negti2 (ti_int a); // -a
|
||||
di_int __muldi3 (di_int a, di_int b); // a * b
|
||||
ti_int __multi3 (ti_int a, ti_int b); // a * b
|
||||
si_int __divsi3 (si_int a, si_int b); // a / b signed
|
||||
di_int __divdi3 (di_int a, di_int b); // a / b signed
|
||||
ti_int __divti3 (ti_int a, ti_int b); // a / b signed
|
||||
su_int __udivsi3 (su_int n, su_int d); // a / b unsigned
|
||||
du_int __udivdi3 (du_int a, du_int b); // a / b unsigned
|
||||
tu_int __udivti3 (tu_int a, tu_int b); // a / b unsigned
|
||||
si_int __modsi3 (si_int a, si_int b); // a % b signed
|
||||
di_int __moddi3 (di_int a, di_int b); // a % b signed
|
||||
ti_int __modti3 (ti_int a, ti_int b); // a % b signed
|
||||
su_int __umodsi3 (su_int a, su_int b); // a % b unsigned
|
||||
du_int __umoddi3 (du_int a, du_int b); // a % b unsigned
|
||||
tu_int __umodti3 (tu_int a, tu_int b); // a % b unsigned
|
||||
du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b unsigned
|
||||
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned
|
||||
su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned
|
||||
si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed
|
||||
|
||||
|
||||
|
||||
// Integral arithmetic with trapping overflow
|
||||
|
||||
si_int __absvsi2(si_int a); // abs(a)
|
||||
di_int __absvdi2(di_int a); // abs(a)
|
||||
ti_int __absvti2(ti_int a); // abs(a)
|
||||
|
||||
si_int __negvsi2(si_int a); // -a
|
||||
di_int __negvdi2(di_int a); // -a
|
||||
ti_int __negvti2(ti_int a); // -a
|
||||
|
||||
si_int __addvsi3(si_int a, si_int b); // a + b
|
||||
di_int __addvdi3(di_int a, di_int b); // a + b
|
||||
ti_int __addvti3(ti_int a, ti_int b); // a + b
|
||||
|
||||
si_int __subvsi3(si_int a, si_int b); // a - b
|
||||
di_int __subvdi3(di_int a, di_int b); // a - b
|
||||
ti_int __subvti3(ti_int a, ti_int b); // a - b
|
||||
|
||||
si_int __mulvsi3(si_int a, si_int b); // a * b
|
||||
di_int __mulvdi3(di_int a, di_int b); // a * b
|
||||
ti_int __mulvti3(ti_int a, ti_int b); // a * b
|
||||
|
||||
|
||||
// Integral arithmetic which returns if overflow
|
||||
|
||||
si_int __mulosi4(si_int a, si_int b, int* overflow); // a * b, overflow set to one if result not in signed range
|
||||
di_int __mulodi4(di_int a, di_int b, int* overflow); // a * b, overflow set to one if result not in signed range
|
||||
ti_int __muloti4(ti_int a, ti_int b, int* overflow); // a * b, overflow set to
|
||||
one if result not in signed range
|
||||
|
||||
|
||||
// Integral comparison: a < b -> 0
|
||||
// a == b -> 1
|
||||
// a > b -> 2
|
||||
|
||||
si_int __cmpdi2 (di_int a, di_int b);
|
||||
si_int __cmpti2 (ti_int a, ti_int b);
|
||||
si_int __ucmpdi2(du_int a, du_int b);
|
||||
si_int __ucmpti2(tu_int a, tu_int b);
|
||||
|
||||
// Integral / floating point conversion
|
||||
|
||||
di_int __fixsfdi( float a);
|
||||
di_int __fixdfdi( double a);
|
||||
di_int __fixxfdi(long double a);
|
||||
|
||||
ti_int __fixsfti( float a);
|
||||
ti_int __fixdfti( double a);
|
||||
ti_int __fixxfti(long double a);
|
||||
uint64_t __fixtfdi(long double input); // ppc only, doesn't match documentation
|
||||
|
||||
su_int __fixunssfsi( float a);
|
||||
su_int __fixunsdfsi( double a);
|
||||
su_int __fixunsxfsi(long double a);
|
||||
|
||||
du_int __fixunssfdi( float a);
|
||||
du_int __fixunsdfdi( double a);
|
||||
du_int __fixunsxfdi(long double a);
|
||||
|
||||
tu_int __fixunssfti( float a);
|
||||
tu_int __fixunsdfti( double a);
|
||||
tu_int __fixunsxfti(long double a);
|
||||
uint64_t __fixunstfdi(long double input); // ppc only
|
||||
|
||||
float __floatdisf(di_int a);
|
||||
double __floatdidf(di_int a);
|
||||
long double __floatdixf(di_int a);
|
||||
long double __floatditf(int64_t a); // ppc only
|
||||
|
||||
float __floattisf(ti_int a);
|
||||
double __floattidf(ti_int a);
|
||||
long double __floattixf(ti_int a);
|
||||
|
||||
float __floatundisf(du_int a);
|
||||
double __floatundidf(du_int a);
|
||||
long double __floatundixf(du_int a);
|
||||
long double __floatunditf(uint64_t a); // ppc only
|
||||
|
||||
float __floatuntisf(tu_int a);
|
||||
double __floatuntidf(tu_int a);
|
||||
long double __floatuntixf(tu_int a);
|
||||
|
||||
// Floating point raised to integer power
|
||||
|
||||
float __powisf2( float a, si_int b); // a ^ b
|
||||
double __powidf2( double a, si_int b); // a ^ b
|
||||
long double __powixf2(long double a, si_int b); // a ^ b
|
||||
long double __powitf2(long double a, si_int b); // ppc only, a ^ b
|
||||
|
||||
// Complex arithmetic
|
||||
|
||||
// (a + ib) * (c + id)
|
||||
|
||||
float _Complex __mulsc3( float a, float b, float c, float d);
|
||||
double _Complex __muldc3(double a, double b, double c, double d);
|
||||
long double _Complex __mulxc3(long double a, long double b,
|
||||
long double c, long double d);
|
||||
long double _Complex __multc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
|
||||
// (a + ib) / (c + id)
|
||||
|
||||
float _Complex __divsc3( float a, float b, float c, float d);
|
||||
double _Complex __divdc3(double a, double b, double c, double d);
|
||||
long double _Complex __divxc3(long double a, long double b,
|
||||
long double c, long double d);
|
||||
long double _Complex __divtc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
|
||||
|
||||
// Runtime support
|
||||
|
||||
// __clear_cache() is used to tell process that new instructions have been
|
||||
// written to an address range. Necessary on processors that do not have
|
||||
// a unified instuction and data cache.
|
||||
void __clear_cache(void* start, void* end);
|
||||
|
||||
// __enable_execute_stack() is used with nested functions when a trampoline
|
||||
// function is written onto the stack and that page range needs to be made
|
||||
// executable.
|
||||
void __enable_execute_stack(void* addr);
|
||||
|
||||
// __gcc_personality_v0() is normally only called by the system unwinder.
|
||||
// C code (as opposed to C++) normally does not need a personality function
|
||||
// because there are no catch clauses or destructors to be run. But there
|
||||
// is a C language extension __attribute__((cleanup(func))) which marks local
|
||||
// variables as needing the cleanup function "func" to be run when the
|
||||
// variable goes out of scope. That includes when an exception is thrown,
|
||||
// so a personality handler is needed.
|
||||
_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
|
||||
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
|
||||
_Unwind_Context_t context);
|
||||
|
||||
// for use with some implementations of assert() in <assert.h>
|
||||
void __eprintf(const char* format, const char* assertion_expression,
|
||||
const char* line, const char* file);
|
||||
|
||||
|
||||
|
||||
// Power PC specific functions
|
||||
|
||||
// There is no C interface to the saveFP/restFP functions. They are helper
|
||||
// functions called by the prolog and epilog of functions that need to save
|
||||
// a number of non-volatile float point registers.
|
||||
saveFP
|
||||
restFP
|
||||
|
||||
// PowerPC has a standard template for trampoline functions. This function
|
||||
// generates a custom trampoline function with the specific realFunc
|
||||
// and localsPtr values.
|
||||
void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
|
||||
const void* realFunc, void* localsPtr);
|
||||
|
||||
// adds two 128-bit double-double precision values ( x + y )
|
||||
long double __gcc_qadd(long double x, long double y);
|
||||
|
||||
// subtracts two 128-bit double-double precision values ( x - y )
|
||||
long double __gcc_qsub(long double x, long double y);
|
||||
|
||||
// multiples two 128-bit double-double precision values ( x * y )
|
||||
long double __gcc_qmul(long double x, long double y);
|
||||
|
||||
// divides two 128-bit double-double precision values ( x / y )
|
||||
long double __gcc_qdiv(long double a, long double b);
|
||||
|
||||
|
||||
// ARM specific functions
|
||||
|
||||
// There is no C interface to the switch* functions. These helper functions
|
||||
// are only needed by Thumb1 code for efficient switch table generation.
|
||||
switch16
|
||||
switch32
|
||||
switch8
|
||||
switchu8
|
||||
|
||||
// There is no C interface to the *_vfp_d8_d15_regs functions. There are
|
||||
// called in the prolog and epilog of Thumb1 functions. When the C++ ABI use
|
||||
// SJLJ for exceptions, each function with a catch clause or destuctors needs
|
||||
// to save and restore all registers in it prolog and epliog. But there is
|
||||
// no way to access vector and high float registers from thumb1 code, so the
|
||||
// compiler must add call outs to these helper functions in the prolog and
|
||||
// epilog.
|
||||
restore_vfp_d8_d15_regs
|
||||
save_vfp_d8_d15_regs
|
||||
|
||||
|
||||
// Note: long ago ARM processors did not have floating point hardware support.
|
||||
// Floating point was done in software and floating point parameters were
|
||||
// passed in integer registers. When hardware support was added for floating
|
||||
// point, new *vfp functions were added to do the same operations but with
|
||||
// floating point parameters in floating point registers.
|
||||
|
||||
// Undocumented functions
|
||||
|
||||
float __addsf3vfp(float a, float b); // Appears to return a + b
|
||||
double __adddf3vfp(double a, double b); // Appears to return a + b
|
||||
float __divsf3vfp(float a, float b); // Appears to return a / b
|
||||
double __divdf3vfp(double a, double b); // Appears to return a / b
|
||||
int __eqsf2vfp(float a, float b); // Appears to return one
|
||||
// iff a == b and neither is NaN.
|
||||
int __eqdf2vfp(double a, double b); // Appears to return one
|
||||
// iff a == b and neither is NaN.
|
||||
double __extendsfdf2vfp(float a); // Appears to convert from
|
||||
// float to double.
|
||||
int __fixdfsivfp(double a); // Appears to convert from
|
||||
// double to int.
|
||||
int __fixsfsivfp(float a); // Appears to convert from
|
||||
// float to int.
|
||||
unsigned int __fixunssfsivfp(float a); // Appears to convert from
|
||||
// float to unsigned int.
|
||||
unsigned int __fixunsdfsivfp(double a); // Appears to convert from
|
||||
// double to unsigned int.
|
||||
double __floatsidfvfp(int a); // Appears to convert from
|
||||
// int to double.
|
||||
float __floatsisfvfp(int a); // Appears to convert from
|
||||
// int to float.
|
||||
double __floatunssidfvfp(unsigned int a); // Appears to convert from
|
||||
// unisgned int to double.
|
||||
float __floatunssisfvfp(unsigned int a); // Appears to convert from
|
||||
// unisgned int to float.
|
||||
int __gedf2vfp(double a, double b); // Appears to return __gedf2
|
||||
// (a >= b)
|
||||
int __gesf2vfp(float a, float b); // Appears to return __gesf2
|
||||
// (a >= b)
|
||||
int __gtdf2vfp(double a, double b); // Appears to return __gtdf2
|
||||
// (a > b)
|
||||
int __gtsf2vfp(float a, float b); // Appears to return __gtsf2
|
||||
// (a > b)
|
||||
int __ledf2vfp(double a, double b); // Appears to return __ledf2
|
||||
// (a <= b)
|
||||
int __lesf2vfp(float a, float b); // Appears to return __lesf2
|
||||
// (a <= b)
|
||||
int __ltdf2vfp(double a, double b); // Appears to return __ltdf2
|
||||
// (a < b)
|
||||
int __ltsf2vfp(float a, float b); // Appears to return __ltsf2
|
||||
// (a < b)
|
||||
double __muldf3vfp(double a, double b); // Appears to return a * b
|
||||
float __mulsf3vfp(float a, float b); // Appears to return a * b
|
||||
int __nedf2vfp(double a, double b); // Appears to return __nedf2
|
||||
// (a != b)
|
||||
double __negdf2vfp(double a); // Appears to return -a
|
||||
float __negsf2vfp(float a); // Appears to return -a
|
||||
float __negsf2vfp(float a); // Appears to return -a
|
||||
double __subdf3vfp(double a, double b); // Appears to return a - b
|
||||
float __subsf3vfp(float a, float b); // Appears to return a - b
|
||||
float __truncdfsf2vfp(double a); // Appears to convert from
|
||||
// double to float.
|
||||
int __unorddf2vfp(double a, double b); // Appears to return __unorddf2
|
||||
int __unordsf2vfp(float a, float b); // Appears to return __unordsf2
|
||||
|
||||
|
||||
Preconditions are listed for each function at the definition when there are any.
|
||||
Any preconditions reflect the specification at
|
||||
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.
|
||||
|
||||
Assumptions are listed in "int_lib.h", and in individual files. Where possible
|
||||
assumptions are checked at compile time.
|
||||
|
66
contrib/compiler-rt/include/sanitizer/allocator_interface.h
Normal file
66
contrib/compiler-rt/include/sanitizer/allocator_interface.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===-- allocator_interface.h ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Public interface header for allocator used in sanitizers (ASan/TSan/MSan).
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_ALLOCATOR_INTERFACE_H
|
||||
#define SANITIZER_ALLOCATOR_INTERFACE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Returns the estimated number of bytes that will be reserved by allocator
|
||||
for request of "size" bytes. If allocator can't allocate that much
|
||||
memory, returns the maximal possible allocation size, otherwise returns
|
||||
"size". */
|
||||
size_t __sanitizer_get_estimated_allocated_size(size_t size);
|
||||
|
||||
/* Returns true if p was returned by the allocator and
|
||||
is not yet freed. */
|
||||
int __sanitizer_get_ownership(const volatile void *p);
|
||||
|
||||
/* Returns the number of bytes reserved for the pointer p.
|
||||
Requires (get_ownership(p) == true) or (p == 0). */
|
||||
size_t __sanitizer_get_allocated_size(const volatile void *p);
|
||||
|
||||
/* Number of bytes, allocated and not yet freed by the application. */
|
||||
size_t __sanitizer_get_current_allocated_bytes();
|
||||
|
||||
/* Number of bytes, mmaped by the allocator to fulfill allocation requests.
|
||||
Generally, for request of X bytes, allocator can reserve and add to free
|
||||
lists a large number of chunks of size X to use them for future requests.
|
||||
All these chunks count toward the heap size. Currently, allocator never
|
||||
releases memory to OS (instead, it just puts freed chunks to free
|
||||
lists). */
|
||||
size_t __sanitizer_get_heap_size();
|
||||
|
||||
/* Number of bytes, mmaped by the allocator, which can be used to fulfill
|
||||
allocation requests. When a user program frees memory chunk, it can first
|
||||
fall into quarantine and will count toward __sanitizer_get_free_bytes()
|
||||
later. */
|
||||
size_t __sanitizer_get_free_bytes();
|
||||
|
||||
/* Number of bytes in unmapped pages, that are released to OS. Currently,
|
||||
always returns 0. */
|
||||
size_t __sanitizer_get_unmapped_bytes();
|
||||
|
||||
/* Malloc hooks that may be optionally provided by user.
|
||||
__sanitizer_malloc_hook(ptr, size) is called immediately after
|
||||
allocation of "size" bytes, which returned "ptr".
|
||||
__sanitizer_free_hook(ptr) is called immediately before
|
||||
deallocation of "ptr". */
|
||||
void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);
|
||||
void __sanitizer_free_hook(const volatile void *ptr);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
156
contrib/compiler-rt/include/sanitizer/asan_interface.h
Normal file
156
contrib/compiler-rt/include/sanitizer/asan_interface.h
Normal file
@ -0,0 +1,156 @@
|
||||
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_ASAN_INTERFACE_H
|
||||
#define SANITIZER_ASAN_INTERFACE_H
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Marks memory region [addr, addr+size) as unaddressable.
|
||||
// This memory must be previously allocated by the user program. Accessing
|
||||
// addresses in this region from instrumented code is forbidden until
|
||||
// this region is unpoisoned. This function is not guaranteed to poison
|
||||
// the whole region - it may poison only subregion of [addr, addr+size) due
|
||||
// to ASan alignment restrictions.
|
||||
// Method is NOT thread-safe in the sense that no two threads can
|
||||
// (un)poison memory in the same memory region simultaneously.
|
||||
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||
// Marks memory region [addr, addr+size) as addressable.
|
||||
// This memory must be previously allocated by the user program. Accessing
|
||||
// addresses in this region is allowed until this region is poisoned again.
|
||||
// This function may unpoison a superregion of [addr, addr+size) due to
|
||||
// ASan alignment restrictions.
|
||||
// Method is NOT thread-safe in the sense that no two threads can
|
||||
// (un)poison memory in the same memory region simultaneously.
|
||||
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
|
||||
// User code should use macros instead of functions.
|
||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
#define ASAN_POISON_MEMORY_REGION(addr, size) \
|
||||
__asan_poison_memory_region((addr), (size))
|
||||
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
|
||||
__asan_unpoison_memory_region((addr), (size))
|
||||
#else
|
||||
#define ASAN_POISON_MEMORY_REGION(addr, size) \
|
||||
((void)(addr), (void)(size))
|
||||
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
|
||||
((void)(addr), (void)(size))
|
||||
#endif
|
||||
|
||||
// Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this
|
||||
// address will result in error report from AddressSanitizer).
|
||||
// Otherwise returns 0.
|
||||
int __asan_address_is_poisoned(void const volatile *addr);
|
||||
|
||||
// If at least one byte in [beg, beg+size) is poisoned, return the address
|
||||
// of the first such byte. Otherwise return 0.
|
||||
void *__asan_region_is_poisoned(void *beg, size_t size);
|
||||
|
||||
// Print the description of addr (useful when debugging in gdb).
|
||||
void __asan_describe_address(void *addr);
|
||||
|
||||
// Useful for calling from a debugger to get information about an ASan error.
|
||||
// Returns 1 if an error has been (or is being) reported, otherwise returns 0.
|
||||
int __asan_report_present();
|
||||
|
||||
// Useful for calling from a debugger to get information about an ASan error.
|
||||
// If an error has been (or is being) reported, the following functions return
|
||||
// the pc, bp, sp, address, access type (0 = read, 1 = write), access size and
|
||||
// bug description (e.g. "heap-use-after-free"). Otherwise they return 0.
|
||||
void *__asan_get_report_pc();
|
||||
void *__asan_get_report_bp();
|
||||
void *__asan_get_report_sp();
|
||||
void *__asan_get_report_address();
|
||||
int __asan_get_report_access_type();
|
||||
size_t __asan_get_report_access_size();
|
||||
const char *__asan_get_report_description();
|
||||
|
||||
// Useful for calling from the debugger to get information about a pointer.
|
||||
// Returns the category of the given pointer as a constant string.
|
||||
// Possible return values are "global", "stack", "stack-fake", "heap",
|
||||
// "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown".
|
||||
// If global or stack, tries to also return the variable name, address and
|
||||
// size. If heap, tries to return the chunk address and size. 'name' should
|
||||
// point to an allocated buffer of size 'name_size'.
|
||||
const char *__asan_locate_address(void *addr, char *name, size_t name_size,
|
||||
void **region_address, size_t *region_size);
|
||||
|
||||
// Useful for calling from the debugger to get the allocation stack trace
|
||||
// and thread ID for a heap address. Stores up to 'size' frames into 'trace',
|
||||
// returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
|
||||
// Useful for calling from the debugger to get the free stack trace
|
||||
// and thread ID for a heap address. Stores up to 'size' frames into 'trace',
|
||||
// returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
|
||||
// Useful for calling from the debugger to get the current shadow memory
|
||||
// mapping.
|
||||
void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
|
||||
|
||||
// This is an internal function that is called to report an error.
|
||||
// However it is still a part of the interface because users may want to
|
||||
// set a breakpoint on this function in a debugger.
|
||||
void __asan_report_error(void *pc, void *bp, void *sp,
|
||||
void *addr, int is_write, size_t access_size);
|
||||
|
||||
// Sets the exit code to use when reporting an error.
|
||||
// Returns the old value.
|
||||
int __asan_set_error_exit_code(int exit_code);
|
||||
|
||||
// Sets the callback to be called right before death on error.
|
||||
// Passing 0 will unset the callback.
|
||||
void __asan_set_death_callback(void (*callback)(void));
|
||||
|
||||
void __asan_set_error_report_callback(void (*callback)(const char*));
|
||||
|
||||
// User may provide function that would be called right when ASan detects
|
||||
// an error. This can be used to notice cases when ASan detects an error, but
|
||||
// the program crashes before ASan report is printed.
|
||||
void __asan_on_error();
|
||||
|
||||
// Prints accumulated stats to stderr. Used for debugging.
|
||||
void __asan_print_accumulated_stats();
|
||||
|
||||
// This function may be optionally provided by user and should return
|
||||
// a string containing ASan runtime options. See asan_flags.h for details.
|
||||
const char* __asan_default_options();
|
||||
|
||||
// The following 2 functions facilitate garbage collection in presence of
|
||||
// asan's fake stack.
|
||||
|
||||
// Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.
|
||||
// Returns NULL if the current thread does not have a fake stack.
|
||||
void *__asan_get_current_fake_stack();
|
||||
|
||||
// If fake_stack is non-NULL and addr belongs to a fake frame in
|
||||
// fake_stack, returns the address on real stack that corresponds to
|
||||
// the fake frame and sets beg/end to the boundaries of this fake frame.
|
||||
// Otherwise returns NULL and does not touch beg/end.
|
||||
// If beg/end are NULL, they are not touched.
|
||||
// This function may be called from a thread other than the owner of
|
||||
// fake_stack, but the owner thread need to be alive.
|
||||
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
|
||||
void **end);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_ASAN_INTERFACE_H
|
127
contrib/compiler-rt/include/sanitizer/common_interface_defs.h
Normal file
127
contrib/compiler-rt/include/sanitizer/common_interface_defs.h
Normal file
@ -0,0 +1,127 @@
|
||||
//===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common part of the public sanitizer interface.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SANITIZER_COMMON_INTERFACE_DEFS_H
|
||||
#define SANITIZER_COMMON_INTERFACE_DEFS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// GCC does not understand __has_feature.
|
||||
#if !defined(__has_feature)
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Arguments for __sanitizer_sandbox_on_notify() below.
|
||||
typedef struct {
|
||||
// Enable sandbox support in sanitizer coverage.
|
||||
int coverage_sandboxed;
|
||||
// File descriptor to write coverage data to. If -1 is passed, a file will
|
||||
// be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
|
||||
// effect if coverage_sandboxed == 0.
|
||||
intptr_t coverage_fd;
|
||||
// If non-zero, split the coverage data into well-formed blocks. This is
|
||||
// useful when coverage_fd is a socket descriptor. Each block will contain
|
||||
// a header, allowing data from multiple processes to be sent over the same
|
||||
// socket.
|
||||
unsigned int coverage_max_block_size;
|
||||
} __sanitizer_sandbox_arguments;
|
||||
|
||||
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
|
||||
void __sanitizer_set_report_path(const char *path);
|
||||
|
||||
// Notify the tools that the sandbox is going to be turned on. The reserved
|
||||
// parameter will be used in the future to hold a structure with functions
|
||||
// that the tools may call to bypass the sandbox.
|
||||
void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
|
||||
|
||||
// This function is called by the tool when it has just finished reporting
|
||||
// an error. 'error_summary' is a one-line string that summarizes
|
||||
// the error message. This function can be overridden by the client.
|
||||
void __sanitizer_report_error_summary(const char *error_summary);
|
||||
|
||||
// Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen
|
||||
// in unaligned loads/stores. In order to find such bugs reliably one needs
|
||||
// to replace plain unaligned loads/stores with these calls.
|
||||
uint16_t __sanitizer_unaligned_load16(const void *p);
|
||||
uint32_t __sanitizer_unaligned_load32(const void *p);
|
||||
uint64_t __sanitizer_unaligned_load64(const void *p);
|
||||
void __sanitizer_unaligned_store16(void *p, uint16_t x);
|
||||
void __sanitizer_unaligned_store32(void *p, uint32_t x);
|
||||
void __sanitizer_unaligned_store64(void *p, uint64_t x);
|
||||
|
||||
// Initialize coverage.
|
||||
void __sanitizer_cov_init();
|
||||
// Record and dump coverage info.
|
||||
void __sanitizer_cov_dump();
|
||||
// Open <name>.sancov.packed in the coverage directory and return the file
|
||||
// descriptor. Returns -1 on failure, or if coverage dumping is disabled.
|
||||
// This is intended for use by sandboxing code.
|
||||
intptr_t __sanitizer_maybe_open_cov_file(const char *name);
|
||||
// Get the number of total unique covered entities (blocks, edges, calls).
|
||||
// This can be useful for coverage-directed in-process fuzzers.
|
||||
uintptr_t __sanitizer_get_total_unique_coverage();
|
||||
|
||||
// Annotate the current state of a contiguous container, such as
|
||||
// std::vector, std::string or similar.
|
||||
// A contiguous container is a container that keeps all of its elements
|
||||
// in a contiguous region of memory. The container owns the region of memory
|
||||
// [beg, end); the memory [beg, mid) is used to store the current elements
|
||||
// and the memory [mid, end) is reserved for future elements;
|
||||
// beg <= mid <= end. For example, in "std::vector<> v"
|
||||
// beg = &v[0];
|
||||
// end = beg + v.capacity() * sizeof(v[0]);
|
||||
// mid = beg + v.size() * sizeof(v[0]);
|
||||
//
|
||||
// This annotation tells the Sanitizer tool about the current state of the
|
||||
// container so that the tool can report errors when memory from [mid, end)
|
||||
// is accessed. Insert this annotation into methods like push_back/pop_back.
|
||||
// Supply the old and the new values of mid (old_mid/new_mid).
|
||||
// In the initial state mid == end and so should be the final
|
||||
// state when the container is destroyed or when it reallocates the storage.
|
||||
//
|
||||
// Use with caution and don't use for anything other than vector-like classes.
|
||||
//
|
||||
// For AddressSanitizer, 'beg' should be 8-aligned and 'end' should
|
||||
// be either 8-aligned or it should point to the end of a separate heap-,
|
||||
// stack-, or global- allocated buffer. I.e. the following will not work:
|
||||
// int64_t x[2]; // 16 bytes, 8-aligned.
|
||||
// char *beg = (char *)&x[0];
|
||||
// char *end = beg + 12; // Not 8 aligned, not the end of the buffer.
|
||||
// This however will work fine:
|
||||
// int32_t x[3]; // 12 bytes, but 8-aligned under AddressSanitizer.
|
||||
// char *beg = (char*)&x[0];
|
||||
// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer.
|
||||
void __sanitizer_annotate_contiguous_container(const void *beg,
|
||||
const void *end,
|
||||
const void *old_mid,
|
||||
const void *new_mid);
|
||||
// Returns true if the contiguous container [beg, end) is properly poisoned
|
||||
// (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
|
||||
// - [beg, mid) is addressable,
|
||||
// - [mid, end) is unaddressable.
|
||||
// Full verification requires O(end-beg) time; this function tries to avoid
|
||||
// such complexity by touching only parts of the container around beg/mid/end.
|
||||
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
|
||||
const void *end);
|
||||
|
||||
// Print the stack trace leading to this call. Useful for debugging user code.
|
||||
void __sanitizer_print_stack_trace();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_COMMON_INTERFACE_DEFS_H
|
104
contrib/compiler-rt/include/sanitizer/dfsan_interface.h
Normal file
104
contrib/compiler-rt/include/sanitizer/dfsan_interface.h
Normal file
@ -0,0 +1,104 @@
|
||||
//===-- dfsan_interface.h -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of DataFlowSanitizer.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef DFSAN_INTERFACE_H
|
||||
#define DFSAN_INTERFACE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint16_t dfsan_label;
|
||||
|
||||
/// Stores information associated with a specific label identifier. A label
|
||||
/// may be a base label created using dfsan_create_label, with associated
|
||||
/// text description and user data, or an automatically created union label,
|
||||
/// which represents the union of two label identifiers (which may themselves
|
||||
/// be base or union labels).
|
||||
struct dfsan_label_info {
|
||||
// Fields for union labels, set to 0 for base labels.
|
||||
dfsan_label l1;
|
||||
dfsan_label l2;
|
||||
|
||||
// Fields for base labels.
|
||||
const char *desc;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/// Signature of the callback argument to dfsan_set_write_callback().
|
||||
typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);
|
||||
|
||||
/// Computes the union of \c l1 and \c l2, possibly creating a union label in
|
||||
/// the process.
|
||||
dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
|
||||
|
||||
/// Creates and returns a base label with the given description and user data.
|
||||
dfsan_label dfsan_create_label(const char *desc, void *userdata);
|
||||
|
||||
/// Sets the label for each address in [addr,addr+size) to \c label.
|
||||
void dfsan_set_label(dfsan_label label, void *addr, size_t size);
|
||||
|
||||
/// Sets the label for each address in [addr,addr+size) to the union of the
|
||||
/// current label for that address and \c label.
|
||||
void dfsan_add_label(dfsan_label label, void *addr, size_t size);
|
||||
|
||||
/// Retrieves the label associated with the given data.
|
||||
///
|
||||
/// The type of 'data' is arbitrary. The function accepts a value of any type,
|
||||
/// which can be truncated or extended (implicitly or explicitly) as necessary.
|
||||
/// The truncation/extension operations will preserve the label of the original
|
||||
/// value.
|
||||
dfsan_label dfsan_get_label(long data);
|
||||
|
||||
/// Retrieves the label associated with the data at the given address.
|
||||
dfsan_label dfsan_read_label(const void *addr, size_t size);
|
||||
|
||||
/// Retrieves a pointer to the dfsan_label_info struct for the given label.
|
||||
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);
|
||||
|
||||
/// Returns whether the given label label contains the label elem.
|
||||
int dfsan_has_label(dfsan_label label, dfsan_label elem);
|
||||
|
||||
/// If the given label label contains a label with the description desc, returns
|
||||
/// that label, else returns 0.
|
||||
dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
|
||||
|
||||
/// Returns the number of labels allocated.
|
||||
size_t dfsan_get_label_count(void);
|
||||
|
||||
/// Sets a callback to be invoked on calls to write(). The callback is invoked
|
||||
/// before the write is done. The write is not guaranteed to succeed when the
|
||||
/// callback executes. Pass in NULL to remove any callback.
|
||||
void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);
|
||||
|
||||
/// Writes the labels currently used by the program to the given file
|
||||
/// descriptor. The lines of the output have the following format:
|
||||
///
|
||||
/// <label> <parent label 1> <parent label 2> <label description if any>
|
||||
void dfsan_dump_labels(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
template <typename T>
|
||||
void dfsan_set_label(dfsan_label label, T &data) { // NOLINT
|
||||
dfsan_set_label(label, (void *)&data, sizeof(T));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DFSAN_INTERFACE_H
|
3070
contrib/compiler-rt/include/sanitizer/linux_syscall_hooks.h
Normal file
3070
contrib/compiler-rt/include/sanitizer/linux_syscall_hooks.h
Normal file
File diff suppressed because it is too large
Load Diff
73
contrib/compiler-rt/include/sanitizer/lsan_interface.h
Normal file
73
contrib/compiler-rt/include/sanitizer/lsan_interface.h
Normal file
@ -0,0 +1,73 @@
|
||||
//===-- sanitizer/lsan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of LeakSanitizer.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_LSAN_INTERFACE_H
|
||||
#define SANITIZER_LSAN_INTERFACE_H
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Allocations made between calls to __lsan_disable() and __lsan_enable() will
|
||||
// be treated as non-leaks. Disable/enable pairs may be nested.
|
||||
void __lsan_disable();
|
||||
void __lsan_enable();
|
||||
|
||||
// The heap object into which p points will be treated as a non-leak.
|
||||
void __lsan_ignore_object(const void *p);
|
||||
|
||||
// Memory regions registered through this interface will be treated as sources
|
||||
// of live pointers during leak checking. Useful if you store pointers in
|
||||
// mapped memory.
|
||||
// Points of note:
|
||||
// - __lsan_unregister_root_region() must be called with the same pointer and
|
||||
// size that have earlier been passed to __lsan_register_root_region()
|
||||
// - LSan will skip any inaccessible memory when scanning a root region. E.g.,
|
||||
// if you map memory within a larger region that you have mprotect'ed, you can
|
||||
// register the entire large region.
|
||||
// - the implementation is not optimized for performance. This interface is
|
||||
// intended to be used for a small number of relatively static regions.
|
||||
void __lsan_register_root_region(const void *p, size_t size);
|
||||
void __lsan_unregister_root_region(const void *p, size_t size);
|
||||
|
||||
// Calling this function makes LSan enter the leak checking phase immediately.
|
||||
// Use this if normal end-of-process leak checking happens too late (e.g. if
|
||||
// you have intentional memory leaks in your shutdown code). Calling this
|
||||
// function overrides end-of-process leak checking; it must be called at
|
||||
// most once per process. This function will terminate the process if there
|
||||
// are memory leaks and the exit_code flag is non-zero.
|
||||
void __lsan_do_leak_check();
|
||||
|
||||
// The user may optionally provide this function to disallow leak checking
|
||||
// for the program it is linked into (if the return value is non-zero). This
|
||||
// function must be defined as returning a constant value; any behavior beyond
|
||||
// that is unsupported.
|
||||
int __lsan_is_turned_off();
|
||||
|
||||
// This function may be optionally provided by the user and should return
|
||||
// a string containing LSan suppressions.
|
||||
const char *__lsan_default_suppressions();
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
namespace __lsan {
|
||||
class ScopedDisabler {
|
||||
public:
|
||||
ScopedDisabler() { __lsan_disable(); }
|
||||
~ScopedDisabler() { __lsan_enable(); }
|
||||
};
|
||||
} // namespace __lsan
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_LSAN_INTERFACE_H
|
100
contrib/compiler-rt/include/sanitizer/msan_interface.h
Normal file
100
contrib/compiler-rt/include/sanitizer/msan_interface.h
Normal file
@ -0,0 +1,100 @@
|
||||
//===-- msan_interface.h --------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of MemorySanitizer.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef MSAN_INTERFACE_H
|
||||
#define MSAN_INTERFACE_H
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Set raw origin for the memory range. */
|
||||
void __msan_set_origin(const volatile void *a, size_t size, uint32_t origin);
|
||||
|
||||
/* Get raw origin for an address. */
|
||||
uint32_t __msan_get_origin(const volatile void *a);
|
||||
|
||||
/* Returns non-zero if tracking origins. */
|
||||
int __msan_get_track_origins();
|
||||
|
||||
/* Returns the origin id of the latest UMR in the calling thread. */
|
||||
uint32_t __msan_get_umr_origin();
|
||||
|
||||
/* Make memory region fully initialized (without changing its contents). */
|
||||
void __msan_unpoison(const volatile void *a, size_t size);
|
||||
|
||||
/* Make a null-terminated string fully initialized (without changing its
|
||||
contents). */
|
||||
void __msan_unpoison_string(const volatile char *a);
|
||||
|
||||
/* Make memory region fully uninitialized (without changing its contents). */
|
||||
void __msan_poison(const volatile void *a, size_t size);
|
||||
|
||||
/* Make memory region partially uninitialized (without changing its contents).
|
||||
*/
|
||||
void __msan_partial_poison(const volatile void *data, void *shadow,
|
||||
size_t size);
|
||||
|
||||
/* Returns the offset of the first (at least partially) poisoned byte in the
|
||||
memory range, or -1 if the whole range is good. */
|
||||
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
|
||||
|
||||
/* Checks that memory range is fully initialized, and reports an error if it
|
||||
* is not. */
|
||||
void __msan_check_mem_is_initialized(const volatile void *x, size_t size);
|
||||
|
||||
/* Set exit code when error(s) were detected.
|
||||
Value of 0 means don't change the program exit code. */
|
||||
void __msan_set_exit_code(int exit_code);
|
||||
|
||||
/* For testing:
|
||||
__msan_set_expect_umr(1);
|
||||
... some buggy code ...
|
||||
__msan_set_expect_umr(0);
|
||||
The last line will verify that a UMR happened. */
|
||||
void __msan_set_expect_umr(int expect_umr);
|
||||
|
||||
/* Change the value of keep_going flag. Non-zero value means don't terminate
|
||||
program execution when an error is detected. This will not affect error in
|
||||
modules that were compiled without the corresponding compiler flag. */
|
||||
void __msan_set_keep_going(int keep_going);
|
||||
|
||||
/* Print shadow and origin for the memory range to stderr in a human-readable
|
||||
format. */
|
||||
void __msan_print_shadow(const volatile void *x, size_t size);
|
||||
|
||||
/* Print shadow for the memory range to stderr in a minimalistic
|
||||
human-readable format. */
|
||||
void __msan_dump_shadow(const volatile void *x, size_t size);
|
||||
|
||||
/* Returns true if running under a dynamic tool (DynamoRio-based). */
|
||||
int __msan_has_dynamic_component();
|
||||
|
||||
/* Tell MSan about newly allocated memory (ex.: custom allocator).
|
||||
Memory will be marked uninitialized, with origin at the call site. */
|
||||
void __msan_allocated_memory(const volatile void* data, size_t size);
|
||||
|
||||
/* This function may be optionally provided by user and should return
|
||||
a string containing Msan runtime options. See msan_flags.h for details. */
|
||||
const char* __msan_default_options();
|
||||
|
||||
/* Sets the callback to be called right before death on error.
|
||||
Passing 0 will unset the callback. */
|
||||
void __msan_set_death_callback(void (*callback)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
222
contrib/compiler-rt/include/sanitizer/tsan_interface_atomic.h
Normal file
222
contrib/compiler-rt/include/sanitizer/tsan_interface_atomic.h
Normal file
@ -0,0 +1,222 @@
|
||||
//===-- tsan_interface_atomic.h ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of ThreadSanitizer (TSan), a race detector.
|
||||
//
|
||||
// Public interface header for TSan atomics.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef TSAN_INTERFACE_ATOMIC_H
|
||||
#define TSAN_INTERFACE_ATOMIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef char __tsan_atomic8;
|
||||
typedef short __tsan_atomic16; // NOLINT
|
||||
typedef int __tsan_atomic32;
|
||||
typedef long __tsan_atomic64; // NOLINT
|
||||
#if defined(__SIZEOF_INT128__) \
|
||||
|| (__clang_major__ * 100 + __clang_minor__ >= 302)
|
||||
__extension__ typedef __int128 __tsan_atomic128;
|
||||
# define __TSAN_HAS_INT128 1
|
||||
#else
|
||||
# define __TSAN_HAS_INT128 0
|
||||
#endif
|
||||
|
||||
// Part of ABI, do not change.
|
||||
// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup
|
||||
typedef enum {
|
||||
__tsan_memory_order_relaxed,
|
||||
__tsan_memory_order_consume,
|
||||
__tsan_memory_order_acquire,
|
||||
__tsan_memory_order_release,
|
||||
__tsan_memory_order_acq_rel,
|
||||
__tsan_memory_order_seq_cst
|
||||
} __tsan_memory_order;
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_load(const volatile __tsan_atomic8 *a,
|
||||
__tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_load(const volatile __tsan_atomic16 *a,
|
||||
__tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_load(const volatile __tsan_atomic32 *a,
|
||||
__tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_load(const volatile __tsan_atomic64 *a,
|
||||
__tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_load(const volatile __tsan_atomic128 *a,
|
||||
__tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
void __tsan_atomic8_store(volatile __tsan_atomic8 *a, __tsan_atomic8 v,
|
||||
__tsan_memory_order mo);
|
||||
void __tsan_atomic16_store(volatile __tsan_atomic16 *a, __tsan_atomic16 v,
|
||||
__tsan_memory_order mo);
|
||||
void __tsan_atomic32_store(volatile __tsan_atomic32 *a, __tsan_atomic32 v,
|
||||
__tsan_memory_order mo);
|
||||
void __tsan_atomic64_store(volatile __tsan_atomic64 *a, __tsan_atomic64 v,
|
||||
__tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
void __tsan_atomic128_store(volatile __tsan_atomic128 *a, __tsan_atomic128 v,
|
||||
__tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_exchange(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_exchange(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_exchange(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_exchange(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_exchange(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_add(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_add(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_add(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_add(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_add(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_sub(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_sub(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_sub(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_sub(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_sub(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_and(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_and(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_and(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_and(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_and(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_or(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_or(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_or(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_or(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_or(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_xor(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_xor(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_xor(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_xor(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_xor(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_fetch_nand(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 v, __tsan_memory_order mo);
|
||||
__tsan_atomic16 __tsan_atomic16_fetch_nand(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 v, __tsan_memory_order mo);
|
||||
__tsan_atomic32 __tsan_atomic32_fetch_nand(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 v, __tsan_memory_order mo);
|
||||
__tsan_atomic64 __tsan_atomic64_fetch_nand(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 v, __tsan_memory_order mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_fetch_nand(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 v, __tsan_memory_order mo);
|
||||
#endif
|
||||
|
||||
int __tsan_atomic8_compare_exchange_weak(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic16_compare_exchange_weak(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic32_compare_exchange_weak(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic64_compare_exchange_weak(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
int __tsan_atomic128_compare_exchange_weak(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
#endif
|
||||
|
||||
int __tsan_atomic8_compare_exchange_strong(volatile __tsan_atomic8 *a,
|
||||
__tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic16_compare_exchange_strong(volatile __tsan_atomic16 *a,
|
||||
__tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic32_compare_exchange_strong(volatile __tsan_atomic32 *a,
|
||||
__tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
int __tsan_atomic64_compare_exchange_strong(volatile __tsan_atomic64 *a,
|
||||
__tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
int __tsan_atomic128_compare_exchange_strong(volatile __tsan_atomic128 *a,
|
||||
__tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,
|
||||
__tsan_memory_order fail_mo);
|
||||
#endif
|
||||
|
||||
__tsan_atomic8 __tsan_atomic8_compare_exchange_val(
|
||||
volatile __tsan_atomic8 *a, __tsan_atomic8 c, __tsan_atomic8 v,
|
||||
__tsan_memory_order mo, __tsan_memory_order fail_mo);
|
||||
__tsan_atomic16 __tsan_atomic16_compare_exchange_val(
|
||||
volatile __tsan_atomic16 *a, __tsan_atomic16 c, __tsan_atomic16 v,
|
||||
__tsan_memory_order mo, __tsan_memory_order fail_mo);
|
||||
__tsan_atomic32 __tsan_atomic32_compare_exchange_val(
|
||||
volatile __tsan_atomic32 *a, __tsan_atomic32 c, __tsan_atomic32 v,
|
||||
__tsan_memory_order mo, __tsan_memory_order fail_mo);
|
||||
__tsan_atomic64 __tsan_atomic64_compare_exchange_val(
|
||||
volatile __tsan_atomic64 *a, __tsan_atomic64 c, __tsan_atomic64 v,
|
||||
__tsan_memory_order mo, __tsan_memory_order fail_mo);
|
||||
#if __TSAN_HAS_INT128
|
||||
__tsan_atomic128 __tsan_atomic128_compare_exchange_val(
|
||||
volatile __tsan_atomic128 *a, __tsan_atomic128 c, __tsan_atomic128 v,
|
||||
__tsan_memory_order mo, __tsan_memory_order fail_mo);
|
||||
#endif
|
||||
|
||||
void __tsan_atomic_thread_fence(__tsan_memory_order mo);
|
||||
void __tsan_atomic_signal_fence(__tsan_memory_order mo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // TSAN_INTERFACE_ATOMIC_H
|
@ -1,152 +0,0 @@
|
||||
//===-- lib/adddf3.c - Double-precision addition ------------------*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements double-precision soft-float addition with the IEEE-754
|
||||
// default rounding (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
ARM_EABI_FNALIAS(dadd, adddf3)
|
||||
|
||||
COMPILER_RT_ABI fp_t
|
||||
__adddf3(fp_t a, fp_t b) {
|
||||
|
||||
rep_t aRep = toRep(a);
|
||||
rep_t bRep = toRep(b);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const rep_t bAbs = bRep & absMask;
|
||||
|
||||
// Detect if a or b is zero, infinity, or NaN.
|
||||
if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) {
|
||||
|
||||
// NaN + anything = qNaN
|
||||
if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
|
||||
// anything + NaN = qNaN
|
||||
if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
|
||||
|
||||
if (aAbs == infRep) {
|
||||
// +/-infinity + -/+infinity = qNaN
|
||||
if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep);
|
||||
// +/-infinity + anything remaining = +/- infinity
|
||||
else return a;
|
||||
}
|
||||
|
||||
// anything remaining + +/-infinity = +/-infinity
|
||||
if (bAbs == infRep) return b;
|
||||
|
||||
// zero + anything = anything
|
||||
if (!aAbs) {
|
||||
// but we need to get the sign right for zero + zero
|
||||
if (!bAbs) return fromRep(toRep(a) & toRep(b));
|
||||
else return b;
|
||||
}
|
||||
|
||||
// anything + zero = anything
|
||||
if (!bAbs) return a;
|
||||
}
|
||||
|
||||
// Swap a and b if necessary so that a has the larger absolute value.
|
||||
if (bAbs > aAbs) {
|
||||
const rep_t temp = aRep;
|
||||
aRep = bRep;
|
||||
bRep = temp;
|
||||
}
|
||||
|
||||
// Extract the exponent and significand from the (possibly swapped) a and b.
|
||||
int aExponent = aRep >> significandBits & maxExponent;
|
||||
int bExponent = bRep >> significandBits & maxExponent;
|
||||
rep_t aSignificand = aRep & significandMask;
|
||||
rep_t bSignificand = bRep & significandMask;
|
||||
|
||||
// Normalize any denormals, and adjust the exponent accordingly.
|
||||
if (aExponent == 0) aExponent = normalize(&aSignificand);
|
||||
if (bExponent == 0) bExponent = normalize(&bSignificand);
|
||||
|
||||
// The sign of the result is the sign of the larger operand, a. If they
|
||||
// have opposite signs, we are performing a subtraction; otherwise addition.
|
||||
const rep_t resultSign = aRep & signBit;
|
||||
const bool subtraction = (aRep ^ bRep) & signBit;
|
||||
|
||||
// Shift the significands to give us round, guard and sticky, and or in the
|
||||
// implicit significand bit. (If we fell through from the denormal path it
|
||||
// was already set by normalize( ), but setting it twice won't hurt
|
||||
// anything.)
|
||||
aSignificand = (aSignificand | implicitBit) << 3;
|
||||
bSignificand = (bSignificand | implicitBit) << 3;
|
||||
|
||||
// Shift the significand of b by the difference in exponents, with a sticky
|
||||
// bottom bit to get rounding correct.
|
||||
const unsigned int align = aExponent - bExponent;
|
||||
if (align) {
|
||||
if (align < typeWidth) {
|
||||
const bool sticky = bSignificand << (typeWidth - align);
|
||||
bSignificand = bSignificand >> align | sticky;
|
||||
} else {
|
||||
bSignificand = 1; // sticky; b is known to be non-zero.
|
||||
}
|
||||
}
|
||||
|
||||
if (subtraction) {
|
||||
aSignificand -= bSignificand;
|
||||
|
||||
// If a == -b, return +zero.
|
||||
if (aSignificand == 0) return fromRep(0);
|
||||
|
||||
// If partial cancellation occured, we need to left-shift the result
|
||||
// and adjust the exponent:
|
||||
if (aSignificand < implicitBit << 3) {
|
||||
const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);
|
||||
aSignificand <<= shift;
|
||||
aExponent -= shift;
|
||||
}
|
||||
}
|
||||
|
||||
else /* addition */ {
|
||||
aSignificand += bSignificand;
|
||||
|
||||
// If the addition carried up, we need to right-shift the result and
|
||||
// adjust the exponent:
|
||||
if (aSignificand & implicitBit << 4) {
|
||||
const bool sticky = aSignificand & 1;
|
||||
aSignificand = aSignificand >> 1 | sticky;
|
||||
aExponent += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have overflowed the type, return +/- infinity:
|
||||
if (aExponent >= maxExponent) return fromRep(infRep | resultSign);
|
||||
|
||||
if (aExponent <= 0) {
|
||||
// Result is denormal before rounding; the exponent is zero and we
|
||||
// need to shift the significand.
|
||||
const int shift = 1 - aExponent;
|
||||
const bool sticky = aSignificand << (typeWidth - shift);
|
||||
aSignificand = aSignificand >> shift | sticky;
|
||||
aExponent = 0;
|
||||
}
|
||||
|
||||
// Low three bits are round, guard, and sticky.
|
||||
const int roundGuardSticky = aSignificand & 0x7;
|
||||
|
||||
// Shift the significand into place, and mask off the implicit bit.
|
||||
rep_t result = aSignificand >> 3 & significandMask;
|
||||
|
||||
// Insert the exponent and sign.
|
||||
result |= (rep_t)aExponent << significandBits;
|
||||
result |= resultSign;
|
||||
|
||||
// Final rounding. The result may overflow to infinity, but that is the
|
||||
// correct result in that case.
|
||||
if (roundGuardSticky > 0x4) result++;
|
||||
if (roundGuardSticky == 0x4) result += result & 1;
|
||||
return fromRep(result);
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*===-- udivmodsi4.S - 32-bit unsigned integer divide and modulus ---------===//
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===//
|
||||
*
|
||||
* This file implements the __udivmodsi4 (32-bit unsigned integer divide and
|
||||
* modulus) function for the ARM architecture. A naive digit-by-digit
|
||||
* computation is employed for simplicity.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
#define ESTABLISH_FRAME \
|
||||
push {r4, r7, lr} ;\
|
||||
add r7, sp, #4
|
||||
#define CLEAR_FRAME_AND_RETURN \
|
||||
pop {r4, r7, pc}
|
||||
|
||||
#define a r0
|
||||
#define b r1
|
||||
#define i r3
|
||||
#define r r4
|
||||
#define q ip
|
||||
#define one lr
|
||||
|
||||
.syntax unified
|
||||
.align 3
|
||||
DEFINE_COMPILERRT_FUNCTION(__udivmodsi4)
|
||||
// We use a simple digit by digit algorithm; before we get into the actual
|
||||
// divide loop, we must calculate the left-shift amount necessary to align
|
||||
// the MSB of the divisor with that of the dividend (If this shift is
|
||||
// negative, then the result is zero, and we early out). We also conjure a
|
||||
// bit mask of 1 to use in constructing the quotient, and initialize the
|
||||
// quotient to zero.
|
||||
ESTABLISH_FRAME
|
||||
clz r4, a
|
||||
tst b, b // detect divide-by-zero
|
||||
clz r3, b
|
||||
mov q, #0
|
||||
beq LOCAL_LABEL(return) // return 0 if b is zero.
|
||||
mov one, #1
|
||||
subs i, r3, r4
|
||||
blt LOCAL_LABEL(return) // return 0 if MSB(a) < MSB(b)
|
||||
|
||||
LOCAL_LABEL(mainLoop):
|
||||
// This loop basically implements the following:
|
||||
//
|
||||
// do {
|
||||
// if (a >= b << i) {
|
||||
// a -= b << i;
|
||||
// q |= 1 << i;
|
||||
// if (a == 0) break;
|
||||
// }
|
||||
// } while (--i)
|
||||
//
|
||||
// Note that this does not perform the final iteration (i == 0); by doing it
|
||||
// this way, we can merge the two branches which is a substantial win for
|
||||
// such a tight loop on current ARM architectures.
|
||||
subs r, a, b, lsl i
|
||||
orrhs q, q,one, lsl i
|
||||
movhs a, r
|
||||
subsne i, i, #1
|
||||
bhi LOCAL_LABEL(mainLoop)
|
||||
|
||||
// Do the final test subtraction and update of quotient (i == 0), as it is
|
||||
// not performed in the main loop.
|
||||
subs r, a, b
|
||||
orrhs q, #1
|
||||
movhs a, r
|
||||
|
||||
LOCAL_LABEL(return):
|
||||
// Store the remainder, and move the quotient to r0, then return.
|
||||
str a, [r2]
|
||||
mov r0, q
|
||||
CLEAR_FRAME_AND_RETURN
|
@ -1,90 +0,0 @@
|
||||
/*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===//
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===//
|
||||
*
|
||||
* This file implements the __udivsi3 (32-bit unsigned integer divide)
|
||||
* function for the ARM architecture. A naive digit-by-digit computation is
|
||||
* employed for simplicity.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
#define ESTABLISH_FRAME \
|
||||
push {r7, lr} ;\
|
||||
mov r7, sp
|
||||
#define CLEAR_FRAME_AND_RETURN \
|
||||
pop {r7, pc}
|
||||
|
||||
#define a r0
|
||||
#define b r1
|
||||
#define r r2
|
||||
#define i r3
|
||||
#define q ip
|
||||
#define one lr
|
||||
|
||||
.syntax unified
|
||||
.align 3
|
||||
// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3)
|
||||
DEFINE_COMPILERRT_FUNCTION(__udivsi3)
|
||||
#if __ARM_ARCH_7S__
|
||||
tst r1,r1
|
||||
beq LOCAL_LABEL(divzero)
|
||||
udiv r0, r0, r1
|
||||
bx lr
|
||||
LOCAL_LABEL(divzero):
|
||||
mov r0,#0
|
||||
bx lr
|
||||
#else
|
||||
// We use a simple digit by digit algorithm; before we get into the actual
|
||||
// divide loop, we must calculate the left-shift amount necessary to align
|
||||
// the MSB of the divisor with that of the dividend (If this shift is
|
||||
// negative, then the result is zero, and we early out). We also conjure a
|
||||
// bit mask of 1 to use in constructing the quotient, and initialize the
|
||||
// quotient to zero.
|
||||
ESTABLISH_FRAME
|
||||
clz r2, a
|
||||
tst b, b // detect divide-by-zero
|
||||
clz r3, b
|
||||
mov q, #0
|
||||
beq LOCAL_LABEL(return) // return 0 if b is zero.
|
||||
mov one, #1
|
||||
subs i, r3, r2
|
||||
blt LOCAL_LABEL(return) // return 0 if MSB(a) < MSB(b)
|
||||
|
||||
LOCAL_LABEL(mainLoop):
|
||||
// This loop basically implements the following:
|
||||
//
|
||||
// do {
|
||||
// if (a >= b << i) {
|
||||
// a -= b << i;
|
||||
// q |= 1 << i;
|
||||
// if (a == 0) break;
|
||||
// }
|
||||
// } while (--i)
|
||||
//
|
||||
// Note that this does not perform the final iteration (i == 0); by doing it
|
||||
// this way, we can merge the two branches which is a substantial win for
|
||||
// such a tight loop on current ARM architectures.
|
||||
subs r, a, b, lsl i
|
||||
orrhs q, q,one, lsl i
|
||||
movhs a, r
|
||||
subsne i, i, #1
|
||||
bhi LOCAL_LABEL(mainLoop)
|
||||
|
||||
// Do the final test subtraction and update of quotient (i == 0), as it is
|
||||
// not performed in the main loop.
|
||||
subs r, a, b
|
||||
orrhs q, #1
|
||||
|
||||
LOCAL_LABEL(return):
|
||||
// Move the quotient to r0 and return.
|
||||
mov r0, q
|
||||
CLEAR_FRAME_AND_RETURN
|
||||
#endif
|
@ -1,58 +0,0 @@
|
||||
/*===-- umodsi3.S - 32-bit unsigned integer modulus -----------------------===//
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===//
|
||||
*
|
||||
* This file implements the __umodsi3 (32-bit unsigned integer modulus)
|
||||
* function for the ARM architecture. A naive digit-by-digit computation is
|
||||
* employed for simplicity.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
#define a r0
|
||||
#define b r1
|
||||
#define r r2
|
||||
#define i r3
|
||||
|
||||
.syntax unified
|
||||
.align 3
|
||||
DEFINE_COMPILERRT_FUNCTION(__umodsi3)
|
||||
// We use a simple digit by digit algorithm; before we get into the actual
|
||||
// divide loop, we must calculate the left-shift amount necessary to align
|
||||
// the MSB of the divisor with that of the dividend.
|
||||
clz r2, a
|
||||
tst b, b // detect b == 0
|
||||
clz r3, b
|
||||
bxeq lr // return a if b == 0
|
||||
subs i, r3, r2
|
||||
bxlt lr // return a if MSB(a) < MSB(b)
|
||||
|
||||
LOCAL_LABEL(mainLoop):
|
||||
// This loop basically implements the following:
|
||||
//
|
||||
// do {
|
||||
// if (a >= b << i) {
|
||||
// a -= b << i;
|
||||
// if (a == 0) break;
|
||||
// }
|
||||
// } while (--i)
|
||||
//
|
||||
// Note that this does not perform the final iteration (i == 0); by doing it
|
||||
// this way, we can merge the two branches which is a substantial win for
|
||||
// such a tight loop on current ARM architectures.
|
||||
subs r, a, b, lsl i
|
||||
movhs a, r
|
||||
subsne i, i, #1
|
||||
bhi LOCAL_LABEL(mainLoop)
|
||||
|
||||
// Do the final test subtraction and update of remainder (i == 0), as it is
|
||||
// not performed in the main loop.
|
||||
subs r, a, b
|
||||
movhs a, r
|
||||
bx lr
|
28
contrib/compiler-rt/lib/asan/README.txt
Normal file
28
contrib/compiler-rt/lib/asan/README.txt
Normal file
@ -0,0 +1,28 @@
|
||||
AddressSanitizer RT
|
||||
================================
|
||||
This directory contains sources of the AddressSanitizer (asan) runtime library.
|
||||
We are in the process of integrating AddressSanitizer with LLVM, stay tuned.
|
||||
|
||||
Directory structure:
|
||||
README.txt : This file.
|
||||
Makefile.mk : File for make-based build.
|
||||
CMakeLists.txt : File for cmake-based build.
|
||||
asan_*.{cc,h} : Sources of the asan runtime library.
|
||||
scripts/* : Helper scripts.
|
||||
tests/* : ASan unit tests.
|
||||
|
||||
Also ASan runtime needs the following libraries:
|
||||
lib/interception/ : Machinery used to intercept function calls.
|
||||
lib/sanitizer_common/ : Code shared between ASan and TSan.
|
||||
|
||||
Currently ASan runtime can be built by both make and cmake build systems.
|
||||
(see compiler-rt/make and files Makefile.mk for make-based build and
|
||||
files CMakeLists.txt for cmake-based build).
|
||||
|
||||
ASan unit and output tests work only with cmake. You may run this
|
||||
command from the root of your cmake build tree:
|
||||
|
||||
make check-asan
|
||||
|
||||
For more instructions see:
|
||||
http://code.google.com/p/address-sanitizer/wiki/HowToBuild
|
3
contrib/compiler-rt/lib/asan/asan.syms.extra
Normal file
3
contrib/compiler-rt/lib/asan/asan.syms.extra
Normal file
@ -0,0 +1,3 @@
|
||||
__asan_*
|
||||
__lsan_*
|
||||
__ubsan_*
|
88
contrib/compiler-rt/lib/asan/asan_activation.cc
Normal file
88
contrib/compiler-rt/lib/asan/asan_activation.cc
Normal file
@ -0,0 +1,88 @@
|
||||
//===-- asan_activation.cc --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// ASan activation/deactivation logic.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "asan_activation.h"
|
||||
#include "asan_allocator.h"
|
||||
#include "asan_flags.h"
|
||||
#include "asan_internal.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
static struct AsanDeactivatedFlags {
|
||||
int quarantine_size;
|
||||
int max_redzone;
|
||||
int malloc_context_size;
|
||||
bool poison_heap;
|
||||
bool alloc_dealloc_mismatch;
|
||||
bool allocator_may_return_null;
|
||||
} asan_deactivated_flags;
|
||||
|
||||
static bool asan_is_deactivated;
|
||||
|
||||
void AsanStartDeactivated() {
|
||||
VReport(1, "Deactivating ASan\n");
|
||||
// Save flag values.
|
||||
asan_deactivated_flags.quarantine_size = flags()->quarantine_size;
|
||||
asan_deactivated_flags.max_redzone = flags()->max_redzone;
|
||||
asan_deactivated_flags.poison_heap = flags()->poison_heap;
|
||||
asan_deactivated_flags.malloc_context_size =
|
||||
common_flags()->malloc_context_size;
|
||||
asan_deactivated_flags.alloc_dealloc_mismatch =
|
||||
flags()->alloc_dealloc_mismatch;
|
||||
asan_deactivated_flags.allocator_may_return_null =
|
||||
common_flags()->allocator_may_return_null;
|
||||
|
||||
flags()->quarantine_size = 0;
|
||||
flags()->max_redzone = 16;
|
||||
flags()->poison_heap = false;
|
||||
common_flags()->malloc_context_size = 0;
|
||||
flags()->alloc_dealloc_mismatch = false;
|
||||
common_flags()->allocator_may_return_null = true;
|
||||
|
||||
asan_is_deactivated = true;
|
||||
}
|
||||
|
||||
void AsanActivate() {
|
||||
if (!asan_is_deactivated) return;
|
||||
VReport(1, "Activating ASan\n");
|
||||
|
||||
// Restore flag values.
|
||||
// FIXME: this is not atomic, and there may be other threads alive.
|
||||
flags()->quarantine_size = asan_deactivated_flags.quarantine_size;
|
||||
flags()->max_redzone = asan_deactivated_flags.max_redzone;
|
||||
flags()->poison_heap = asan_deactivated_flags.poison_heap;
|
||||
common_flags()->malloc_context_size =
|
||||
asan_deactivated_flags.malloc_context_size;
|
||||
flags()->alloc_dealloc_mismatch =
|
||||
asan_deactivated_flags.alloc_dealloc_mismatch;
|
||||
common_flags()->allocator_may_return_null =
|
||||
asan_deactivated_flags.allocator_may_return_null;
|
||||
|
||||
ParseExtraActivationFlags();
|
||||
|
||||
ReInitializeAllocator();
|
||||
|
||||
asan_is_deactivated = false;
|
||||
VReport(
|
||||
1,
|
||||
"quarantine_size %d, max_redzone %d, poison_heap %d, "
|
||||
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
|
||||
"allocator_may_return_null %d\n",
|
||||
flags()->quarantine_size, flags()->max_redzone, flags()->poison_heap,
|
||||
common_flags()->malloc_context_size, flags()->alloc_dealloc_mismatch,
|
||||
common_flags()->allocator_may_return_null);
|
||||
}
|
||||
|
||||
} // namespace __asan
|
23
contrib/compiler-rt/lib/asan/asan_activation.h
Normal file
23
contrib/compiler-rt/lib/asan/asan_activation.h
Normal file
@ -0,0 +1,23 @@
|
||||
//===-- asan_activation.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// ASan activation/deactivation logic.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ASAN_ACTIVATION_H
|
||||
#define ASAN_ACTIVATION_H
|
||||
|
||||
namespace __asan {
|
||||
void AsanStartDeactivated();
|
||||
void AsanActivate();
|
||||
} // namespace __asan
|
||||
|
||||
#endif // ASAN_ACTIVATION_H
|
165
contrib/compiler-rt/lib/asan/asan_allocator.h
Normal file
165
contrib/compiler-rt/lib/asan/asan_allocator.h
Normal file
@ -0,0 +1,165 @@
|
||||
//===-- asan_allocator.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// ASan-private header for asan_allocator2.cc.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ASAN_ALLOCATOR_H
|
||||
#define ASAN_ALLOCATOR_H
|
||||
|
||||
#include "asan_internal.h"
|
||||
#include "asan_interceptors.h"
|
||||
#include "sanitizer_common/sanitizer_allocator.h"
|
||||
#include "sanitizer_common/sanitizer_list.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
enum AllocType {
|
||||
FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
|
||||
FROM_NEW = 2, // Memory block came from operator new.
|
||||
FROM_NEW_BR = 3 // Memory block came from operator new [ ]
|
||||
};
|
||||
|
||||
static const uptr kNumberOfSizeClasses = 255;
|
||||
struct AsanChunk;
|
||||
|
||||
void InitializeAllocator();
|
||||
void ReInitializeAllocator();
|
||||
|
||||
class AsanChunkView {
|
||||
public:
|
||||
explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
|
||||
bool IsValid(); // Checks if AsanChunkView points to a valid allocated
|
||||
// or quarantined chunk.
|
||||
uptr Beg(); // First byte of user memory.
|
||||
uptr End(); // Last byte of user memory.
|
||||
uptr UsedSize(); // Size requested by the user.
|
||||
uptr AllocTid();
|
||||
uptr FreeTid();
|
||||
bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
|
||||
StackTrace GetAllocStack();
|
||||
StackTrace GetFreeStack();
|
||||
bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {
|
||||
if (addr >= Beg() && (addr + access_size) <= End()) {
|
||||
*offset = addr - Beg();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) {
|
||||
(void)access_size;
|
||||
if (addr < Beg()) {
|
||||
*offset = Beg() - addr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) {
|
||||
if (addr + access_size > End()) {
|
||||
*offset = addr - End();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
AsanChunk *const chunk_;
|
||||
};
|
||||
|
||||
AsanChunkView FindHeapChunkByAddress(uptr address);
|
||||
|
||||
// List of AsanChunks with total size.
|
||||
class AsanChunkFifoList: public IntrusiveList<AsanChunk> {
|
||||
public:
|
||||
explicit AsanChunkFifoList(LinkerInitialized) { }
|
||||
AsanChunkFifoList() { clear(); }
|
||||
void Push(AsanChunk *n);
|
||||
void PushList(AsanChunkFifoList *q);
|
||||
AsanChunk *Pop();
|
||||
uptr size() { return size_; }
|
||||
void clear() {
|
||||
IntrusiveList<AsanChunk>::clear();
|
||||
size_ = 0;
|
||||
}
|
||||
private:
|
||||
uptr size_;
|
||||
};
|
||||
|
||||
struct AsanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const;
|
||||
void OnUnmap(uptr p, uptr size) const;
|
||||
};
|
||||
|
||||
#if SANITIZER_CAN_USE_ALLOCATOR64
|
||||
# if defined(__powerpc64__)
|
||||
const uptr kAllocatorSpace = 0xa0000000000ULL;
|
||||
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
|
||||
# else
|
||||
const uptr kAllocatorSpace = 0x600000000000ULL;
|
||||
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
|
||||
# endif
|
||||
typedef DefaultSizeClassMap SizeClassMap;
|
||||
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0 /*metadata*/,
|
||||
SizeClassMap, AsanMapUnmapCallback> PrimaryAllocator;
|
||||
#else // Fallback to SizeClassAllocator32.
|
||||
static const uptr kRegionSizeLog = 20;
|
||||
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
|
||||
# if SANITIZER_WORDSIZE == 32
|
||||
typedef FlatByteMap<kNumRegions> ByteMap;
|
||||
# elif SANITIZER_WORDSIZE == 64
|
||||
typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
|
||||
# endif
|
||||
typedef CompactSizeClassMap SizeClassMap;
|
||||
typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 16,
|
||||
SizeClassMap, kRegionSizeLog,
|
||||
ByteMap,
|
||||
AsanMapUnmapCallback> PrimaryAllocator;
|
||||
#endif // SANITIZER_CAN_USE_ALLOCATOR64
|
||||
|
||||
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
|
||||
typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
|
||||
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
|
||||
SecondaryAllocator> Allocator;
|
||||
|
||||
|
||||
struct AsanThreadLocalMallocStorage {
|
||||
uptr quarantine_cache[16];
|
||||
AllocatorCache allocator2_cache;
|
||||
void CommitBack();
|
||||
private:
|
||||
// These objects are allocated via mmap() and are zero-initialized.
|
||||
AsanThreadLocalMallocStorage() {}
|
||||
};
|
||||
|
||||
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
|
||||
AllocType alloc_type);
|
||||
void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);
|
||||
void asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack,
|
||||
AllocType alloc_type);
|
||||
|
||||
void *asan_malloc(uptr size, BufferedStackTrace *stack);
|
||||
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
|
||||
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);
|
||||
void *asan_valloc(uptr size, BufferedStackTrace *stack);
|
||||
void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
|
||||
|
||||
int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp);
|
||||
|
||||
uptr asan_mz_size(const void *ptr);
|
||||
void asan_mz_force_lock();
|
||||
void asan_mz_force_unlock();
|
||||
|
||||
void PrintInternalAllocatorStats();
|
||||
|
||||
} // namespace __asan
|
||||
#endif // ASAN_ALLOCATOR_H
|
792
contrib/compiler-rt/lib/asan/asan_allocator2.cc
Normal file
792
contrib/compiler-rt/lib/asan/asan_allocator2.cc
Normal file
@ -0,0 +1,792 @@
|
||||
//===-- asan_allocator2.cc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Implementation of ASan's memory allocator, 2-nd version.
|
||||
// This variant uses the allocator from sanitizer_common, i.e. the one shared
|
||||
// with ThreadSanitizer and MemorySanitizer.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "asan_allocator.h"
|
||||
|
||||
#include "asan_mapping.h"
|
||||
#include "asan_poisoning.h"
|
||||
#include "asan_report.h"
|
||||
#include "asan_stack.h"
|
||||
#include "asan_thread.h"
|
||||
#include "sanitizer_common/sanitizer_allocator_interface.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_list.h"
|
||||
#include "sanitizer_common/sanitizer_stackdepot.h"
|
||||
#include "sanitizer_common/sanitizer_quarantine.h"
|
||||
#include "lsan/lsan_common.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {
|
||||
PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);
|
||||
// Statistics.
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.mmaps++;
|
||||
thread_stats.mmaped += size;
|
||||
}
|
||||
void AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const {
|
||||
PoisonShadow(p, size, 0);
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// Mark the corresponding shadow memory as not needed.
|
||||
FlushUnneededASanShadowMemory(p, size);
|
||||
// Statistics.
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.munmaps++;
|
||||
thread_stats.munmaped += size;
|
||||
}
|
||||
|
||||
// We can not use THREADLOCAL because it is not supported on some of the
|
||||
// platforms we care about (OSX 10.6, Android).
|
||||
// static THREADLOCAL AllocatorCache cache;
|
||||
AllocatorCache *GetAllocatorCache(AsanThreadLocalMallocStorage *ms) {
|
||||
CHECK(ms);
|
||||
return &ms->allocator2_cache;
|
||||
}
|
||||
|
||||
static Allocator allocator;
|
||||
|
||||
static const uptr kMaxAllowedMallocSize =
|
||||
FIRST_32_SECOND_64(3UL << 30, 64UL << 30);
|
||||
|
||||
static const uptr kMaxThreadLocalQuarantine =
|
||||
FIRST_32_SECOND_64(1 << 18, 1 << 20);
|
||||
|
||||
// Every chunk of memory allocated by this allocator can be in one of 3 states:
|
||||
// CHUNK_AVAILABLE: the chunk is in the free list and ready to be allocated.
|
||||
// CHUNK_ALLOCATED: the chunk is allocated and not yet freed.
|
||||
// CHUNK_QUARANTINE: the chunk was freed and put into quarantine zone.
|
||||
enum {
|
||||
CHUNK_AVAILABLE = 0, // 0 is the default value even if we didn't set it.
|
||||
CHUNK_ALLOCATED = 2,
|
||||
CHUNK_QUARANTINE = 3
|
||||
};
|
||||
|
||||
// Valid redzone sizes are 16, 32, 64, ... 2048, so we encode them in 3 bits.
|
||||
// We use adaptive redzones: for larger allocation larger redzones are used.
|
||||
static u32 RZLog2Size(u32 rz_log) {
|
||||
CHECK_LT(rz_log, 8);
|
||||
return 16 << rz_log;
|
||||
}
|
||||
|
||||
static u32 RZSize2Log(u32 rz_size) {
|
||||
CHECK_GE(rz_size, 16);
|
||||
CHECK_LE(rz_size, 2048);
|
||||
CHECK(IsPowerOfTwo(rz_size));
|
||||
u32 res = Log2(rz_size) - 4;
|
||||
CHECK_EQ(rz_size, RZLog2Size(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
static uptr ComputeRZLog(uptr user_requested_size) {
|
||||
u32 rz_log =
|
||||
user_requested_size <= 64 - 16 ? 0 :
|
||||
user_requested_size <= 128 - 32 ? 1 :
|
||||
user_requested_size <= 512 - 64 ? 2 :
|
||||
user_requested_size <= 4096 - 128 ? 3 :
|
||||
user_requested_size <= (1 << 14) - 256 ? 4 :
|
||||
user_requested_size <= (1 << 15) - 512 ? 5 :
|
||||
user_requested_size <= (1 << 16) - 1024 ? 6 : 7;
|
||||
return Min(Max(rz_log, RZSize2Log(flags()->redzone)),
|
||||
RZSize2Log(flags()->max_redzone));
|
||||
}
|
||||
|
||||
// The memory chunk allocated from the underlying allocator looks like this:
|
||||
// L L L L L L H H U U U U U U R R
|
||||
// L -- left redzone words (0 or more bytes)
|
||||
// H -- ChunkHeader (16 bytes), which is also a part of the left redzone.
|
||||
// U -- user memory.
|
||||
// R -- right redzone (0 or more bytes)
|
||||
// ChunkBase consists of ChunkHeader and other bytes that overlap with user
|
||||
// memory.
|
||||
|
||||
// If the left redzone is greater than the ChunkHeader size we store a magic
|
||||
// value in the first uptr word of the memory block and store the address of
|
||||
// ChunkBase in the next uptr.
|
||||
// M B L L L L L L L L L H H U U U U U U
|
||||
// | ^
|
||||
// ---------------------|
|
||||
// M -- magic value kAllocBegMagic
|
||||
// B -- address of ChunkHeader pointing to the first 'H'
|
||||
static const uptr kAllocBegMagic = 0xCC6E96B9;
|
||||
|
||||
struct ChunkHeader {
|
||||
// 1-st 8 bytes.
|
||||
u32 chunk_state : 8; // Must be first.
|
||||
u32 alloc_tid : 24;
|
||||
|
||||
u32 free_tid : 24;
|
||||
u32 from_memalign : 1;
|
||||
u32 alloc_type : 2;
|
||||
u32 rz_log : 3;
|
||||
u32 lsan_tag : 2;
|
||||
// 2-nd 8 bytes
|
||||
// This field is used for small sizes. For large sizes it is equal to
|
||||
// SizeClassMap::kMaxSize and the actual size is stored in the
|
||||
// SecondaryAllocator's metadata.
|
||||
u32 user_requested_size;
|
||||
u32 alloc_context_id;
|
||||
};
|
||||
|
||||
struct ChunkBase : ChunkHeader {
|
||||
// Header2, intersects with user memory.
|
||||
u32 free_context_id;
|
||||
};
|
||||
|
||||
static const uptr kChunkHeaderSize = sizeof(ChunkHeader);
|
||||
static const uptr kChunkHeader2Size = sizeof(ChunkBase) - kChunkHeaderSize;
|
||||
COMPILER_CHECK(kChunkHeaderSize == 16);
|
||||
COMPILER_CHECK(kChunkHeader2Size <= 16);
|
||||
|
||||
struct AsanChunk: ChunkBase {
|
||||
uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; }
|
||||
uptr UsedSize(bool locked_version = false) {
|
||||
if (user_requested_size != SizeClassMap::kMaxSize)
|
||||
return user_requested_size;
|
||||
return *reinterpret_cast<uptr *>(
|
||||
allocator.GetMetaData(AllocBeg(locked_version)));
|
||||
}
|
||||
void *AllocBeg(bool locked_version = false) {
|
||||
if (from_memalign) {
|
||||
if (locked_version)
|
||||
return allocator.GetBlockBeginFastLocked(
|
||||
reinterpret_cast<void *>(this));
|
||||
return allocator.GetBlockBegin(reinterpret_cast<void *>(this));
|
||||
}
|
||||
return reinterpret_cast<void*>(Beg() - RZLog2Size(rz_log));
|
||||
}
|
||||
bool AddrIsInside(uptr addr, bool locked_version = false) {
|
||||
return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version));
|
||||
}
|
||||
};
|
||||
|
||||
bool AsanChunkView::IsValid() {
|
||||
return chunk_ != 0 && chunk_->chunk_state != CHUNK_AVAILABLE;
|
||||
}
|
||||
uptr AsanChunkView::Beg() { return chunk_->Beg(); }
|
||||
uptr AsanChunkView::End() { return Beg() + UsedSize(); }
|
||||
uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); }
|
||||
uptr AsanChunkView::AllocTid() { return chunk_->alloc_tid; }
|
||||
uptr AsanChunkView::FreeTid() { return chunk_->free_tid; }
|
||||
|
||||
static StackTrace GetStackTraceFromId(u32 id) {
|
||||
CHECK(id);
|
||||
StackTrace res = StackDepotGet(id);
|
||||
CHECK(res.trace);
|
||||
return res;
|
||||
}
|
||||
|
||||
StackTrace AsanChunkView::GetAllocStack() {
|
||||
return GetStackTraceFromId(chunk_->alloc_context_id);
|
||||
}
|
||||
|
||||
StackTrace AsanChunkView::GetFreeStack() {
|
||||
return GetStackTraceFromId(chunk_->free_context_id);
|
||||
}
|
||||
|
||||
struct QuarantineCallback;
|
||||
typedef Quarantine<QuarantineCallback, AsanChunk> AsanQuarantine;
|
||||
typedef AsanQuarantine::Cache QuarantineCache;
|
||||
static AsanQuarantine quarantine(LINKER_INITIALIZED);
|
||||
static QuarantineCache fallback_quarantine_cache(LINKER_INITIALIZED);
|
||||
static AllocatorCache fallback_allocator_cache;
|
||||
static SpinMutex fallback_mutex;
|
||||
|
||||
QuarantineCache *GetQuarantineCache(AsanThreadLocalMallocStorage *ms) {
|
||||
CHECK(ms);
|
||||
CHECK_LE(sizeof(QuarantineCache), sizeof(ms->quarantine_cache));
|
||||
return reinterpret_cast<QuarantineCache *>(ms->quarantine_cache);
|
||||
}
|
||||
|
||||
struct QuarantineCallback {
|
||||
explicit QuarantineCallback(AllocatorCache *cache)
|
||||
: cache_(cache) {
|
||||
}
|
||||
|
||||
void Recycle(AsanChunk *m) {
|
||||
CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
|
||||
atomic_store((atomic_uint8_t*)m, CHUNK_AVAILABLE, memory_order_relaxed);
|
||||
CHECK_NE(m->alloc_tid, kInvalidTid);
|
||||
CHECK_NE(m->free_tid, kInvalidTid);
|
||||
PoisonShadow(m->Beg(),
|
||||
RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),
|
||||
kAsanHeapLeftRedzoneMagic);
|
||||
void *p = reinterpret_cast<void *>(m->AllocBeg());
|
||||
if (p != m) {
|
||||
uptr *alloc_magic = reinterpret_cast<uptr *>(p);
|
||||
CHECK_EQ(alloc_magic[0], kAllocBegMagic);
|
||||
// Clear the magic value, as allocator internals may overwrite the
|
||||
// contents of deallocated chunk, confusing GetAsanChunk lookup.
|
||||
alloc_magic[0] = 0;
|
||||
CHECK_EQ(alloc_magic[1], reinterpret_cast<uptr>(m));
|
||||
}
|
||||
|
||||
// Statistics.
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.real_frees++;
|
||||
thread_stats.really_freed += m->UsedSize();
|
||||
|
||||
allocator.Deallocate(cache_, p);
|
||||
}
|
||||
|
||||
void *Allocate(uptr size) {
|
||||
return allocator.Allocate(cache_, size, 1, false);
|
||||
}
|
||||
|
||||
void Deallocate(void *p) {
|
||||
allocator.Deallocate(cache_, p);
|
||||
}
|
||||
|
||||
AllocatorCache *cache_;
|
||||
};
|
||||
|
||||
void InitializeAllocator() {
|
||||
allocator.Init();
|
||||
quarantine.Init((uptr)flags()->quarantine_size, kMaxThreadLocalQuarantine);
|
||||
}
|
||||
|
||||
void ReInitializeAllocator() {
|
||||
quarantine.Init((uptr)flags()->quarantine_size, kMaxThreadLocalQuarantine);
|
||||
}
|
||||
|
||||
static void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
|
||||
AllocType alloc_type, bool can_fill) {
|
||||
if (UNLIKELY(!asan_inited))
|
||||
AsanInitFromRtl();
|
||||
Flags &fl = *flags();
|
||||
CHECK(stack);
|
||||
const uptr min_alignment = SHADOW_GRANULARITY;
|
||||
if (alignment < min_alignment)
|
||||
alignment = min_alignment;
|
||||
if (size == 0) {
|
||||
// We'd be happy to avoid allocating memory for zero-size requests, but
|
||||
// some programs/tests depend on this behavior and assume that malloc would
|
||||
// not return NULL even for zero-size allocations. Moreover, it looks like
|
||||
// operator new should never return NULL, and results of consecutive "new"
|
||||
// calls must be different even if the allocated size is zero.
|
||||
size = 1;
|
||||
}
|
||||
CHECK(IsPowerOfTwo(alignment));
|
||||
uptr rz_log = ComputeRZLog(size);
|
||||
uptr rz_size = RZLog2Size(rz_log);
|
||||
uptr rounded_size = RoundUpTo(Max(size, kChunkHeader2Size), alignment);
|
||||
uptr needed_size = rounded_size + rz_size;
|
||||
if (alignment > min_alignment)
|
||||
needed_size += alignment;
|
||||
bool using_primary_allocator = true;
|
||||
// If we are allocating from the secondary allocator, there will be no
|
||||
// automatic right redzone, so add the right redzone manually.
|
||||
if (!PrimaryAllocator::CanAllocate(needed_size, alignment)) {
|
||||
needed_size += rz_size;
|
||||
using_primary_allocator = false;
|
||||
}
|
||||
CHECK(IsAligned(needed_size, min_alignment));
|
||||
if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) {
|
||||
Report("WARNING: AddressSanitizer failed to allocate %p bytes\n",
|
||||
(void*)size);
|
||||
return AllocatorReturnNull();
|
||||
}
|
||||
|
||||
AsanThread *t = GetCurrentThread();
|
||||
void *allocated;
|
||||
if (t) {
|
||||
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
|
||||
allocated = allocator.Allocate(cache, needed_size, 8, false);
|
||||
} else {
|
||||
SpinMutexLock l(&fallback_mutex);
|
||||
AllocatorCache *cache = &fallback_allocator_cache;
|
||||
allocated = allocator.Allocate(cache, needed_size, 8, false);
|
||||
}
|
||||
|
||||
if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && flags()->poison_heap) {
|
||||
// Heap poisoning is enabled, but the allocator provides an unpoisoned
|
||||
// chunk. This is possible if flags()->poison_heap was disabled for some
|
||||
// time, for example, due to flags()->start_disabled.
|
||||
// Anyway, poison the block before using it for anything else.
|
||||
uptr allocated_size = allocator.GetActuallyAllocatedSize(allocated);
|
||||
PoisonShadow((uptr)allocated, allocated_size, kAsanHeapLeftRedzoneMagic);
|
||||
}
|
||||
|
||||
uptr alloc_beg = reinterpret_cast<uptr>(allocated);
|
||||
uptr alloc_end = alloc_beg + needed_size;
|
||||
uptr beg_plus_redzone = alloc_beg + rz_size;
|
||||
uptr user_beg = beg_plus_redzone;
|
||||
if (!IsAligned(user_beg, alignment))
|
||||
user_beg = RoundUpTo(user_beg, alignment);
|
||||
uptr user_end = user_beg + size;
|
||||
CHECK_LE(user_end, alloc_end);
|
||||
uptr chunk_beg = user_beg - kChunkHeaderSize;
|
||||
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
|
||||
m->alloc_type = alloc_type;
|
||||
m->rz_log = rz_log;
|
||||
u32 alloc_tid = t ? t->tid() : 0;
|
||||
m->alloc_tid = alloc_tid;
|
||||
CHECK_EQ(alloc_tid, m->alloc_tid); // Does alloc_tid fit into the bitfield?
|
||||
m->free_tid = kInvalidTid;
|
||||
m->from_memalign = user_beg != beg_plus_redzone;
|
||||
if (alloc_beg != chunk_beg) {
|
||||
CHECK_LE(alloc_beg+ 2 * sizeof(uptr), chunk_beg);
|
||||
reinterpret_cast<uptr *>(alloc_beg)[0] = kAllocBegMagic;
|
||||
reinterpret_cast<uptr *>(alloc_beg)[1] = chunk_beg;
|
||||
}
|
||||
if (using_primary_allocator) {
|
||||
CHECK(size);
|
||||
m->user_requested_size = size;
|
||||
CHECK(allocator.FromPrimary(allocated));
|
||||
} else {
|
||||
CHECK(!allocator.FromPrimary(allocated));
|
||||
m->user_requested_size = SizeClassMap::kMaxSize;
|
||||
uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(allocated));
|
||||
meta[0] = size;
|
||||
meta[1] = chunk_beg;
|
||||
}
|
||||
|
||||
m->alloc_context_id = StackDepotPut(*stack);
|
||||
|
||||
uptr size_rounded_down_to_granularity = RoundDownTo(size, SHADOW_GRANULARITY);
|
||||
// Unpoison the bulk of the memory region.
|
||||
if (size_rounded_down_to_granularity)
|
||||
PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);
|
||||
// Deal with the end of the region if size is not aligned to granularity.
|
||||
if (size != size_rounded_down_to_granularity && fl.poison_heap) {
|
||||
u8 *shadow = (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity);
|
||||
*shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0;
|
||||
}
|
||||
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.mallocs++;
|
||||
thread_stats.malloced += size;
|
||||
thread_stats.malloced_redzones += needed_size - size;
|
||||
uptr class_id = Min(kNumberOfSizeClasses, SizeClassMap::ClassID(needed_size));
|
||||
thread_stats.malloced_by_size[class_id]++;
|
||||
if (needed_size > SizeClassMap::kMaxSize)
|
||||
thread_stats.malloc_large++;
|
||||
|
||||
void *res = reinterpret_cast<void *>(user_beg);
|
||||
if (can_fill && fl.max_malloc_fill_size) {
|
||||
uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size);
|
||||
REAL(memset)(res, fl.malloc_fill_byte, fill_size);
|
||||
}
|
||||
#if CAN_SANITIZE_LEAKS
|
||||
m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
|
||||
: __lsan::kDirectlyLeaked;
|
||||
#endif
|
||||
// Must be the last mutation of metadata in this function.
|
||||
atomic_store((atomic_uint8_t *)m, CHUNK_ALLOCATED, memory_order_release);
|
||||
ASAN_MALLOC_HOOK(res, size);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void ReportInvalidFree(void *ptr, u8 chunk_state,
|
||||
BufferedStackTrace *stack) {
|
||||
if (chunk_state == CHUNK_QUARANTINE)
|
||||
ReportDoubleFree((uptr)ptr, stack);
|
||||
else
|
||||
ReportFreeNotMalloced((uptr)ptr, stack);
|
||||
}
|
||||
|
||||
static void AtomicallySetQuarantineFlag(AsanChunk *m, void *ptr,
|
||||
BufferedStackTrace *stack) {
|
||||
u8 old_chunk_state = CHUNK_ALLOCATED;
|
||||
// Flip the chunk_state atomically to avoid race on double-free.
|
||||
if (!atomic_compare_exchange_strong((atomic_uint8_t*)m, &old_chunk_state,
|
||||
CHUNK_QUARANTINE, memory_order_acquire))
|
||||
ReportInvalidFree(ptr, old_chunk_state, stack);
|
||||
CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);
|
||||
}
|
||||
|
||||
// Expects the chunk to already be marked as quarantined by using
|
||||
// AtomicallySetQuarantineFlag.
|
||||
static void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
|
||||
|
||||
if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch)
|
||||
ReportAllocTypeMismatch((uptr)ptr, stack,
|
||||
(AllocType)m->alloc_type, (AllocType)alloc_type);
|
||||
|
||||
CHECK_GE(m->alloc_tid, 0);
|
||||
if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area.
|
||||
CHECK_EQ(m->free_tid, kInvalidTid);
|
||||
AsanThread *t = GetCurrentThread();
|
||||
m->free_tid = t ? t->tid() : 0;
|
||||
m->free_context_id = StackDepotPut(*stack);
|
||||
// Poison the region.
|
||||
PoisonShadow(m->Beg(),
|
||||
RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),
|
||||
kAsanHeapFreeMagic);
|
||||
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.frees++;
|
||||
thread_stats.freed += m->UsedSize();
|
||||
|
||||
// Push into quarantine.
|
||||
if (t) {
|
||||
AsanThreadLocalMallocStorage *ms = &t->malloc_storage();
|
||||
AllocatorCache *ac = GetAllocatorCache(ms);
|
||||
quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac),
|
||||
m, m->UsedSize());
|
||||
} else {
|
||||
SpinMutexLock l(&fallback_mutex);
|
||||
AllocatorCache *ac = &fallback_allocator_cache;
|
||||
quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac),
|
||||
m, m->UsedSize());
|
||||
}
|
||||
}
|
||||
|
||||
static void Deallocate(void *ptr, uptr delete_size, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
uptr p = reinterpret_cast<uptr>(ptr);
|
||||
if (p == 0) return;
|
||||
|
||||
uptr chunk_beg = p - kChunkHeaderSize;
|
||||
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
|
||||
if (delete_size && flags()->new_delete_type_mismatch &&
|
||||
delete_size != m->UsedSize()) {
|
||||
ReportNewDeleteSizeMismatch(p, delete_size, stack);
|
||||
}
|
||||
ASAN_FREE_HOOK(ptr);
|
||||
// Must mark the chunk as quarantined before any changes to its metadata.
|
||||
AtomicallySetQuarantineFlag(m, ptr, stack);
|
||||
QuarantineChunk(m, ptr, stack, alloc_type);
|
||||
}
|
||||
|
||||
static void *Reallocate(void *old_ptr, uptr new_size,
|
||||
BufferedStackTrace *stack) {
|
||||
CHECK(old_ptr && new_size);
|
||||
uptr p = reinterpret_cast<uptr>(old_ptr);
|
||||
uptr chunk_beg = p - kChunkHeaderSize;
|
||||
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
|
||||
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.reallocs++;
|
||||
thread_stats.realloced += new_size;
|
||||
|
||||
void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC, true);
|
||||
if (new_ptr) {
|
||||
u8 chunk_state = m->chunk_state;
|
||||
if (chunk_state != CHUNK_ALLOCATED)
|
||||
ReportInvalidFree(old_ptr, chunk_state, stack);
|
||||
CHECK_NE(REAL(memcpy), (void*)0);
|
||||
uptr memcpy_size = Min(new_size, m->UsedSize());
|
||||
// If realloc() races with free(), we may start copying freed memory.
|
||||
// However, we will report racy double-free later anyway.
|
||||
REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
|
||||
Deallocate(old_ptr, 0, stack, FROM_MALLOC);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
// Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).
|
||||
static AsanChunk *GetAsanChunk(void *alloc_beg) {
|
||||
if (!alloc_beg) return 0;
|
||||
if (!allocator.FromPrimary(alloc_beg)) {
|
||||
uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(alloc_beg));
|
||||
AsanChunk *m = reinterpret_cast<AsanChunk *>(meta[1]);
|
||||
return m;
|
||||
}
|
||||
uptr *alloc_magic = reinterpret_cast<uptr *>(alloc_beg);
|
||||
if (alloc_magic[0] == kAllocBegMagic)
|
||||
return reinterpret_cast<AsanChunk *>(alloc_magic[1]);
|
||||
return reinterpret_cast<AsanChunk *>(alloc_beg);
|
||||
}
|
||||
|
||||
static AsanChunk *GetAsanChunkByAddr(uptr p) {
|
||||
void *alloc_beg = allocator.GetBlockBegin(reinterpret_cast<void *>(p));
|
||||
return GetAsanChunk(alloc_beg);
|
||||
}
|
||||
|
||||
// Allocator must be locked when this function is called.
|
||||
static AsanChunk *GetAsanChunkByAddrFastLocked(uptr p) {
|
||||
void *alloc_beg =
|
||||
allocator.GetBlockBeginFastLocked(reinterpret_cast<void *>(p));
|
||||
return GetAsanChunk(alloc_beg);
|
||||
}
|
||||
|
||||
static uptr AllocationSize(uptr p) {
|
||||
AsanChunk *m = GetAsanChunkByAddr(p);
|
||||
if (!m) return 0;
|
||||
if (m->chunk_state != CHUNK_ALLOCATED) return 0;
|
||||
if (m->Beg() != p) return 0;
|
||||
return m->UsedSize();
|
||||
}
|
||||
|
||||
// We have an address between two chunks, and we want to report just one.
|
||||
AsanChunk *ChooseChunk(uptr addr,
|
||||
AsanChunk *left_chunk, AsanChunk *right_chunk) {
|
||||
// Prefer an allocated chunk over freed chunk and freed chunk
|
||||
// over available chunk.
|
||||
if (left_chunk->chunk_state != right_chunk->chunk_state) {
|
||||
if (left_chunk->chunk_state == CHUNK_ALLOCATED)
|
||||
return left_chunk;
|
||||
if (right_chunk->chunk_state == CHUNK_ALLOCATED)
|
||||
return right_chunk;
|
||||
if (left_chunk->chunk_state == CHUNK_QUARANTINE)
|
||||
return left_chunk;
|
||||
if (right_chunk->chunk_state == CHUNK_QUARANTINE)
|
||||
return right_chunk;
|
||||
}
|
||||
// Same chunk_state: choose based on offset.
|
||||
sptr l_offset = 0, r_offset = 0;
|
||||
CHECK(AsanChunkView(left_chunk).AddrIsAtRight(addr, 1, &l_offset));
|
||||
CHECK(AsanChunkView(right_chunk).AddrIsAtLeft(addr, 1, &r_offset));
|
||||
if (l_offset < r_offset)
|
||||
return left_chunk;
|
||||
return right_chunk;
|
||||
}
|
||||
|
||||
AsanChunkView FindHeapChunkByAddress(uptr addr) {
|
||||
AsanChunk *m1 = GetAsanChunkByAddr(addr);
|
||||
if (!m1) return AsanChunkView(m1);
|
||||
sptr offset = 0;
|
||||
if (AsanChunkView(m1).AddrIsAtLeft(addr, 1, &offset)) {
|
||||
// The address is in the chunk's left redzone, so maybe it is actually
|
||||
// a right buffer overflow from the other chunk to the left.
|
||||
// Search a bit to the left to see if there is another chunk.
|
||||
AsanChunk *m2 = 0;
|
||||
for (uptr l = 1; l < GetPageSizeCached(); l++) {
|
||||
m2 = GetAsanChunkByAddr(addr - l);
|
||||
if (m2 == m1) continue; // Still the same chunk.
|
||||
break;
|
||||
}
|
||||
if (m2 && AsanChunkView(m2).AddrIsAtRight(addr, 1, &offset))
|
||||
m1 = ChooseChunk(addr, m2, m1);
|
||||
}
|
||||
return AsanChunkView(m1);
|
||||
}
|
||||
|
||||
void AsanThreadLocalMallocStorage::CommitBack() {
|
||||
AllocatorCache *ac = GetAllocatorCache(this);
|
||||
quarantine.Drain(GetQuarantineCache(this), QuarantineCallback(ac));
|
||||
allocator.SwallowCache(GetAllocatorCache(this));
|
||||
}
|
||||
|
||||
void PrintInternalAllocatorStats() {
|
||||
allocator.PrintStats();
|
||||
}
|
||||
|
||||
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
return Allocate(size, alignment, stack, alloc_type, true);
|
||||
}
|
||||
|
||||
void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) {
|
||||
Deallocate(ptr, 0, stack, alloc_type);
|
||||
}
|
||||
|
||||
void asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
Deallocate(ptr, size, stack, alloc_type);
|
||||
}
|
||||
|
||||
void *asan_malloc(uptr size, BufferedStackTrace *stack) {
|
||||
return Allocate(size, 8, stack, FROM_MALLOC, true);
|
||||
}
|
||||
|
||||
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
|
||||
if (CallocShouldReturnNullDueToOverflow(size, nmemb))
|
||||
return AllocatorReturnNull();
|
||||
void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false);
|
||||
// If the memory comes from the secondary allocator no need to clear it
|
||||
// as it comes directly from mmap.
|
||||
if (ptr && allocator.FromPrimary(ptr))
|
||||
REAL(memset)(ptr, 0, nmemb * size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
|
||||
if (p == 0)
|
||||
return Allocate(size, 8, stack, FROM_MALLOC, true);
|
||||
if (size == 0) {
|
||||
Deallocate(p, 0, stack, FROM_MALLOC);
|
||||
return 0;
|
||||
}
|
||||
return Reallocate(p, size, stack);
|
||||
}
|
||||
|
||||
void *asan_valloc(uptr size, BufferedStackTrace *stack) {
|
||||
return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC, true);
|
||||
}
|
||||
|
||||
void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
|
||||
uptr PageSize = GetPageSizeCached();
|
||||
size = RoundUpTo(size, PageSize);
|
||||
if (size == 0) {
|
||||
// pvalloc(0) should allocate one page.
|
||||
size = PageSize;
|
||||
}
|
||||
return Allocate(size, PageSize, stack, FROM_MALLOC, true);
|
||||
}
|
||||
|
||||
int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
|
||||
BufferedStackTrace *stack) {
|
||||
void *ptr = Allocate(size, alignment, stack, FROM_MALLOC, true);
|
||||
CHECK(IsAligned((uptr)ptr, alignment));
|
||||
*memptr = ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp) {
|
||||
if (ptr == 0) return 0;
|
||||
uptr usable_size = AllocationSize(reinterpret_cast<uptr>(ptr));
|
||||
if (flags()->check_malloc_usable_size && (usable_size == 0)) {
|
||||
GET_STACK_TRACE_FATAL(pc, bp);
|
||||
ReportMallocUsableSizeNotOwned((uptr)ptr, &stack);
|
||||
}
|
||||
return usable_size;
|
||||
}
|
||||
|
||||
uptr asan_mz_size(const void *ptr) {
|
||||
return AllocationSize(reinterpret_cast<uptr>(ptr));
|
||||
}
|
||||
|
||||
void asan_mz_force_lock() {
|
||||
allocator.ForceLock();
|
||||
fallback_mutex.Lock();
|
||||
}
|
||||
|
||||
void asan_mz_force_unlock() {
|
||||
fallback_mutex.Unlock();
|
||||
allocator.ForceUnlock();
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
// --- Implementation of LSan-specific functions --- {{{1
|
||||
namespace __lsan {
|
||||
void LockAllocator() {
|
||||
__asan::allocator.ForceLock();
|
||||
}
|
||||
|
||||
void UnlockAllocator() {
|
||||
__asan::allocator.ForceUnlock();
|
||||
}
|
||||
|
||||
void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
|
||||
*begin = (uptr)&__asan::allocator;
|
||||
*end = *begin + sizeof(__asan::allocator);
|
||||
}
|
||||
|
||||
uptr PointsIntoChunk(void* p) {
|
||||
uptr addr = reinterpret_cast<uptr>(p);
|
||||
__asan::AsanChunk *m = __asan::GetAsanChunkByAddrFastLocked(addr);
|
||||
if (!m) return 0;
|
||||
uptr chunk = m->Beg();
|
||||
if (m->chunk_state != __asan::CHUNK_ALLOCATED)
|
||||
return 0;
|
||||
if (m->AddrIsInside(addr, /*locked_version=*/true))
|
||||
return chunk;
|
||||
if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),
|
||||
addr))
|
||||
return chunk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr GetUserBegin(uptr chunk) {
|
||||
__asan::AsanChunk *m =
|
||||
__asan::GetAsanChunkByAddrFastLocked(chunk);
|
||||
CHECK(m);
|
||||
return m->Beg();
|
||||
}
|
||||
|
||||
LsanMetadata::LsanMetadata(uptr chunk) {
|
||||
metadata_ = reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize);
|
||||
}
|
||||
|
||||
bool LsanMetadata::allocated() const {
|
||||
__asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
|
||||
return m->chunk_state == __asan::CHUNK_ALLOCATED;
|
||||
}
|
||||
|
||||
ChunkTag LsanMetadata::tag() const {
|
||||
__asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
|
||||
return static_cast<ChunkTag>(m->lsan_tag);
|
||||
}
|
||||
|
||||
void LsanMetadata::set_tag(ChunkTag value) {
|
||||
__asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
|
||||
m->lsan_tag = value;
|
||||
}
|
||||
|
||||
uptr LsanMetadata::requested_size() const {
|
||||
__asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
|
||||
return m->UsedSize(/*locked_version=*/true);
|
||||
}
|
||||
|
||||
u32 LsanMetadata::stack_trace_id() const {
|
||||
__asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
|
||||
return m->alloc_context_id;
|
||||
}
|
||||
|
||||
void ForEachChunk(ForEachChunkCallback callback, void *arg) {
|
||||
__asan::allocator.ForEachChunk(callback, arg);
|
||||
}
|
||||
|
||||
IgnoreObjectResult IgnoreObjectLocked(const void *p) {
|
||||
uptr addr = reinterpret_cast<uptr>(p);
|
||||
__asan::AsanChunk *m = __asan::GetAsanChunkByAddr(addr);
|
||||
if (!m) return kIgnoreObjectInvalid;
|
||||
if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && m->AddrIsInside(addr)) {
|
||||
if (m->lsan_tag == kIgnored)
|
||||
return kIgnoreObjectAlreadyIgnored;
|
||||
m->lsan_tag = __lsan::kIgnored;
|
||||
return kIgnoreObjectSuccess;
|
||||
} else {
|
||||
return kIgnoreObjectInvalid;
|
||||
}
|
||||
}
|
||||
} // namespace __lsan
|
||||
|
||||
// ---------------------- Interface ---------------- {{{1
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
// ASan allocator doesn't reserve extra bytes, so normally we would
|
||||
// just return "size". We don't want to expose our redzone sizes, etc here.
|
||||
uptr __sanitizer_get_estimated_allocated_size(uptr size) {
|
||||
return size;
|
||||
}
|
||||
|
||||
int __sanitizer_get_ownership(const void *p) {
|
||||
uptr ptr = reinterpret_cast<uptr>(p);
|
||||
return (AllocationSize(ptr) > 0);
|
||||
}
|
||||
|
||||
uptr __sanitizer_get_allocated_size(const void *p) {
|
||||
if (p == 0) return 0;
|
||||
uptr ptr = reinterpret_cast<uptr>(p);
|
||||
uptr allocated_size = AllocationSize(ptr);
|
||||
// Die if p is not malloced or if it is already freed.
|
||||
if (allocated_size == 0) {
|
||||
GET_STACK_TRACE_FATAL_HERE;
|
||||
ReportSanitizerGetAllocatedSizeNotOwned(ptr, &stack);
|
||||
}
|
||||
return allocated_size;
|
||||
}
|
||||
|
||||
#if !SANITIZER_SUPPORTS_WEAK_HOOKS
|
||||
// Provide default (no-op) implementation of malloc hooks.
|
||||
extern "C" {
|
||||
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
|
||||
void __sanitizer_malloc_hook(void *ptr, uptr size) {
|
||||
(void)ptr;
|
||||
(void)size;
|
||||
}
|
||||
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
|
||||
void __sanitizer_free_hook(void *ptr) {
|
||||
(void)ptr;
|
||||
}
|
||||
} // extern "C"
|
||||
#endif
|
13
contrib/compiler-rt/lib/asan/asan_blacklist.txt
Normal file
13
contrib/compiler-rt/lib/asan/asan_blacklist.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Blacklist for AddressSanitizer. Turns off instrumentation of particular
|
||||
# functions or sources. Use with care. You may set location of blacklist
|
||||
# at compile-time using -fsanitize-blacklist=<path> flag.
|
||||
|
||||
# Example usage:
|
||||
# fun:*bad_function_name*
|
||||
# src:file_with_tricky_code.cc
|
||||
# global:*global_with_bad_access_or_initialization*
|
||||
# global:*global_with_initialization_issues*=init
|
||||
# type:*Namespace::ClassName*=init
|
||||
|
||||
# Stack buffer overflow in VC/INCLUDE/xlocnum, see http://goo.gl/L4qqUG
|
||||
fun:*_Find_elem@*@std*
|
141
contrib/compiler-rt/lib/asan/asan_debugging.cc
Normal file
141
contrib/compiler-rt/lib/asan/asan_debugging.cc
Normal file
@ -0,0 +1,141 @@
|
||||
//===-- asan_debugging.cc -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file contains various functions that are generally useful to call when
|
||||
// using a debugger (LLDB, GDB).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "asan_allocator.h"
|
||||
#include "asan_flags.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_mapping.h"
|
||||
#include "asan_report.h"
|
||||
#include "asan_thread.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
void GetInfoForStackVar(uptr addr, AddressDescription *descr, AsanThread *t) {
|
||||
descr->name[0] = 0;
|
||||
descr->region_address = 0;
|
||||
descr->region_size = 0;
|
||||
descr->region_kind = "stack";
|
||||
|
||||
AsanThread::StackFrameAccess access;
|
||||
if (!t->GetStackFrameAccessByAddr(addr, &access))
|
||||
return;
|
||||
InternalMmapVector<StackVarDescr> vars(16);
|
||||
if (!ParseFrameDescription(access.frame_descr, &vars)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uptr i = 0; i < vars.size(); i++) {
|
||||
if (access.offset <= vars[i].beg + vars[i].size) {
|
||||
internal_strncat(descr->name, vars[i].name_pos,
|
||||
Min(descr->name_size, vars[i].name_len));
|
||||
descr->region_address = addr - (access.offset - vars[i].beg);
|
||||
descr->region_size = vars[i].size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetInfoForHeapAddress(uptr addr, AddressDescription *descr) {
|
||||
AsanChunkView chunk = FindHeapChunkByAddress(addr);
|
||||
|
||||
descr->name[0] = 0;
|
||||
descr->region_address = 0;
|
||||
descr->region_size = 0;
|
||||
|
||||
if (!chunk.IsValid()) {
|
||||
descr->region_kind = "heap-invalid";
|
||||
return;
|
||||
}
|
||||
|
||||
descr->region_address = chunk.Beg();
|
||||
descr->region_size = chunk.UsedSize();
|
||||
descr->region_kind = "heap";
|
||||
}
|
||||
|
||||
void AsanLocateAddress(uptr addr, AddressDescription *descr) {
|
||||
if (DescribeAddressIfShadow(addr, descr, /* print */ false)) {
|
||||
return;
|
||||
}
|
||||
if (GetInfoForAddressIfGlobal(addr, descr)) {
|
||||
return;
|
||||
}
|
||||
asanThreadRegistry().Lock();
|
||||
AsanThread *thread = FindThreadByStackAddress(addr);
|
||||
asanThreadRegistry().Unlock();
|
||||
if (thread) {
|
||||
GetInfoForStackVar(addr, descr, thread);
|
||||
return;
|
||||
}
|
||||
GetInfoForHeapAddress(addr, descr);
|
||||
}
|
||||
|
||||
uptr AsanGetStack(uptr addr, uptr *trace, uptr size, u32 *thread_id,
|
||||
bool alloc_stack) {
|
||||
AsanChunkView chunk = FindHeapChunkByAddress(addr);
|
||||
if (!chunk.IsValid()) return 0;
|
||||
|
||||
StackTrace stack(nullptr, 0);
|
||||
if (alloc_stack) {
|
||||
if (chunk.AllocTid() == kInvalidTid) return 0;
|
||||
stack = chunk.GetAllocStack();
|
||||
if (thread_id) *thread_id = chunk.AllocTid();
|
||||
} else {
|
||||
if (chunk.FreeTid() == kInvalidTid) return 0;
|
||||
stack = chunk.GetFreeStack();
|
||||
if (thread_id) *thread_id = chunk.FreeTid();
|
||||
}
|
||||
|
||||
if (trace && size) {
|
||||
size = Min(size, Min(stack.size, kStackTraceMax));
|
||||
for (uptr i = 0; i < size; i++)
|
||||
trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
using namespace __asan;
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
|
||||
uptr *region_address, uptr *region_size) {
|
||||
AddressDescription descr = { name, name_size, 0, 0, 0 };
|
||||
AsanLocateAddress(addr, &descr);
|
||||
if (region_address) *region_address = descr.region_address;
|
||||
if (region_size) *region_size = descr.region_size;
|
||||
return descr.region_kind;
|
||||
}
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
|
||||
return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true);
|
||||
}
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
|
||||
return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false);
|
||||
}
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) {
|
||||
if (shadow_scale)
|
||||
*shadow_scale = SHADOW_SCALE;
|
||||
if (shadow_offset)
|
||||
*shadow_offset = SHADOW_OFFSET;
|
||||
}
|
257
contrib/compiler-rt/lib/asan/asan_fake_stack.cc
Normal file
257
contrib/compiler-rt/lib/asan/asan_fake_stack.cc
Normal file
@ -0,0 +1,257 @@
|
||||
//===-- asan_fake_stack.cc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// FakeStack is used to detect use-after-return bugs.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "asan_allocator.h"
|
||||
#include "asan_poisoning.h"
|
||||
#include "asan_thread.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
static const u64 kMagic1 = kAsanStackAfterReturnMagic;
|
||||
static const u64 kMagic2 = (kMagic1 << 8) | kMagic1;
|
||||
static const u64 kMagic4 = (kMagic2 << 16) | kMagic2;
|
||||
static const u64 kMagic8 = (kMagic4 << 32) | kMagic4;
|
||||
|
||||
// For small size classes inline PoisonShadow for better performance.
|
||||
ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
|
||||
CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3.
|
||||
u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
|
||||
if (class_id <= 6) {
|
||||
for (uptr i = 0; i < (1U << class_id); i++) {
|
||||
shadow[i] = magic;
|
||||
SanitizerBreakOptimization(0); // Make sure this does not become memset.
|
||||
}
|
||||
} else {
|
||||
// The size class is too big, it's cheaper to poison only size bytes.
|
||||
PoisonShadow(ptr, size, static_cast<u8>(magic));
|
||||
}
|
||||
}
|
||||
|
||||
FakeStack *FakeStack::Create(uptr stack_size_log) {
|
||||
static uptr kMinStackSizeLog = 16;
|
||||
static uptr kMaxStackSizeLog = FIRST_32_SECOND_64(24, 28);
|
||||
if (stack_size_log < kMinStackSizeLog)
|
||||
stack_size_log = kMinStackSizeLog;
|
||||
if (stack_size_log > kMaxStackSizeLog)
|
||||
stack_size_log = kMaxStackSizeLog;
|
||||
uptr size = RequiredSize(stack_size_log);
|
||||
FakeStack *res = reinterpret_cast<FakeStack *>(
|
||||
flags()->uar_noreserve ? MmapNoReserveOrDie(size, "FakeStack")
|
||||
: MmapOrDie(size, "FakeStack"));
|
||||
res->stack_size_log_ = stack_size_log;
|
||||
u8 *p = reinterpret_cast<u8 *>(res);
|
||||
VReport(1, "T%d: FakeStack created: %p -- %p stack_size_log: %zd; "
|
||||
"mmapped %zdK, noreserve=%d \n",
|
||||
GetCurrentTidOrInvalid(), p,
|
||||
p + FakeStack::RequiredSize(stack_size_log), stack_size_log,
|
||||
size >> 10, flags()->uar_noreserve);
|
||||
return res;
|
||||
}
|
||||
|
||||
void FakeStack::Destroy(int tid) {
|
||||
PoisonAll(0);
|
||||
if (common_flags()->verbosity >= 2) {
|
||||
InternalScopedString str(kNumberOfSizeClasses * 50);
|
||||
for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++)
|
||||
str.append("%zd: %zd/%zd; ", class_id, hint_position_[class_id],
|
||||
NumberOfFrames(stack_size_log(), class_id));
|
||||
Report("T%d: FakeStack destroyed: %s\n", tid, str.data());
|
||||
}
|
||||
uptr size = RequiredSize(stack_size_log_);
|
||||
FlushUnneededASanShadowMemory(reinterpret_cast<uptr>(this), size);
|
||||
UnmapOrDie(this, size);
|
||||
}
|
||||
|
||||
void FakeStack::PoisonAll(u8 magic) {
|
||||
PoisonShadow(reinterpret_cast<uptr>(this), RequiredSize(stack_size_log()),
|
||||
magic);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE USED
|
||||
FakeFrame *FakeStack::Allocate(uptr stack_size_log, uptr class_id,
|
||||
uptr real_stack) {
|
||||
CHECK_LT(class_id, kNumberOfSizeClasses);
|
||||
if (needs_gc_)
|
||||
GC(real_stack);
|
||||
uptr &hint_position = hint_position_[class_id];
|
||||
const int num_iter = NumberOfFrames(stack_size_log, class_id);
|
||||
u8 *flags = GetFlags(stack_size_log, class_id);
|
||||
for (int i = 0; i < num_iter; i++) {
|
||||
uptr pos = ModuloNumberOfFrames(stack_size_log, class_id, hint_position++);
|
||||
// This part is tricky. On one hand, checking and setting flags[pos]
|
||||
// should be atomic to ensure async-signal safety. But on the other hand,
|
||||
// if the signal arrives between checking and setting flags[pos], the
|
||||
// signal handler's fake stack will start from a different hint_position
|
||||
// and so will not touch this particular byte. So, it is safe to do this
|
||||
// with regular non-atimic load and store (at least I was not able to make
|
||||
// this code crash).
|
||||
if (flags[pos]) continue;
|
||||
flags[pos] = 1;
|
||||
FakeFrame *res = reinterpret_cast<FakeFrame *>(
|
||||
GetFrame(stack_size_log, class_id, pos));
|
||||
res->real_stack = real_stack;
|
||||
*SavedFlagPtr(reinterpret_cast<uptr>(res), class_id) = &flags[pos];
|
||||
return res;
|
||||
}
|
||||
return 0; // We are out of fake stack.
|
||||
}
|
||||
|
||||
uptr FakeStack::AddrIsInFakeStack(uptr ptr, uptr *frame_beg, uptr *frame_end) {
|
||||
uptr stack_size_log = this->stack_size_log();
|
||||
uptr beg = reinterpret_cast<uptr>(GetFrame(stack_size_log, 0, 0));
|
||||
uptr end = reinterpret_cast<uptr>(this) + RequiredSize(stack_size_log);
|
||||
if (ptr < beg || ptr >= end) return 0;
|
||||
uptr class_id = (ptr - beg) >> stack_size_log;
|
||||
uptr base = beg + (class_id << stack_size_log);
|
||||
CHECK_LE(base, ptr);
|
||||
CHECK_LT(ptr, base + (1UL << stack_size_log));
|
||||
uptr pos = (ptr - base) >> (kMinStackFrameSizeLog + class_id);
|
||||
uptr res = base + pos * BytesInSizeClass(class_id);
|
||||
*frame_end = res + BytesInSizeClass(class_id);
|
||||
*frame_beg = res + sizeof(FakeFrame);
|
||||
return res;
|
||||
}
|
||||
|
||||
void FakeStack::HandleNoReturn() {
|
||||
needs_gc_ = true;
|
||||
}
|
||||
|
||||
// When throw, longjmp or some such happens we don't call OnFree() and
|
||||
// as the result may leak one or more fake frames, but the good news is that
|
||||
// we are notified about all such events by HandleNoReturn().
|
||||
// If we recently had such no-return event we need to collect garbage frames.
|
||||
// We do it based on their 'real_stack' values -- everything that is lower
|
||||
// than the current real_stack is garbage.
|
||||
NOINLINE void FakeStack::GC(uptr real_stack) {
|
||||
uptr collected = 0;
|
||||
for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {
|
||||
u8 *flags = GetFlags(stack_size_log(), class_id);
|
||||
for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;
|
||||
i++) {
|
||||
if (flags[i] == 0) continue; // not allocated.
|
||||
FakeFrame *ff = reinterpret_cast<FakeFrame *>(
|
||||
GetFrame(stack_size_log(), class_id, i));
|
||||
if (ff->real_stack < real_stack) {
|
||||
flags[i] = 0;
|
||||
collected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
needs_gc_ = false;
|
||||
}
|
||||
|
||||
void FakeStack::ForEachFakeFrame(RangeIteratorCallback callback, void *arg) {
|
||||
for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {
|
||||
u8 *flags = GetFlags(stack_size_log(), class_id);
|
||||
for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;
|
||||
i++) {
|
||||
if (flags[i] == 0) continue; // not allocated.
|
||||
FakeFrame *ff = reinterpret_cast<FakeFrame *>(
|
||||
GetFrame(stack_size_log(), class_id, i));
|
||||
uptr begin = reinterpret_cast<uptr>(ff);
|
||||
callback(begin, begin + FakeStack::BytesInSizeClass(class_id), arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
static THREADLOCAL FakeStack *fake_stack_tls;
|
||||
|
||||
FakeStack *GetTLSFakeStack() {
|
||||
return fake_stack_tls;
|
||||
}
|
||||
void SetTLSFakeStack(FakeStack *fs) {
|
||||
fake_stack_tls = fs;
|
||||
}
|
||||
#else
|
||||
FakeStack *GetTLSFakeStack() { return 0; }
|
||||
void SetTLSFakeStack(FakeStack *fs) { }
|
||||
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
|
||||
static FakeStack *GetFakeStack() {
|
||||
AsanThread *t = GetCurrentThread();
|
||||
if (!t) return 0;
|
||||
return t->fake_stack();
|
||||
}
|
||||
|
||||
static FakeStack *GetFakeStackFast() {
|
||||
if (FakeStack *fs = GetTLSFakeStack())
|
||||
return fs;
|
||||
if (!__asan_option_detect_stack_use_after_return)
|
||||
return 0;
|
||||
return GetFakeStack();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size, uptr real_stack) {
|
||||
FakeStack *fs = GetFakeStackFast();
|
||||
if (!fs) return real_stack;
|
||||
FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack);
|
||||
if (!ff)
|
||||
return real_stack; // Out of fake stack, return the real one.
|
||||
uptr ptr = reinterpret_cast<uptr>(ff);
|
||||
SetShadow(ptr, size, class_id, 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size, uptr real_stack) {
|
||||
if (ptr == real_stack)
|
||||
return;
|
||||
FakeStack::Deallocate(ptr, class_id);
|
||||
SetShadow(ptr, size, class_id, kMagic8);
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
// ---------------------- Interface ---------------- {{{1
|
||||
using namespace __asan;
|
||||
#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id) \
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr \
|
||||
__asan_stack_malloc_##class_id(uptr size, uptr real_stack) { \
|
||||
return OnMalloc(class_id, size, real_stack); \
|
||||
} \
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __asan_stack_free_##class_id( \
|
||||
uptr ptr, uptr size, uptr real_stack) { \
|
||||
OnFree(ptr, class_id, size, real_stack); \
|
||||
}
|
||||
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9)
|
||||
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10)
|
||||
extern "C" {
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
void *__asan_get_current_fake_stack() { return GetFakeStackFast(); }
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
|
||||
void **end) {
|
||||
FakeStack *fs = reinterpret_cast<FakeStack*>(fake_stack);
|
||||
if (!fs) return 0;
|
||||
uptr frame_beg, frame_end;
|
||||
FakeFrame *frame = reinterpret_cast<FakeFrame *>(fs->AddrIsInFakeStack(
|
||||
reinterpret_cast<uptr>(addr), &frame_beg, &frame_end));
|
||||
if (!frame) return 0;
|
||||
if (frame->magic != kCurrentStackFrameMagic)
|
||||
return 0;
|
||||
if (beg) *beg = reinterpret_cast<void*>(frame_beg);
|
||||
if (end) *end = reinterpret_cast<void*>(frame_end);
|
||||
return reinterpret_cast<void*>(frame->real_stack);
|
||||
}
|
||||
} // extern "C"
|
175
contrib/compiler-rt/lib/asan/asan_fake_stack.h
Normal file
175
contrib/compiler-rt/lib/asan/asan_fake_stack.h
Normal file
@ -0,0 +1,175 @@
|
||||
//===-- asan_fake_stack.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// ASan-private header for asan_fake_stack.cc, implements FakeStack.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ASAN_FAKE_STACK_H
|
||||
#define ASAN_FAKE_STACK_H
|
||||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
// Fake stack frame contains local variables of one function.
|
||||
struct FakeFrame {
|
||||
uptr magic; // Modified by the instrumented code.
|
||||
uptr descr; // Modified by the instrumented code.
|
||||
uptr pc; // Modified by the instrumented code.
|
||||
uptr real_stack;
|
||||
};
|
||||
|
||||
// For each thread we create a fake stack and place stack objects on this fake
|
||||
// stack instead of the real stack. The fake stack is not really a stack but
|
||||
// a fast malloc-like allocator so that when a function exits the fake stack
|
||||
// is not popped but remains there for quite some time until gets used again.
|
||||
// So, we poison the objects on the fake stack when function returns.
|
||||
// It helps us find use-after-return bugs.
|
||||
//
|
||||
// The FakeStack objects is allocated by a single mmap call and has no other
|
||||
// pointers. The size of the fake stack depends on the actual thread stack size
|
||||
// and thus can not be a constant.
|
||||
// stack_size is a power of two greater or equal to the thread's stack size;
|
||||
// we store it as its logarithm (stack_size_log).
|
||||
// FakeStack has kNumberOfSizeClasses (11) size classes, each size class
|
||||
// is a power of two, starting from 64 bytes. Each size class occupies
|
||||
// stack_size bytes and thus can allocate
|
||||
// NumberOfFrames=(stack_size/BytesInSizeClass) fake frames (also a power of 2).
|
||||
// For each size class we have NumberOfFrames allocation flags,
|
||||
// each flag indicates whether the given frame is currently allocated.
|
||||
// All flags for size classes 0 .. 10 are stored in a single contiguous region
|
||||
// followed by another contiguous region which contains the actual memory for
|
||||
// size classes. The addresses are computed by GetFlags and GetFrame without
|
||||
// any memory accesses solely based on 'this' and stack_size_log.
|
||||
// Allocate() flips the appropriate allocation flag atomically, thus achieving
|
||||
// async-signal safety.
|
||||
// This allocator does not have quarantine per se, but it tries to allocate the
|
||||
// frames in round robin fasion to maximize the delay between a deallocation
|
||||
// and the next allocation.
|
||||
class FakeStack {
|
||||
static const uptr kMinStackFrameSizeLog = 6; // Min frame is 64B.
|
||||
static const uptr kMaxStackFrameSizeLog = 16; // Max stack frame is 64K.
|
||||
|
||||
public:
|
||||
static const uptr kNumberOfSizeClasses =
|
||||
kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1;
|
||||
|
||||
// CTOR: create the FakeStack as a single mmap-ed object.
|
||||
static FakeStack *Create(uptr stack_size_log);
|
||||
|
||||
void Destroy(int tid);
|
||||
|
||||
// stack_size_log is at least 15 (stack_size >= 32K).
|
||||
static uptr SizeRequiredForFlags(uptr stack_size_log) {
|
||||
return 1UL << (stack_size_log + 1 - kMinStackFrameSizeLog);
|
||||
}
|
||||
|
||||
// Each size class occupies stack_size bytes.
|
||||
static uptr SizeRequiredForFrames(uptr stack_size_log) {
|
||||
return (1ULL << stack_size_log) * kNumberOfSizeClasses;
|
||||
}
|
||||
|
||||
// Number of bytes requires for the whole object.
|
||||
static uptr RequiredSize(uptr stack_size_log) {
|
||||
return kFlagsOffset + SizeRequiredForFlags(stack_size_log) +
|
||||
SizeRequiredForFrames(stack_size_log);
|
||||
}
|
||||
|
||||
// Offset of the given flag from the first flag.
|
||||
// The flags for class 0 begin at offset 000000000
|
||||
// The flags for class 1 begin at offset 100000000
|
||||
// ....................2................ 110000000
|
||||
// ....................3................ 111000000
|
||||
// and so on.
|
||||
static uptr FlagsOffset(uptr stack_size_log, uptr class_id) {
|
||||
uptr t = kNumberOfSizeClasses - 1 - class_id;
|
||||
const uptr all_ones = (1 << (kNumberOfSizeClasses - 1)) - 1;
|
||||
return ((all_ones >> t) << t) << (stack_size_log - 15);
|
||||
}
|
||||
|
||||
static uptr NumberOfFrames(uptr stack_size_log, uptr class_id) {
|
||||
return 1UL << (stack_size_log - kMinStackFrameSizeLog - class_id);
|
||||
}
|
||||
|
||||
// Divide n by the numbe of frames in size class.
|
||||
static uptr ModuloNumberOfFrames(uptr stack_size_log, uptr class_id, uptr n) {
|
||||
return n & (NumberOfFrames(stack_size_log, class_id) - 1);
|
||||
}
|
||||
|
||||
// The the pointer to the flags of the given class_id.
|
||||
u8 *GetFlags(uptr stack_size_log, uptr class_id) {
|
||||
return reinterpret_cast<u8 *>(this) + kFlagsOffset +
|
||||
FlagsOffset(stack_size_log, class_id);
|
||||
}
|
||||
|
||||
// Get frame by class_id and pos.
|
||||
u8 *GetFrame(uptr stack_size_log, uptr class_id, uptr pos) {
|
||||
return reinterpret_cast<u8 *>(this) + kFlagsOffset +
|
||||
SizeRequiredForFlags(stack_size_log) +
|
||||
(1 << stack_size_log) * class_id + BytesInSizeClass(class_id) * pos;
|
||||
}
|
||||
|
||||
// Allocate the fake frame.
|
||||
FakeFrame *Allocate(uptr stack_size_log, uptr class_id, uptr real_stack);
|
||||
|
||||
// Deallocate the fake frame: read the saved flag address and write 0 there.
|
||||
static void Deallocate(uptr x, uptr class_id) {
|
||||
**SavedFlagPtr(x, class_id) = 0;
|
||||
}
|
||||
|
||||
// Poison the entire FakeStack's shadow with the magic value.
|
||||
void PoisonAll(u8 magic);
|
||||
|
||||
// Return the beginning of the FakeFrame or 0 if the address is not ours.
|
||||
uptr AddrIsInFakeStack(uptr addr, uptr *frame_beg, uptr *frame_end);
|
||||
USED uptr AddrIsInFakeStack(uptr addr) {
|
||||
uptr t1, t2;
|
||||
return AddrIsInFakeStack(addr, &t1, &t2);
|
||||
}
|
||||
|
||||
// Number of bytes in a fake frame of this size class.
|
||||
static uptr BytesInSizeClass(uptr class_id) {
|
||||
return 1UL << (class_id + kMinStackFrameSizeLog);
|
||||
}
|
||||
|
||||
// The fake frame is guaranteed to have a right redzone.
|
||||
// We use the last word of that redzone to store the address of the flag
|
||||
// that corresponds to the current frame to make faster deallocation.
|
||||
static u8 **SavedFlagPtr(uptr x, uptr class_id) {
|
||||
return reinterpret_cast<u8 **>(x + BytesInSizeClass(class_id) - sizeof(x));
|
||||
}
|
||||
|
||||
uptr stack_size_log() const { return stack_size_log_; }
|
||||
|
||||
void HandleNoReturn();
|
||||
void GC(uptr real_stack);
|
||||
|
||||
void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
|
||||
|
||||
private:
|
||||
FakeStack() { }
|
||||
static const uptr kFlagsOffset = 4096; // This is were the flags begin.
|
||||
// Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
|
||||
COMPILER_CHECK(kNumberOfSizeClasses == 11);
|
||||
static const uptr kMaxStackMallocSize = 1 << kMaxStackFrameSizeLog;
|
||||
|
||||
uptr hint_position_[kNumberOfSizeClasses];
|
||||
uptr stack_size_log_;
|
||||
// a bit is set if something was allocated from the corresponding size class.
|
||||
bool needs_gc_;
|
||||
};
|
||||
|
||||
FakeStack *GetTLSFakeStack();
|
||||
void SetTLSFakeStack(FakeStack *fs);
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
#endif // ASAN_FAKE_STACK_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user