--- ./attic/backwards.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./attic/backwards.c	2019-11-23 17:54:09.000000000 -0800
@@ -7,6 +7,8 @@
 #include <stdlib.h>
 #include <time.h>
 
+#include "ntp_machine.h"	/* For clock_gettime fallback */
+
 #define UNUSED_ARG(arg)         ((void)(arg))
 
 static void ts_print(struct timespec *ts0, struct timespec *ts1);
--- ./attic/clocks.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./attic/clocks.c	2019-11-23 17:54:09.000000000 -0800
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <time.h>
 
+#include "ntp_machine.h"	/* For clock_gettime fallback */
+
 struct table {
   const int type;
   const char* name;
--- ./attic/digest-timing.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./attic/digest-timing.c	2019-11-23 17:54:09.000000000 -0800
@@ -34,6 +34,8 @@
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 
+#include "ntp_machine.h"	/* For clock_gettime fallback */
+
 #define UNUSED_ARG(arg)         ((void)(arg))
 
 #ifndef EVP_MD_CTX_reset
--- ./include/ntp_machine.h.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./include/ntp_machine.h	2019-11-23 17:54:09.000000000 -0800
@@ -13,14 +13,145 @@
 
 #ifndef CLOCK_REALTIME
 /*
- * Pacify platforms that don't have a real clock_gettime(2),
- * notably Mac OS X.
+ * Handle platforms that don't have a real clock_gettime(2),
+ * notably some versions of Mac OS X.
  */
-#define CLOCK_REALTIME	0
-#define CLOCK_MONOTONIC	1
+
+#include <errno.h>
+
 typedef int clockid_t;
-int clock_gettime(clockid_t clock_id, struct timespec *tp);
-#endif
+
+#define CLOCK_REALTIME	0
+
+#ifdef __APPLE__
+
+#define CLOCK_MONOTONIC 1
+#define CLOCK_MONOTONIC_RAW 2
+
+#include <mach/clock.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+#endif /* __APPLE__ */
+
+static inline int clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+    switch (clk_id) {
+
+    case CLOCK_REALTIME:
+	{
+	    /*
+	     * On OSX, it's tempting to use clock_get_time() for its apparent
+	     * nanosecond resolution, but it really only has microsecond
+	     * resolution, and is substantially slower than gettimeofday().
+	     */
+	    struct timeval tv;
+
+	    if (gettimeofday(&tv, NULL))
+		return -1;
+	    tp->tv_sec = tv.tv_sec;
+	    tp->tv_nsec = tv.tv_usec * 1000;
+	    return 0;
+	}
+
+#ifdef __APPLE__
+    case CLOCK_MONOTONIC:
+	{
+	    mach_timespec_t mts;
+	    static clock_serv_t sclock = 0;
+
+	    /*
+	     * Obtain clock port on first call, then reuse it.
+	     * Rely on exit cleanup to free it.
+	     */
+	    if (!sclock) {
+		mach_port_t mach_host = mach_host_self();
+		host_get_clock_service(mach_host,
+		    SYSTEM_CLOCK, &sclock);
+		mach_port_deallocate(mach_task_self(), mach_host);
+	    }
+	    clock_get_time(sclock, &mts);
+	    tp->tv_sec = mts.tv_sec;
+	    tp->tv_nsec = mts.tv_nsec;
+	    return 0;
+	}
+
+    case CLOCK_MONOTONIC_RAW:
+	{
+	    static mach_timebase_info_data_t sTimebaseInfo = {0, 0};
+	    unsigned long long nanos;
+
+	    /* Obtain scale factors on first call, then reuse them. */
+	    if ( sTimebaseInfo.denom == 0 ) {
+		    (void) mach_timebase_info(&sTimebaseInfo);
+	    }
+	    nanos = mach_absolute_time()
+		    * sTimebaseInfo.numer / sTimebaseInfo.denom;
+	    tp->tv_sec = nanos / 1000000000U;
+	    tp->tv_nsec = nanos - tp->tv_sec * 1000000000U;
+	    return 0;
+	}
+#endif /* __APPLE__ */
+
+    default:
+	errno = EINVAL;
+	return -1;
+    }
+}
+
+static inline int clock_getres(clockid_t clk_id, struct timespec *res)
+{
+    switch (clk_id) {
+
+    case CLOCK_REALTIME:
+	res->tv_sec = 0;
+	res->tv_nsec = 1000;
+	return 0;
+
+#ifdef __APPLE__
+    case CLOCK_MONOTONIC:
+    case CLOCK_MONOTONIC_RAW:
+	res->tv_sec = 0;
+	res->tv_nsec = 1;
+	return 0;
+#endif /* __APPLE__ */
+
+    default:
+	errno = EINVAL;
+	return -1;
+    }
+}
+
+/*
+ * Prototype for settimeofday() may suppressed by feature-test flags.
+ * Provide it here just in case, and get an error if it mismatches.
+ * Similarly, "struct timezone" definition may be suppressed, but the
+ * incomplete definition provided here is adequate given that the
+ * timezone argument is unused.
+ */
+struct timezone;
+int settimeofday(const struct timeval *, const struct timezone *);
+
+static inline int clock_settime(clockid_t clk_id, const struct timespec *tp)
+{
+    switch (clk_id) {
+
+    case CLOCK_REALTIME:
+	{
+	    struct timeval tv;
+
+	    tv.tv_sec = tp->tv_sec;
+	    tv.tv_usec = (tp->tv_nsec + 500) / 1000;
+	    return settimeofday(&tv, NULL);
+	}
+
+    default:
+	errno = EINVAL;
+	return -1;
+    }
+}
+
+#endif /* !CLOCK_REALTIME */
 
 int ntp_set_tod (struct timespec *tvs);
 
--- ./include/ntp_stdlib.h.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./include/ntp_stdlib.h	2019-11-23 17:54:09.000000000 -0800
@@ -95,7 +95,9 @@ extern	const char * eventstr	(int);
 extern	const char * ceventstr	(int);
 extern	const char * res_match_flags(unsigned short);
 extern	const char * res_access_flags(unsigned short);
+#ifdef HAVE_KERNEL_PLL
 extern	const char * k_st_flags	(uint32_t);
+#endif
 extern	char *	statustoa	(int, int);
 extern	const char * socktoa	(const sockaddr_u *);
 extern	const char * socktoa_r	(const sockaddr_u *sock, char *buf, size_t buflen);
--- ./include/ntp_syscall.h.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./include/ntp_syscall.h	2019-11-23 17:54:09.000000000 -0800
@@ -9,9 +9,11 @@
 #ifndef GUARD_NTP_SYSCALL_H
 #define GUARD_NTP_SYSCALL_H
 
+#ifdef HAVE_SYS_TIMEX_H
 # include <sys/time.h>	/* prerequisite on NetBSD */
 # include <sys/timex.h>
 extern int ntp_adjtime_ns(struct timex *);
+#endif
 
 /*
  * The units of the maxerror and esterror fields vary by platform.  If
--- ./libntp/clockwork.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./libntp/clockwork.c	2019-11-23 17:54:09.000000000 -0800
@@ -5,8 +5,10 @@
 #include "config.h"
 
 #include <unistd.h>
-#include <sys/time.h>	/* prerequisite on NetBSD */
-#include <sys/timex.h>
+#ifdef HAVE_SYS_TIMEX_H
+# include <sys/time.h>	/* prerequisite on NetBSD */
+# include <sys/timex.h>
+#endif
 
 #include "ntp.h"
 #include "ntp_machine.h"
--- ./libntp/statestr.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./libntp/statestr.c	2019-11-23 17:54:09.000000000 -0800
@@ -12,7 +12,9 @@
 #include "lib_strbuf.h"
 #include "ntp_refclock.h"
 #include "ntp_control.h"
+#ifdef HAVE_KERNEL_PLL
 # include "ntp_syscall.h"
+#endif
 
 
 /*
@@ -186,23 +188,50 @@ static const struct codestring res_acces
 	/* not used with getcode(), no terminating entry needed */
 };
 
+#ifdef HAVE_KERNEL_PLL
 /*
  * kernel discipline status bits
  */
 static const struct codestring k_st_bits[] = {
+# ifdef STA_PLL
 	{ STA_PLL,			"pll" },
+# endif
+# ifdef STA_PPSFREQ
 	{ STA_PPSFREQ,			"ppsfreq" },
+# endif
+# ifdef STA_PPSTIME
 	{ STA_PPSTIME,			"ppstime" },
+# endif
+# ifdef STA_FLL
 	{ STA_FLL,			"fll" },
+# endif
+# ifdef STA_INS
 	{ STA_INS,			"ins" },
+# endif
+# ifdef STA_DEL
 	{ STA_DEL,			"del" },
+# endif
+# ifdef STA_UNSYNC
 	{ STA_UNSYNC,			"unsync" },
+# endif
+# ifdef STA_FREQHOLD
 	{ STA_FREQHOLD,			"freqhold" },
+# endif
+# ifdef STA_PPSSIGNAL
 	{ STA_PPSSIGNAL,		"ppssignal" },
+# endif
+# ifdef STA_PPSJITTER
 	{ STA_PPSJITTER,		"ppsjitter" },
+# endif
+# ifdef STA_PPSWANDER
 	{ STA_PPSWANDER,		"ppswander" },
+# endif
+# ifdef STA_PPSERROR
 	{ STA_PPSERROR,			"ppserror" },
+# endif
+# ifdef STA_CLOCKERR
 	{ STA_CLOCKERR,			"clockerr" },
+# endif
 # ifdef STA_NANO
 	{ STA_NANO,			"nano" },
 # endif
@@ -214,6 +243,7 @@ static const struct codestring k_st_bits
 # endif
 	/* not used with getcode(), no terminating entry needed */
 };
+#endif	/* HAVE_KERNEL_PLL */
 
 /* Forwards */
 static const char *	getcode(int, const struct codestring *);
@@ -318,10 +348,12 @@ decode_bitflags(
 		 "decode_bitflags(%s) can't decode 0x%x in %d bytes",
 		 (tab == peer_st_bits)
 		     ? "peer_st"
-		     :
+		     : 
+#ifdef HAVE_KERNEL_PLL
 		       (tab == k_st_bits)
 			   ? "kern_st"
 			   :
+#endif
 			     "",
 		 (unsigned)bits, (int)LIB_BUFLENGTH);
 	errno = saved_errno;
@@ -360,6 +392,7 @@ res_access_flags(
 }
 
 
+#ifdef HAVE_KERNEL_PLL
 const char *
 k_st_flags(
 	uint32_t st
@@ -367,6 +400,8 @@ k_st_flags(
 {
 	return decode_bitflags((int)st, " ", k_st_bits, COUNTOF(k_st_bits));
 }
+#endif	/* HAVE_KERNEL_PLL */
+
 
 /*
  * statustoa - return a descriptive string for a peer status
--- ./ntpd/ntp_control.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./ntpd/ntp_control.c	2019-11-23 17:54:09.000000000 -0800
@@ -1359,6 +1359,7 @@ ctl_putsys(
 	char str[256];
 	double dtemp;
 	const char *ss;
+#ifdef HAVE_KERNEL_PLL
 	static struct timex ntx;
 	static unsigned long ntp_adjtime_time;
 
@@ -1374,6 +1375,7 @@ ctl_putsys(
 		else
                     ntp_adjtime_time = current_time;
 	}
+#endif	/* HAVE_KERNEL_PLL */
 
 	switch (varid) {
 
@@ -1769,50 +1771,93 @@ ctl_putsys(
 		break;
 
 		/*
-		 * CTL_IF_KERNPPS() puts a zero if kernel hard PPS is not
+		 * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
+		 * unavailable, otherwise calls putfunc with args.
+		 */
+#ifndef HAVE_KERNEL_PLL
+# define	CTL_IF_KERNLOOP(putfunc, args)	\
+		ctl_putint(sys_var[varid].text, 0)
+#else
+# define	CTL_IF_KERNLOOP(putfunc, args)	\
+		putfunc args
+#endif
+
+		/*
+		 * CTL_IF_KERNPPS() puts a zero if either the kernel
+		 * loop is unavailable, or kernel hard PPS is not
 		 * active, otherwise calls putfunc with args.
 		 */
+#ifndef HAVE_KERNEL_PLL
+# define	CTL_IF_KERNPPS(putfunc, args)	\
+		ctl_putint(sys_var[varid].text, 0)
+#else
 # define	CTL_IF_KERNPPS(putfunc, args)			\
 		if (0 == ntx.shift)				\
 			ctl_putint(sys_var[varid].text, 0);	\
 		else						\
 			putfunc args	/* no trailing ; */
+#endif
 
 	case CS_K_OFFSET:
-		ctl_putdblf(sys_var[varid].text, false, -1,
-			ntp_error_in_seconds(ntx.offset) * MS_PER_S);
+		CTL_IF_KERNLOOP(
+			ctl_putdblf,
+			(sys_var[varid].text, false, -1,
+			 ntp_error_in_seconds(ntx.offset) * MS_PER_S)
+		);
 		break;
 
 	case CS_K_FREQ:
-		ctl_putsfp(sys_var[varid].text, ntx.freq);
+		CTL_IF_KERNLOOP(
+			ctl_putsfp,
+			(sys_var[varid].text, ntx.freq)
+		);
 		break;
 
 	case CS_K_MAXERR:
-		ctl_putdblf(sys_var[varid].text, false, 6,
-			    ntp_error_in_seconds(ntx.maxerror) * MS_PER_S);
+		CTL_IF_KERNLOOP(
+			ctl_putdblf,
+			(sys_var[varid].text, false, 6,
+			 ntp_error_in_seconds(ntx.maxerror) * MS_PER_S)
+		);
 		break;
 
 	case CS_K_ESTERR:
-		ctl_putdblf(sys_var[varid].text, false, 6,
-			 ntp_error_in_seconds(ntx.esterror) * MS_PER_S);
+		CTL_IF_KERNLOOP(
+			ctl_putdblf,
+			(sys_var[varid].text, false, 6,
+			 ntp_error_in_seconds(ntx.esterror) * MS_PER_S)
+		);
 		break;
 
 	case CS_K_STFLAGS:
+#ifndef HAVE_KERNEL_PLL
+		ss = "";
+#else
 		ss = k_st_flags((uint32_t)ntx.status);
+#endif
 		ctl_putstr(sys_var[varid].text, ss, strlen(ss));
 		break;
 
 	case CS_K_TIMECONST:
-		ctl_putint(sys_var[varid].text, ntx.constant);
+		CTL_IF_KERNLOOP(
+			ctl_putint,
+			(sys_var[varid].text, ntx.constant)
+		);
 		break;
 
 	case CS_K_PRECISION:
-		ctl_putdblf(sys_var[varid].text, false, 6,
-			    ntp_error_in_seconds(ntx.precision) * MS_PER_S);
+		CTL_IF_KERNLOOP(
+			ctl_putdblf,
+			(sys_var[varid].text, false, 6,
+			 ntp_error_in_seconds(ntx.precision) * MS_PER_S)
+		);
 		break;
 
 	case CS_K_FREQTOL:
-	        ctl_putsfp(sys_var[varid].text, ntx.tolerance);
+		CTL_IF_KERNLOOP(
+			ctl_putsfp,
+			(sys_var[varid].text, ntx.tolerance)
+		);
 		break;
 
 	case CS_K_PPS_FREQ:
--- ./ntpd/ntp_loopfilter.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./ntpd/ntp_loopfilter.c	2019-11-23 17:54:09.000000000 -0800
@@ -23,8 +23,10 @@
 
 #define NTP_MAXFREQ	500e-6
 
+#ifdef HAVE_KERNEL_PLL
 # define FREQTOD(x)	((x) / 65536e6)            /* NTP to double */
 # define DTOFREQ(x)	((int32_t)((x) * 65536e6)) /* double to NTP */
+#endif /* HAVE_KERNEL_PLL */
 
 /*
  * This is an implementation of the clock discipline algorithm described
@@ -125,6 +127,7 @@ static void rstclock (int, double); /* t
 static double direct_freq(double); /* direct set frequency */
 static void set_freq(double);	/* set frequency */
 
+#ifdef HAVE_KERNEL_PLL
 #ifndef PATH_MAX
 # define PATH_MAX MAX_PATH
 #endif
@@ -138,6 +141,7 @@ static unsigned int loop_tai;	/* last TA
 #endif /* STA_NANO */
 static	void	start_kern_loop(void);
 static	void	stop_kern_loop(void);
+#endif /* HAVE_KERNEL_PLL */
 
 /*
  * Clock state machine control flags
@@ -154,7 +158,9 @@ struct clock_control_flags clock_ctl = {
 int	freq_cnt;		/* initial frequency clamp */
 
 static int freq_set;		/* initial set frequency switch */
+#ifdef HAVE_KERNEL_PLL
 static bool	ext_enable;	/* external clock enabled */
+#endif /* HAVE_KERNEL_PLL */
 
 /*
  * Clock state machine variables
@@ -172,6 +178,7 @@ static int sys_hufflen;		/* huff-n'-puff
 static int sys_huffptr;		/* huff-n'-puff filter pointer */
 static double sys_mindly;	/* huff-n'-puff filter min delay */
 
+#if defined(HAVE_KERNEL_PLL)
 /* Emacs cc-mode goes nuts if we split the next line... */
 #define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \
     MOD_STATUS | MOD_TIMECONST)
@@ -181,7 +188,9 @@ static struct sigaction sigsys;	/* curre
 static struct sigaction newsigsys; /* new sigaction status */
 static sigjmp_buf env;		/* environment var. for pll_trap() */
 #endif /* SIGSYS */
+#endif /* HAVE_KERNEL_PLL */
 
+#ifdef HAVE_KERNEL_PLL
 static void
 sync_status(const char *what, int ostatus, int nstatus) {
 	/* only used in non-lockclock case */
@@ -205,6 +214,7 @@ static char *file_name(void) {
 	}
 	return this_file;
 }
+#endif /* HAVE_KERNEL_PLL */
 
 /*
  * init_loopfilter - initialize loop filter data
@@ -219,6 +229,7 @@ init_loopfilter(void) {
 	freq_cnt = (int)clock_minstep;
 }
 
+#ifdef HAVE_KERNEL_PLL
 /*
  * ntp_adjtime_error_handler - process errors from ntp_adjtime
  */
@@ -417,6 +428,7 @@ or, from ntp_adjtime():
 	}
 	return;
 }
+#endif /* HAVE_KERNEL_PLL */
 
 /*
  * local_clock - the NTP logical clock loop filter.
@@ -450,7 +462,9 @@ local_clock(
 
 	int	rval;		/* return code */
 	int	osys_poll;	/* old system poll */
+#ifdef HAVE_KERNEL_PLL
 	int	ntp_adj_ret;	/* returned by ntp_adjtime */
+#endif /* HAVE_KERNEL_PLL */
 	double	mu;		/* interval since last update */
 	double	clock_frequency; /* clock frequency */
 	double	dtemp, etemp;	/* double temps */
@@ -707,6 +721,7 @@ local_clock(
 		}
 	}
 
+#ifdef HAVE_KERNEL_PLL
 	/*
 	 * This code segment works when clock adjustments are made using
 	 * precision time kernel support and the ntp_adjtime() system
@@ -823,6 +838,7 @@ local_clock(
 		}
 #endif /* STA_NANO */
 	}
+#endif /* HAVE_KERNEL_PLL */
 
 	/*
 	 * Clamp the frequency within the tolerance range and calculate
@@ -934,8 +950,10 @@ adj_host_clock(
 	} else if (freq_cnt > 0) {
 		offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(1));
 		freq_cnt--;
+#ifdef HAVE_KERNEL_PLL
 	} else if (clock_ctl.pll_control && clock_ctl.kern_enable) {
 		offset_adj = 0.;
+#endif /* HAVE_KERNEL_PLL */
 	} else {
 		offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(clkstate.sys_poll));
 	}
@@ -946,9 +964,11 @@ adj_host_clock(
 	 * set_freq().  Otherwise it is a component of the adj_systime()
 	 * offset.
 	 */
+#ifdef HAVE_KERNEL_PLL
 	if (clock_ctl.pll_control && clock_ctl.kern_enable)
 		freq_adj = 0.;
 	else
+#endif /* HAVE_KERNEL_PLL */
 		freq_adj = loop_data.drift_comp;
 
 	/* Bound absolute value of total adjustment to NTP_MAXFREQ. */
@@ -1037,6 +1057,7 @@ set_freq(
 
 	loop_data.drift_comp = freq;
 	loop_desc = "ntpd";
+#ifdef HAVE_KERNEL_PLL
 	if (clock_ctl.pll_control) {
 		int ntp_adj_ret;
 		ZERO(ntv);
@@ -1049,10 +1070,12 @@ set_freq(
 		    ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, false, false, __LINE__ - 1);
 		}
 	}
+#endif /* HAVE_KERNEL_PLL */
 	mprintf_event(EVNT_FSET, NULL, "%s %.6f PPM", loop_desc,
 	    loop_data.drift_comp * US_PER_S);
 }
 
+#ifdef HAVE_KERNEL_PLL
 static void
 start_kern_loop(void)
 {
@@ -1113,8 +1136,10 @@ start_kern_loop(void)
 	  	    "kernel time sync enabled");
 	}
 }
+#endif	/* HAVE_KERNEL_PLL */
 
 
+#ifdef HAVE_KERNEL_PLL
 static void
 stop_kern_loop(void)
 {
@@ -1122,6 +1147,7 @@ stop_kern_loop(void)
 		report_event(EVNT_KERN, NULL,
 		    "kernel time sync disabled");
 }
+#endif	/* HAVE_KERNEL_PLL */
 
 
 /*
@@ -1134,11 +1160,15 @@ select_loop(
 {
 	if (clock_ctl.kern_enable == use_kern_loop)
 		return;
+#ifdef HAVE_KERNEL_PLL
 	if (clock_ctl.pll_control && !use_kern_loop)
 		stop_kern_loop();
+#endif /* HAVE_KERNEL_PLL */
 	clock_ctl.kern_enable = use_kern_loop;
+#ifdef HAVE_KERNEL_PLL
 	if (clock_ctl.pll_control && use_kern_loop)
 		start_kern_loop();
+#endif /* HAVE_KERNEL_PLL */
 	/*
 	 * If this loop selection change occurs after initial startup,
 	 * call set_freq() to switch the frequency compensation to or
@@ -1194,10 +1224,12 @@ loop_config(
 	 * variables. Otherwise, continue leaving no harm behind.
 	 */
 	case LOOP_DRIFTINIT:
+#ifdef HAVE_KERNEL_PLL
 		if (loop_data.lockclock || clock_ctl.mode_ntpdate)
 			break;
 
 		start_kern_loop();
+#endif /* HAVE_KERNEL_PLL */
 
 		/*
 		 * Initialize frequency if given; otherwise, begin frequency
@@ -1216,11 +1248,14 @@ loop_config(
 			rstclock(EVNT_FSET, 0);
 		else
 			rstclock(EVNT_NSET, 0);
+#ifdef HAVE_KERNEL_PLL
 		loop_started = true;
+#endif /* HAVE_KERNEL_PLL */
 		break;
 
 	case LOOP_KERN_CLEAR:
 #if 0		/* XXX: needs more review, and how can we get here? */
+# ifdef HAVE_KERNEL_PLL
 		if (!loop_data.lockclock && (clock_ctl.pll_control && clock_ctl.kern_enable)) {
 			memset((char *)&ntv, 0, sizeof(ntv));
 			ntv.modes = MOD_STATUS;
@@ -1230,6 +1265,7 @@ loop_config(
 				pll_status,
 				ntv.status);
 		   }
+# endif /* HAVE_KERNEL_PLL */
 #endif
 		break;
 
@@ -1310,7 +1346,7 @@ loop_config(
 }
 
 
-#if defined(SIGSYS)
+#if defined(HAVE_KERNEL_PLL) && defined(SIGSYS)
 /*
  * _trap - trap processor for undefined syscalls
  *
@@ -1328,4 +1364,4 @@ pll_trap(
 	clock_ctl.pll_control = false;
 	siglongjmp(env, 1);
 }
-#endif /* SIGSYS */
+#endif /* HAVE_KERNEL_PLL && SIGSYS */
--- ./ntpd/ntp_timer.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./ntpd/ntp_timer.c	2019-11-23 17:54:09.000000000 -0800
@@ -13,7 +13,9 @@
 #include <signal.h>
 #include <unistd.h>
 
+#ifdef HAVE_KERNEL_PLL
 #include "ntp_syscall.h"
+#endif /* HAVE_KERNEL_PLL */
 
 #ifdef HAVE_TIMER_CREATE
 /* TC_ERR represents the timer_create() error return value. */
@@ -381,7 +383,11 @@ check_leapsec(
 
 	leap_result_t lsdata;
 	uint32_t       lsprox;
+#ifdef HAVE_KERNEL_PLL
 	leapsec_electric((clock_ctl.pll_control && clock_ctl.kern_enable) ? electric_on : electric_off);
+#else
+	leapsec_electric(electric_off);
+#endif
 #ifdef ENABLE_LEAP_SMEAR
 	leap_smear.enabled = (leap_smear_intv != 0);
 #endif
--- ./ntpd/refclock_local.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./ntpd/refclock_local.c	2019-11-23 17:54:09.000000000 -0800
@@ -158,6 +158,7 @@ local_poll(
 	 * If another process is disciplining the system clock, we set
 	 * the leap bits and quality indicators from the kernel.
 	 */
+#ifdef HAVE_KERNEL_PLL
 	if (loop_data.lockclock) {
 		struct timex ntv;
 		memset(&ntv,  0, sizeof ntv);
@@ -188,6 +189,13 @@ local_poll(
 		pp->disp = DISPERSION;
 		pp->jitter = 0;
 	}
+	pp->disp = 0;
+	pp->jitter = 0;
+#else /* !HAVE_KERNEL_PLL */
+	pp->leap = LEAP_NOWARNING;
+	pp->disp = DISPERSION;
+	pp->jitter = 0;
+#endif /* !HAVE_KERNEL_PLL */
 	pp->lastref = pp->lastrec;
 	refclock_receive(peer);
 }
--- ./ntpfrob/precision.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./ntpfrob/precision.c	2019-11-23 17:54:09.000000000 -0800
@@ -11,6 +11,7 @@
 #include "ntp_types.h"
 #include "ntp_calendar.h"
 #include "ntpfrob.h"
+#include "ntp_machine.h"
 
 #define	DEFAULT_SYS_PRECISION	-99
 
--- ./tests/libntp/statestr.c.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./tests/libntp/statestr.c	2019-11-23 17:54:09.000000000 -0800
@@ -4,7 +4,9 @@
 #include "unity.h"
 #include "unity_fixture.h"
 
+#ifdef HAVE_SYS_TIMEX_H
 #include <sys/timex.h>
+#endif
 
 TEST_GROUP(statestr);
 
@@ -29,7 +31,9 @@ TEST(statestr, ResAccessFlags) {
 
 // k_st_flags()
 TEST(statestr, KSTFlags) {
+#ifdef STA_PPSFREQ
 	TEST_ASSERT_EQUAL_STRING("ppsfreq", k_st_flags(STA_PPSFREQ));
+#endif
 }
 
 // statustoa
--- ./wafhelpers/bin_test.py.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./wafhelpers/bin_test.py	2019-11-23 17:54:09.000000000 -0800
@@ -97,6 +97,12 @@ def cmd_bin_test(ctx, config):
     if ctx.env['PYTHON_CURSES']:
         cmd_map_python.update(cmd_map_python_curses)
 
+    # Kludge to remove ntptime if it didn't get built
+    if not ctx.env.HEADER_SYS_TIMEX_H:
+        for cmd in list(cmd_map.keys()):
+            if 'ntptime' in cmd[0]:
+                del cmd_map[cmd]
+
     for cmd in sorted(cmd_map):
         if not run(cmd, cmd_map[cmd], False):
             fails += 1
--- ./wafhelpers/options.py.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./wafhelpers/options.py	2019-11-23 17:54:09.000000000 -0800
@@ -19,6 +19,8 @@ def options_cmd(ctx, config):
                    help="Droproot earlier (breaks SHM and NetBSD).")
     grp.add_option('--enable-seccomp', action='store_true',
                    default=False, help="Enable seccomp (restricts syscalls).")
+    grp.add_option('--disable-kernel-pll', action='store_true',
+                   default=False, help="Disable kernel PLL.")
     grp.add_option('--disable-mdns-registration', action='store_true',
                    default=False, help="Disable MDNS registration.")
     grp.add_option(
--- ./wscript.orig	2019-11-17 14:18:12.000000000 -0800
+++ ./wscript	2019-11-23 17:54:09.000000000 -0800
@@ -592,7 +592,7 @@ int main(int argc, char **argv) {
     structures = (
         ("struct if_laddrconf", ["sys/types.h", "net/if6.h"], False),
         ("struct if_laddrreq", ["sys/types.h", "net/if6.h"], False),
-        ("struct timex", ["sys/time.h", "sys/timex.h"], True),
+        ("struct timex", ["sys/time.h", "sys/timex.h"], False),
         ("struct ntptimeval", ["sys/time.h", "sys/timex.h"], False),
     )
     for (s, h, r) in structures:
@@ -797,6 +797,21 @@ int main(int argc, char **argv) {
     ctx.define("HAVE_WORKING_FORK", 1,
                comment="Whether a working fork() exists")
 
+    # Does the kernel implement a phase-locked loop for timing?
+    # All modern Unixes (in particular Linux and *BSD) have this.
+    #
+    # The README for the (now deleted) kernel directory says this:
+    # "If the precision-time kernel (KERNEL_PLL define) is
+    # configured, the installation process requires the header
+    # file /usr/include/sys/timex.h for the particular
+    # architecture to be in place."
+    #
+    if ((ctx.get_define("HAVE_SYS_TIMEX_H") and
+            not ctx.options.disable_kernel_pll)):
+        ctx.define("HAVE_KERNEL_PLL", 1,
+                   comment="Whether phase-locked loop for timing "
+                   "exists and is enabled")
+
     # SO_REUSEADDR socket option is needed to open a socket on an
     # interface when the port number is already in use on another
     # interface. Linux needs this, NetBSD does not, status on