MFhead @ r277403

This commit is contained in:
Enji Cooper 2015-01-19 22:18:00 +00:00
commit 51dd214c84
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/building-blocks/; revision=277404
3158 changed files with 223602 additions and 67477 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#if defined(sun)
#ifdef illumos
#include <alloca.h>
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
#include <assert.h>
#include <strings.h>
#if defined(sun)
#ifdef illumos
#include <alloca.h>
#endif
#include <fcntl.h>

View File

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

View File

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

View File

@ -30,7 +30,7 @@
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#if defined(sun)
#ifdef illumos
#include <alloca.h>
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@
* APIs for the barrier synchronization primitive.
*/
#if defined(sun)
#ifdef illumos
#include <synch.h>
#else
#include <semaphore.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -171,7 +171,7 @@ aborterr(const char *format, ...)
whine("ERROR", format, ap);
va_end(ap);
#if defined(sun)
#ifdef illumos
abort();
#else
exit(0);

View File

@ -0,0 +1 @@
@set VERSION "2.17.50 [FreeBSD] 2007-07-03"

File diff suppressed because it is too large Load Diff

View 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

View File

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

View File

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

View 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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View 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

View File

@ -0,0 +1,3 @@
__asan_*
__lsan_*
__ubsan_*

View 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

View 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

View 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

View 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

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

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

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

View 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