diff --git a/configure.ac b/configure.ac
index 8d1a71a104..dcb63448ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -789,7 +789,9 @@ dnl ** check for dtrace (currently only implemented for Mac OS X)
 HaveDtrace=NO
 AC_PATH_PROG(DtraceCmd,dtrace)
 if test -n "$DtraceCmd"; then
-  if test "x$TargetOS_CPP-$TargetVendor_CPP" = "xdarwin-apple" -o "x$TargetOS_CPP-$TargetVendor_CPP" = "xsolaris2-unknown"; then
+  if test "x$TargetOS_CPP-$TargetVendor_CPP" = "xdarwin-apple" \
+		-o "x$TargetOS_CPP-$TargetVendor_CPP" = "xfreebsd-portbld" \
+		-o "x$TargetOS_CPP-$TargetVendor_CPP" = "xsolaris2-unknown"; then
     HaveDtrace=YES
   fi
 fi
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 3d4bea433d..517b6e0ed5 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -2422,6 +2422,8 @@ stg_traceEventzh ( W_ msg )
     ccall traceUserMsg(MyCapability() "ptr", msg "ptr");
 
 #elif defined(DTRACE)
+#if defined(__FreeBSD__) && !defined(DYNAMIC)
+#else
 
     W_ enabled;
 
@@ -2446,6 +2448,7 @@ stg_traceEventzh ( W_ msg )
       ccall dtraceUserMsgWrapper(MyCapability() "ptr", msg "ptr");
     }
 
+#endif
 #endif
     return ();
 }
@@ -2459,6 +2462,8 @@ stg_traceMarkerzh ( W_ msg )
     ccall traceUserMarker(MyCapability() "ptr", msg "ptr");
 
 #elif defined(DTRACE)
+#if defined(__FreeBSD__) && !defined(DYNAMIC)
+#else
 
     W_ enabled;
 
@@ -2471,6 +2476,7 @@ stg_traceMarkerzh ( W_ msg )
         ccall dtraceUserMarkerWrapper(MyCapability() "ptr", msg "ptr");
     }
 
+#endif
 #endif
     return ();
 }
diff --git a/rts/RtsProbes.d b/rts/RtsProbes.d
index 277a494632..6718a39f5e 100644
--- a/rts/RtsProbes.d
+++ b/rts/RtsProbes.d
@@ -12,6 +12,13 @@
 # endif
 #endif
 
+#if defined(__FreeBSD__) /* TODO: this is a very unsatisfying hack */
+#define _MACHINE__TYPES_H_
+#define _SYS__TYPES_H_
+#define _SYS_TYPES_H_
+#define _SYS_STDINT_H_
+#define _INTTYPES_H_
+#endif
 #include "HsFFI.h"
 #include "rts/EventLogFormat.h"
 
diff --git a/rts/Trace.c b/rts/Trace.c
index 71403f8a57..97c32a63f1 100644
--- a/rts/Trace.c
+++ b/rts/Trace.c
@@ -814,6 +814,8 @@ void traceEnd (void)
 // wrapper for the user-msg probe (as we can't expand that in PrimOps.cmm)
 //
 #if !defined(DEBUG) && !defined(TRACING) && defined(DTRACE)
+#if defined(__FreeBSD__) && !defined(DYNAMIC)
+#else
 
 void dtraceUserMsgWrapper(Capability *cap, char *msg)
 {
@@ -825,4 +827,5 @@ void dtraceUserMarkerWrapper(Capability *cap, char *msg)
     dtraceUserMarker(cap->no, msg);
 }
 
+#endif
 #endif /* !defined(DEBUG) && !defined(TRACING) && defined(DTRACE) */
diff --git a/rts/Trace.h b/rts/Trace.h
index a72248ab30..1eeb26baf2 100644
--- a/rts/Trace.h
+++ b/rts/Trace.h
@@ -12,7 +12,10 @@
 #include "Capability.h"
 
 #if defined(DTRACE)
+#if defined(__FreeBSD__) && !defined(DYNAMIC)
+#else
 #include "RtsProbes.h"
+#endif
 #endif /* defined(DTRACE) */
 
 #include "BeginPrivate.h"
@@ -338,8 +341,11 @@ void traceHeapProfSampleCostCentre(StgWord8 profile_id,
 //
 #if !defined(DEBUG) && !defined(TRACING) && defined(DTRACE)
 
+#if defined(__FreeBSD__) && !defined(DYNAMIC)
+#else
 void dtraceUserMsgWrapper(Capability *cap, char *msg);
 void dtraceUserMarkerWrapper(Capability *cap, char *msg);
+#endif
 
 #endif /* !defined(DEBUG) && !defined(TRACING) && defined(DTRACE) */
 
@@ -347,7 +353,60 @@ void dtraceUserMarkerWrapper(Capability *cap, char *msg);
 // Aliases for static dtrace probes if dtrace is available
 // -----------------------------------------------------------------------------
 
-#if defined(DTRACE)
+#if !defined(DTRACE) || (defined(DTRACE) && defined(__FreeBSD__) && !defined(DYNAMIC))
+
+#define dtraceCreateThread(cap, tid)                    /* nothing */
+#define dtraceRunThread(cap, tid)                       /* nothing */
+#define dtraceStopThread(cap, tid, status, info)        /* nothing */
+#define dtraceThreadRunnable(cap, tid)                  /* nothing */
+#define dtraceMigrateThread(cap, tid, new_cap)          /* nothing */
+#define dtraceThreadWakeup(cap, tid, other_cap)         /* nothing */
+#define dtraceGcStart(cap)                              /* nothing */
+#define dtraceGcEnd(cap)                                /* nothing */
+#define dtraceRequestSeqGc(cap)                         /* nothing */
+#define dtraceRequestParGc(cap)                         /* nothing */
+#define dtraceCreateSparkThread(cap, spark_tid)         /* nothing */
+#define dtraceThreadLabel(cap, tso, label)              /* nothing */
+#define dtraceUserMsg(cap, msg)                         /* nothing */
+#define dtraceUserMarker(cap, msg)                      /* nothing */
+#define dtraceGcIdle(cap)                               /* nothing */
+#define dtraceGcWork(cap)                               /* nothing */
+#define dtraceGcDone(cap)                               /* nothing */
+#define dtraceGcGlobalSync(cap)                         /* nothing */
+#define dtraceEventGcStats(heap_capset, gens,           \
+                           copies, slop, fragmentation, \
+                           par_n_threads,               \
+                           par_max_copied,              \
+                           par_tot_copied,              \
+                           par_balanced_copied)         /* nothing */
+#define dtraceHeapInfo(heap_capset, gens,               \
+                       maxHeapSize, allocAreaSize,      \
+                       mblockSize, blockSize)           /* nothing */
+#define dtraceEventHeapAllocated(cap, heap_capset,      \
+                                 allocated)             /* nothing */
+#define dtraceEventHeapSize(heap_capset, size)          /* nothing */
+#define dtraceEventHeapLive(heap_capset, live)          /* nothing */
+#define dtraceCapCreate(cap)                            /* nothing */
+#define dtraceCapDelete(cap)                            /* nothing */
+#define dtraceCapEnable(cap)                            /* nothing */
+#define dtraceCapDisable(cap)                           /* nothing */
+#define dtraceCapsetCreate(capset, capset_type)         /* nothing */
+#define dtraceCapsetDelete(capset)                      /* nothing */
+#define dtraceCapsetAssignCap(capset, capno)            /* nothing */
+#define dtraceCapsetRemoveCap(capset, capno)            /* nothing */
+#define dtraceSparkCounters(cap, a, b, c, d, e, f, g)   /* nothing */
+#define dtraceSparkCreate(cap)                          /* nothing */
+#define dtraceSparkDud(cap)                             /* nothing */
+#define dtraceSparkOverflow(cap)                        /* nothing */
+#define dtraceSparkRun(cap)                             /* nothing */
+#define dtraceSparkSteal(cap, victim_cap)               /* nothing */
+#define dtraceSparkFizzle(cap)                          /* nothing */
+#define dtraceSparkGc(cap)                              /* nothing */
+#define dtraceTaskCreate(taskID, cap, tid)              /* nothing */
+#define dtraceTaskMigrate(taskID, cap, new_cap)         /* nothing */
+#define dtraceTaskDelete(taskID)                        /* nothing */
+
+#else /* defined(DTRACE) */
 
 #define dtraceCreateThread(cap, tid)                    \
     HASKELLEVENT_CREATE_THREAD(cap, tid)
@@ -450,59 +509,6 @@ void dtraceUserMarkerWrapper(Capability *cap, char *msg);
 #define dtraceTaskDelete(taskID)                        \
     HASKELLEVENT_TASK_DELETE(taskID)
 
-#else /* !defined(DTRACE) */
-
-#define dtraceCreateThread(cap, tid)                    /* nothing */
-#define dtraceRunThread(cap, tid)                       /* nothing */
-#define dtraceStopThread(cap, tid, status, info)        /* nothing */
-#define dtraceThreadRunnable(cap, tid)                  /* nothing */
-#define dtraceMigrateThread(cap, tid, new_cap)          /* nothing */
-#define dtraceThreadWakeup(cap, tid, other_cap)         /* nothing */
-#define dtraceGcStart(cap)                              /* nothing */
-#define dtraceGcEnd(cap)                                /* nothing */
-#define dtraceRequestSeqGc(cap)                         /* nothing */
-#define dtraceRequestParGc(cap)                         /* nothing */
-#define dtraceCreateSparkThread(cap, spark_tid)         /* nothing */
-#define dtraceThreadLabel(cap, tso, label)              /* nothing */
-#define dtraceUserMsg(cap, msg)                         /* nothing */
-#define dtraceUserMarker(cap, msg)                      /* nothing */
-#define dtraceGcIdle(cap)                               /* nothing */
-#define dtraceGcWork(cap)                               /* nothing */
-#define dtraceGcDone(cap)                               /* nothing */
-#define dtraceGcGlobalSync(cap)                         /* nothing */
-#define dtraceEventGcStats(heap_capset, gens,           \
-                           copies, slop, fragmentation, \
-                           par_n_threads,               \
-                           par_max_copied,              \
-                           par_tot_copied,              \
-                           par_balanced_copied)         /* nothing */
-#define dtraceHeapInfo(heap_capset, gens,               \
-                       maxHeapSize, allocAreaSize,      \
-                       mblockSize, blockSize)           /* nothing */
-#define dtraceEventHeapAllocated(cap, heap_capset,      \
-                                 allocated)             /* nothing */
-#define dtraceEventHeapSize(heap_capset, size)          /* nothing */
-#define dtraceEventHeapLive(heap_capset, live)          /* nothing */
-#define dtraceCapCreate(cap)                            /* nothing */
-#define dtraceCapDelete(cap)                            /* nothing */
-#define dtraceCapEnable(cap)                            /* nothing */
-#define dtraceCapDisable(cap)                           /* nothing */
-#define dtraceCapsetCreate(capset, capset_type)         /* nothing */
-#define dtraceCapsetDelete(capset)                      /* nothing */
-#define dtraceCapsetAssignCap(capset, capno)            /* nothing */
-#define dtraceCapsetRemoveCap(capset, capno)            /* nothing */
-#define dtraceSparkCounters(cap, a, b, c, d, e, f, g)   /* nothing */
-#define dtraceSparkCreate(cap)                          /* nothing */
-#define dtraceSparkDud(cap)                             /* nothing */
-#define dtraceSparkOverflow(cap)                        /* nothing */
-#define dtraceSparkRun(cap)                             /* nothing */
-#define dtraceSparkSteal(cap, victim_cap)               /* nothing */
-#define dtraceSparkFizzle(cap)                          /* nothing */
-#define dtraceSparkGc(cap)                              /* nothing */
-#define dtraceTaskCreate(taskID, cap, tid)              /* nothing */
-#define dtraceTaskMigrate(taskID, cap, new_cap)         /* nothing */
-#define dtraceTaskDelete(taskID)                        /* nothing */
-
 #endif
 
 // -----------------------------------------------------------------------------
diff --git a/rts/ghc.mk b/rts/ghc.mk
index 924a048552..5c0b08185b 100644
--- a/rts/ghc.mk
+++ b/rts/ghc.mk
@@ -170,8 +170,10 @@ rts_$1_CMM_OBJS = $$(patsubst rts/%.cmm,rts/dist/build/%.$$($1_osuf),$$(rts_CMM_
 
 rts_$1_OBJS = $$(rts_$1_C_OBJS) $$(rts_$1_S_OBJS) $$(rts_$1_CMM_OBJS)
 
-ifneq "$$(findstring linux solaris2, $(TargetOS_CPP))" ""
+ifneq "$$(findstring $(TargetOS_CPP), linux solaris2 freebsd)" ""
 NEED_DTRACE_PROBES_OBJ = YES
+else
+NEED_DTRACE_PROBES_OBJ = NO
 endif
 
 ifeq "$(USE_DTRACE)" "YES"
@@ -179,12 +181,26 @@ ifeq "$(NEED_DTRACE_PROBES_OBJ)" "YES"
 # On Darwin we don't need to generate binary containing probes defined
 # in DTrace script, but DTrace on Solaris expects generation of binary
 # from the DTrace probes definitions
+
+ifneq "$$(findstring $(TargetOS_CPP), freebsd)" ""
+
+ifneq "$$(findstring dyn, $1)" ""
 rts_$1_DTRACE_OBJS = rts/dist/build/RtsProbes.$$($1_osuf)
+rts/dist/build/RtsProbes.$$($1_osuf) : $$(rts_$1_OBJS)
+	$(DTRACE) -G -C $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) -DDTRACE -s rts/RtsProbes.d -o \
+		$$@ $$(rts_$1_OBJS)
+else
+rts_$1_DTRACE_OBJS =
+endif
 
+else
+rts_$1_DTRACE_OBJS = rts/dist/build/RtsProbes.$$($1_osuf)
 rts/dist/build/RtsProbes.$$($1_osuf) : $$(rts_$1_OBJS)
 	$(DTRACE) -G -C $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) -DDTRACE -s rts/RtsProbes.d -o \
 		$$@ $$(rts_$1_OBJS)
 endif
+
+endif
 endif
 
 rts_dist_$1_CC_OPTS += -DRtsWay=\"rts_$1\"
