Color strace output
diff --git a/src/apps/personal/strace.nix b/src/apps/personal/strace.nix
new file mode 100644
index 0000000..e46efbc
--- /dev/null
+++ b/src/apps/personal/strace.nix
@@ -0,0 +1,5 @@
+{ pkgs, ... }: {
+  home.packages = [
+    pkgs.strace
+  ];
+}
diff --git a/src/overlays/strace.nix b/src/overlays/strace.nix
new file mode 100644
index 0000000..d78a146
--- /dev/null
+++ b/src/overlays/strace.nix
@@ -0,0 +1,7 @@
+final: prev:  {
+  strace = prev.strace.overrideAttrs (old: {
+    patches = (old.patches or []) ++ [
+      ./strace/color.patch
+    ];
+  });
+}
diff --git a/src/overlays/strace/color.patch b/src/overlays/strace/color.patch
new file mode 100644
index 0000000..b41f2ba
--- /dev/null
+++ b/src/overlays/strace/color.patch
@@ -0,0 +1,1338 @@
+Patch from https://github.com/xfgusta/strace-with-colors
+diff --git a/src/color.h b/src/color.h
+new file mode 100644
+index 000000000..e84b06672
+--- /dev/null
++++ b/src/color.h
+@@ -0,0 +1,12 @@
++#ifndef COLOR_H
++#define COLOR_H
++
++#define C_RESET   "\033[0m"
++#define C_RED     "\033[31m"
++#define C_GREEN   "\033[32m"
++#define C_YELLOW  "\033[33m"
++#define C_BLUE    "\033[34m"
++#define C_MAGENTA "\033[35m"
++#define C_CYAN    "\033[36m"
++
++#endif
+diff --git a/src/futex.c b/src/futex.c
+index 0cfb24de1..53d3ba613 100644
+--- a/src/futex.c
++++ b/src/futex.c
+@@ -25,6 +25,7 @@
+ #include "xlat/futexops.h"
+ #include "xlat/futexwakeops.h"
+ #include "xlat/futexwakecmps.h"
++#include "color.h"
+ 
+ static int
+ do_futex(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
+@@ -113,18 +114,18 @@ do_futex(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
+ 		tprint_arg_next();
+ 		if ((val3 >> 28) & FUTEX_OP_OPARG_SHIFT) {
+ 			print_xlat(FUTEX_OP_OPARG_SHIFT);
+-			tprints("<<28|");
++			tprints("<<" C_CYAN "28" C_RESET "|");
+ 		}
+ 		comment = printxval(futexwakeops, (val3 >> 28) & 0x7, NULL)
+ 			? NULL : "FUTEX_OP_???";
+-		tprints("<<28");
++		tprints("<<" C_CYAN "28" C_RESET);
+ 		tprints_comment(comment);
+ 		tprints("|");
+ 		PRINT_VAL_X((val3 >> 12) & 0xfff);
+-		tprints("<<12|");
++		tprints("<<" C_CYAN "12" C_RESET "|");
+ 		comment = printxval(futexwakecmps, (val3 >> 24) & 0xf, NULL)
+ 			? NULL : "FUTEX_OP_CMP_???";
+-		tprints("<<24");
++		tprints("<<" C_CYAN "24" C_RESET);
+ 		tprints_comment(comment);
+ 		tprints("|");
+ 		PRINT_VAL_X(val3 & 0xfff);
+diff --git a/src/ioctl.c b/src/ioctl.c
+index 60dffa7aa..683f49973 100644
+--- a/src/ioctl.c
++++ b/src/ioctl.c
+@@ -12,6 +12,7 @@
+ #include "defs.h"
+ #include <linux/ioctl.h>
+ #include "xlat/ioctl_dirs.h"
++#include "color.h"
+ 
+ #if defined(SPARC) || defined(SPARC64)
+ /*
+@@ -448,10 +449,10 @@ SYS_FUNC(ioctl)
+ 				if (iop) {
+ 					if (ret)
+ 						tprint_alternative_value();
+-					tprints(iop->symbol);
++					tprintf(C_YELLOW "%s" C_RESET, iop->symbol);
+ 					while ((iop = ioctl_next_match(iop))) {
+ 						tprint_alternative_value();
+-						tprints(iop->symbol);
++						tprintf(C_YELLOW "%s" C_RESET, iop->symbol);
+ 					}
+ 				} else if (!ret) {
+ 					ioctl_print_code(tcp->u_arg[1]);
+diff --git a/src/ipc.c b/src/ipc.c
+index 81b5ce6e1..41be7d560 100644
+--- a/src/ipc.c
++++ b/src/ipc.c
+@@ -8,6 +8,7 @@
+ 
+ #include "defs.h"
+ #include "xlat/ipccalls.h"
++#include "color.h"
+ 
+ SYS_FUNC(ipc)
+ {
+@@ -17,7 +18,7 @@ SYS_FUNC(ipc)
+ 
+ 	if (version) {
+ 		PRINT_VAL_U(version);
+-		tprints("<<16|");
++		tprints("<<" C_CYAN "16" C_RESET "|");
+ 	}
+ 
+ 	printxval_u(ipccalls, call, NULL);
+diff --git a/src/ipc_shm.c b/src/ipc_shm.c
+index 0e5b01028..a5c1fa7a3 100644
+--- a/src/ipc_shm.c
++++ b/src/ipc_shm.c
+@@ -26,6 +26,7 @@
+ 
+ #include "xlat/shm_resource_flags.h"
+ #include "xlat/shm_flags.h"
++#include "color.h"
+ 
+ SYS_FUNC(shmget)
+ {
+@@ -47,7 +48,7 @@ SYS_FUNC(shmget)
+ 		printflags(shm_resource_flags, flags, NULL);
+ 
+ 	if (hugetlb_value) {
+-		tprintf("%s%u<<",
++		tprintf("%s" C_CYAN "%u" C_RESET "<<",
+ 			flags ? "|" : "",
+ 			hugetlb_value >> SHM_HUGE_SHIFT);
+ 		print_xlat_u(SHM_HUGE_SHIFT);
+diff --git a/src/mem.c b/src/mem.c
+index d34a92118..d4158fdb9 100644
+--- a/src/mem.c
++++ b/src/mem.c
+@@ -14,6 +14,7 @@
+ #include "defs.h"
+ #include <linux/mman.h>
+ #include <sys/mman.h>
++#include "color.h"
+ 
+ unsigned long
+ get_pagesize(void)
+@@ -80,7 +81,7 @@ print_mmap_flags(kernel_ulong_t flags)
+ 	}
+ 
+ 	if (hugetlb_value)
+-		tprintf("|%u<<MAP_HUGE_SHIFT",
++		tprintf("|" C_CYAN "%u" C_RESET "<<" C_YELLOW "MAP_HUGE_SHIFT" C_RESET,
+ 			hugetlb_value >> MAP_HUGE_SHIFT);
+ 
+ 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
+diff --git a/src/memfd_create.c b/src/memfd_create.c
+index 16a26533b..2ffbe0680 100644
+--- a/src/memfd_create.c
++++ b/src/memfd_create.c
+@@ -9,6 +9,7 @@
+ #include "defs.h"
+ #include <linux/memfd.h>
+ #include "xlat/memfd_create_flags.h"
++#include "color.h"
+ 
+ #ifndef MFD_NAME_MAX_LEN
+ # define MFD_NAME_MAX_LEN (255 - (sizeof("memfd:") - 1))
+@@ -41,7 +42,7 @@ SYS_FUNC(memfd_create)
+ 			      memfd_create_flags, NULL);
+ 
+ 	if (hugetlb_value)
+-		tprintf("%s%u<<MFD_HUGE_SHIFT",
++		tprintf("%s" C_CYAN "%u" C_RESET "<<" C_YELLOW "MFD_HUGE_SHIFT" C_RESET,
+ 			flags ? "|" : "",
+ 			hugetlb_value >> MFD_HUGE_SHIFT);
+ 
+diff --git a/src/mmsghdr.c b/src/mmsghdr.c
+index 0e313678b..dfb2e8881 100644
+--- a/src/mmsghdr.c
++++ b/src/mmsghdr.c
+@@ -13,6 +13,7 @@
+ #include "msghdr.h"
+ #include "xstring.h"
+ #include <limits.h>
++#include "color.h"
+ 
+ static bool
+ fetch_struct_mmsghdr_for_print(struct tcb *const tcp,
+@@ -138,7 +139,7 @@ dumpiov_in_mmsghdr(struct tcb *const tcp, kernel_ulong_t addr)
+ 		fetched = fetch_struct_mmsghdr(tcp, addr, &mmsg);
+ 		if (!fetched)
+ 			break;
+-		tprintf(" = %" PRI_klu " buffers in vector %u\n",
++		tprintf(" =" C_CYAN "%" PRI_klu C_RESET " buffers in vector " C_CYAN "%u" C_RESET "\n",
+ 			(kernel_ulong_t) mmsg.msg_hdr.msg_iovlen, i);
+ 		dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
+ 			     ptr_to_kulong(mmsg.msg_hdr.msg_iov),
+diff --git a/src/netlink.c b/src/netlink.c
+index d8e4efece..459e7d17e 100644
+--- a/src/netlink.c
++++ b/src/netlink.c
+@@ -52,6 +52,7 @@
+ #include "xlat/nl_sock_diag_types.h"
+ #include "xlat/nl_xfrm_types.h"
+ #include "xlat/nlmsgerr_attrs.h"
++#include "color.h"
+ 
+ /*
+  * Fetch a struct nlmsghdr from the given address.
+@@ -180,7 +181,7 @@ decode_nlmsg_type_netfilter(struct tcb *tcp, const struct xlat *const xlat,
+ 
+ 	printxval(xlat, subsys_id, dflt);
+ 
+-	tprints("<<8|");
++	tprints("<<" C_CYAN "8" C_RESET "|");
+ 	if (subsys_id < ARRAY_SIZE(nf_nlmsg_types))
+ 		printxval(nf_nlmsg_types[subsys_id].xlat,
+ 			  msg_type, nf_nlmsg_types[subsys_id].dflt);
+diff --git a/src/netlink_netlink_diag.c b/src/netlink_netlink_diag.c
+index 35fbb645d..8e22e8f54 100644
+--- a/src/netlink_netlink_diag.c
++++ b/src/netlink_netlink_diag.c
+@@ -19,6 +19,7 @@
+ #include "xlat/netlink_diag_show.h"
+ #include "xlat/netlink_socket_flags.h"
+ #include "xlat/netlink_states.h"
++#include "color.h"
+ 
+ DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req)
+ {
+@@ -61,10 +62,10 @@ print_group(struct tcb *const tcp,
+ 	    void *const opaque_data)
+ {
+ 	if (elem_size < sizeof(kernel_ulong_t))
+-		tprintf("%#0*x", (int) elem_size * 2 + 2,
++		tprintf(C_CYAN "%#0*x" C_RESET, (int) elem_size * 2 + 2,
+ 			*(unsigned int *) elem_buf);
+ 	else
+-		tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
++		tprintf(C_CYAN "%#0*" PRI_klx C_RESET, (int) elem_size * 2 + 2,
+ 			*(kernel_ulong_t *) elem_buf);
+ 
+ 	return true;
+diff --git a/src/numa.c b/src/numa.c
+index 74156203f..167c55586 100644
+--- a/src/numa.c
++++ b/src/numa.c
+@@ -8,15 +8,16 @@
+  */
+ 
+ #include "defs.h"
++#include "color.h"
+ 
+ static bool
+ print_node(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
+ {
+ 	if (elem_size < sizeof(kernel_ulong_t)) {
+-		tprintf("%#0*x", (int) elem_size * 2 + 2,
++		tprintf(C_CYAN "%#0*x" C_RESET, (int) elem_size * 2 + 2,
+ 			*(unsigned int *) elem_buf);
+ 	} else {
+-		tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
++		tprintf(C_CYAN "%#0*" PRI_klx C_RESET, (int) elem_size * 2 + 2,
+ 			*(kernel_ulong_t *) elem_buf);
+ 	}
+ 
+@@ -95,7 +96,7 @@ print_mode(struct tcb *const tcp, const kernel_ulong_t mode_arg)
+ 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
+ 		tprint_comment_begin();
+ 
+-	tprints(mode_str);
++	tprintf(C_YELLOW "%s" C_RESET, mode_str);
+ 	tprints("|");
+ 	printflags_ex(flags, NULL, XLAT_STYLE_ABBREV, mpol_mode_flags, NULL);
+ 
+diff --git a/src/perf.c b/src/perf.c
+index 805bfb649..0855d426f 100644
+--- a/src/perf.c
++++ b/src/perf.c
+@@ -25,6 +25,7 @@
+ #include "xlat/perf_hw_id.h"
+ #include "xlat/perf_sw_ids.h"
+ #include "xlat/perf_type_id.h"
++#include "color.h"
+ 
+ struct pea_desc {
+ 	struct perf_event_attr *attr;
+@@ -159,7 +160,7 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
+ 		tprints_field_name("config");
+ 		if (attr->config >> 32) {
+ 			PRINT_VAL_X(attr->config >> 32);
+-			tprints("<<32|");
++			tprints("<<" C_CYAN "32" C_RESET "|");
+ 		}
+ 		printxval(perf_hw_id, attr->config & PERF_HW_EVENT_MASK,
+ 			   "PERF_COUNT_HW_???");
+@@ -190,19 +191,19 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
+ 		tprints_field_name("config");
+ 		if (attr->config >> 32){
+ 			PRINT_VAL_X(attr->config >> 32);
+-			tprints("<<32|");
++			tprints("<<" C_CYAN "32" C_RESET "|");
+ 		}
+ 		if ((attr->config & PERF_HW_EVENT_MASK) >> 24) {
+ 			PRINT_VAL_X((attr->config & PERF_HW_EVENT_MASK) >> 24);
+-			tprints("<<24|");
++			tprints("<<" C_CYAN "24" C_RESET "|");
+ 		}
+ 		printxval(perf_hw_cache_op_result_id,
+ 			  (attr->config >> 16) & 0xFF,
+ 			  "PERF_COUNT_HW_CACHE_RESULT_???");
+-		tprints("<<16|");
++		tprints("<<" C_CYAN "16" C_RESET "|");
+ 		printxval(perf_hw_cache_op_id, (attr->config >> 8) & 0xFF,
+ 			   "PERF_COUNT_HW_CACHE_OP_???");
+-		tprints("<<8|");
++		tprints("<<" C_CYAN "8" C_RESET "|");
+ 		printxval(perf_hw_cache_id, attr->config & 0xFF,
+ 			  "PERF_COUNT_HW_CACHE_???");
+ 		break;
+diff --git a/src/personality.c b/src/personality.c
+index 8e16930ac..0332302a2 100644
+--- a/src/personality.c
++++ b/src/personality.c
+@@ -18,7 +18,7 @@ SYS_FUNC(personality)
+ 	if (entering(tcp)) {
+ 		pers = tcp->u_arg[0];
+ 		if (0xffffffff == pers) {
+-			tprints("0xffffffff");
++			tprints(C_CYAN "0xffffffff" C_RESET);
+ 		} else {
+ 			printxval(personality_types, pers & PER_MASK, "PER_???");
+ 			pers &= ~PER_MASK;
+diff --git a/src/print_fields.h b/src/print_fields.h
+index 3ceb0b6d7..6ee6b7f59 100644
+--- a/src/print_fields.h
++++ b/src/print_fields.h
+@@ -10,6 +10,7 @@
+ # define STRACE_PRINT_FIELDS_H
+ 
+ # include "static_assert.h"
++#include "color.h"
+ 
+ # ifdef IN_STRACE
+ 
+@@ -94,13 +95,13 @@ tprint_bitset_end(void)
+ static inline void
+ tprint_comment_begin(void)
+ {
+-	tprints(" /* ");
++	tprints(C_MAGENTA " /* ");
+ }
+ 
+ static inline void
+ tprint_comment_end(void)
+ {
+-	tprints(" */");
++	tprints(" */" C_RESET);
+ }
+ 
+ static inline void
+@@ -230,13 +231,13 @@ tprint_bitset_end(void)
+ static inline void
+ tprint_comment_begin(void)
+ {
+-	fputs(" /* ", stdout);
++	fputs(C_MAGENTA " /* ", stdout);
+ }
+ 
+ static inline void
+ tprint_comment_end(void)
+ {
+-	fputs(" */", stdout);
++	fputs(" */" C_RESET, stdout);
+ }
+ 
+ static inline void
+@@ -286,35 +287,35 @@ tprint_unavailable(void)
+ static inline void
+ tprints_field_name(const char *name)
+ {
+-	STRACE_PRINTF("%s=", name);
++	STRACE_PRINTF(C_BLUE "%s" C_RESET "=", name);
+ }
+ 
+ static inline void
+ tprints_arg_name(const char *name)
+ {
+-	STRACE_PRINTF("%s=", name);
++	STRACE_PRINTF(C_BLUE "%s" C_RESET "=", name);
+ }
+ 
+ static inline void
+ tprints_arg_begin(const char *name)
+ {
+-	STRACE_PRINTF("%s(", name);
++	STRACE_PRINTF(C_RED "%s" C_RESET "(", name);
+ }
+ 
+ # define PRINT_VAL_D(val_)	\
+-	STRACE_PRINTF("%lld", sign_extend_unsigned_to_ll(val_))
++	STRACE_PRINTF(C_CYAN "%lld" C_RESET, sign_extend_unsigned_to_ll(val_))
+ 
+ # define PRINT_VAL_U(val_)	\
+-	STRACE_PRINTF("%llu", zero_extend_signed_to_ull(val_))
++	STRACE_PRINTF(C_CYAN "%llu" C_RESET, zero_extend_signed_to_ull(val_))
+ 
+ # define PRINT_VAL_X(val_)	\
+-	STRACE_PRINTF("%#llx", zero_extend_signed_to_ull(val_))
++	STRACE_PRINTF(C_CYAN "%#llx" C_RESET, zero_extend_signed_to_ull(val_))
+ 
+ # define PRINT_VAL_03O(val_)	\
+-	STRACE_PRINTF("%#03llo", zero_extend_signed_to_ull(val_))
++	STRACE_PRINTF(C_CYAN "%#03llo" C_RESET, zero_extend_signed_to_ull(val_))
+ 
+ # define PRINT_VAL_0X(val_)						\
+-	STRACE_PRINTF("%#0*llx", (int) sizeof(val_) * 2,		\
++	STRACE_PRINTF(C_CYAN "%#0*llx" C_RESET, (int) sizeof(val_) * 2,		\
+ 		      zero_extend_signed_to_ull(val_))
+ 
+ # define PRINT_VAL_ID(val_)						\
+diff --git a/src/print_instruction_pointer.c b/src/print_instruction_pointer.c
+index c0d07a6fb..f5d324e17 100644
+--- a/src/print_instruction_pointer.c
++++ b/src/print_instruction_pointer.c
+@@ -14,8 +14,8 @@ print_instruction_pointer(struct tcb *tcp)
+ 
+ 	if (get_instruction_pointer(tcp, &ip)) {
+ 		tprintf(current_wordsize == 4
+-			? "[%08" PRI_klx "] "
+-			: "[%016" PRI_klx "] ", ip);
++			? "[" C_CYAN "%08" PRI_klx C_RESET "] "
++			: "[" C_CYAN "%016" PRI_klx C_RESET "] ", ip);
+ 	} else {
+ 		tprints(current_wordsize == 4
+ 			? "[????????] "
+diff --git a/src/print_syscall_number.c b/src/print_syscall_number.c
+index f9e146059..24e41cb51 100644
+--- a/src/print_syscall_number.c
++++ b/src/print_syscall_number.c
+@@ -6,12 +6,13 @@
+  */
+ 
+ #include "defs.h"
++#include "color.h"
+ 
+ void
+ print_syscall_number(struct tcb *tcp)
+ {
+ 	if (tcp->true_scno != (kernel_ulong_t) -1) {
+-		tprintf("[%4" PRI_klu "] ", tcp->true_scno);
++		tprintf("[" C_CYAN "%4" PRI_klu C_RESET "] ", tcp->true_scno);
+ 	} else {
+ 		tprints("[????] ");
+ 	}
+diff --git a/src/printmode.c b/src/printmode.c
+index b509411a5..111e6ebc8 100644
+--- a/src/printmode.c
++++ b/src/printmode.c
+@@ -16,6 +16,7 @@
+ #include <sys/stat.h>
+ 
+ #include "xlat/modetypes.h"
++#include "color.h"
+ 
+ void
+ print_symbolic_mode_t(const unsigned int mode)
+@@ -31,13 +32,21 @@ print_symbolic_mode_t(const unsigned int mode)
+ 	if (!ifmt || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+ 		return;
+ 
+-	(xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV
+-		? tprintf : tprintf_comment)("%s%s%s%s%s%#03o",
++	if(xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV) {
++		tprintf(C_YELLOW "%s" C_RESET "%s%s%s%s" C_CYAN "%#03o" C_RESET,
++			ifmt, ifmt[0] ? "|" : "",
++			(mode & S_ISUID) ? C_YELLOW "S_ISUID" C_RESET "|" : "",
++			(mode & S_ISGID) ? C_YELLOW "S_ISGID" C_RESET "|" : "",
++			(mode & S_ISVTX) ? C_YELLOW "S_ISVTX" C_RESET "|" : "",
++			mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX));
++	} else {
++		tprintf_comment("%s%s%s%s%s%#03o",
+ 			ifmt, ifmt[0] ? "|" : "",
+ 			(mode & S_ISUID) ? "S_ISUID|" : "",
+ 			(mode & S_ISGID) ? "S_ISGID|" : "",
+ 			(mode & S_ISVTX) ? "S_ISVTX|" : "",
+ 			mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX));
++	}
+ }
+ 
+ void
+diff --git a/src/ptrace.c b/src/ptrace.c
+index 2115ccbfd..bd2872425 100644
+--- a/src/ptrace.c
++++ b/src/ptrace.c
+@@ -31,6 +31,7 @@
+ #include "xlat/compat_ptrace_cmds.h"
+ #include "xlat/ptrace_setoptions_flags.h"
+ #include "xlat/ptrace_peeksiginfo_flags.h"
++#include "color.h"
+ 
+ #define uoff(member)	offsetof(struct user, member)
+ #define XLAT_UOFF(member)	{ uoff(member), "offsetof(struct user, " #member ")" }
+@@ -76,7 +77,7 @@ print_user_offset_addr(const kernel_ulong_t addr)
+ 	if (base_addr == addr)
+ 		tprints(str);
+ 	else
+-		tprintf("%s + %" PRI_klu,
++		tprintf("%s + " C_CYAN "%" PRI_klu C_RESET,
+ 			str, addr - (kernel_ulong_t) base_addr);
+ 
+ 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
+diff --git a/src/s390.c b/src/s390.c
+index 5f024142b..ea3c30405 100644
+--- a/src/s390.c
++++ b/src/s390.c
+@@ -16,6 +16,7 @@
+ # include "xlat/s390_guarded_storage_commands.h"
+ # include "xlat/s390_runtime_instr_commands.h"
+ # include "xlat/s390_sthyi_function_codes.h"
++#include "color.h"
+ 
+ /*
+  * Since, for some reason, kernel doesn't expose all these nice constants and
+@@ -510,7 +511,7 @@ print_sthyi_machine(struct tcb *tcp, struct sthyi_machine *hdr, uint16_t size,
+ 
+ 	CHECK_SIZE_EX(hdr, last_decoded, size, "machine structure");
+ 
+-	tprints("/* machine */ ");
++	tprints(C_MAGENTA "/* machine */ " C_RESET);
+ 	tprint_struct_begin();
+ 	if (!abbrev(tcp)) {
+ 		if (hdr->infmflg1) { /* Reserved */
+@@ -621,7 +622,7 @@ print_sthyi_partition(struct tcb *tcp, struct sthyi_partition *hdr,
+ 
+ 	*mt = !!(hdr->infpflg1 & 0x80);
+ 
+-	tprints("/* partition */ ");
++	tprints(C_MAGENTA "/* partition */ " C_RESET);
+ 	tprint_struct_begin();
+ 	PRINT_FIELD_0X(*hdr, infpflg1);
+ 	if (!abbrev(tcp) && hdr->infpflg1)
+@@ -792,7 +793,7 @@ print_funcs(const uint8_t funcs[8])
+ 			tprint_comment_begin();
+ 			cont = true;
+ 		}
+-		tprintf("%u: %s", i, func_descs[i]);
++		tprintf(C_CYAN "%u" C_RESET ": %s", i, func_descs[i]);
+ 	}
+ 
+ 	if (cont)
+@@ -807,7 +808,7 @@ print_sthyi_hypervisor(struct tcb *tcp, struct sthyi_hypervisor *hdr,
+ 
+ 	CHECK_SIZE_EX(hdr, last_decoded, size, "hypervisor %d structure", num);
+ 
+-	tprintf("/* hypervisor %d */ ", num);
++	tprintf(C_MAGENTA "/* hypervisor %d */ " C_RESET, num);
+ 	tprint_struct_begin();
+ 	PRINT_FIELD_0X(*hdr, infyflg1);
+ 	if (!abbrev(tcp) && hdr->infyflg1)
+@@ -923,7 +924,7 @@ print_sthyi_guest(struct tcb *tcp, struct sthyi_guest *hdr, uint16_t size,
+ {
+ 	CHECK_SIZE(hdr, size, "guest %d structure", num);
+ 
+-	tprintf("/* guest %d */ ", num);
++	tprintf(C_MAGENTA "/* guest %d */ " C_RESET, num);
+ 	tprint_struct_begin();
+ 	PRINT_FIELD_0X(*hdr, infgflg1);
+ 	if (!abbrev(tcp) && hdr->infgflg1)
+@@ -1133,7 +1134,7 @@ print_sthyi_buf(struct tcb *tcp, kernel_ulong_t ptr)
+ 	tprint_struct_begin();
+ 
+ 	/* Header */
+-	tprints("/* header */ ");
++	tprints(C_MAGENTA "/* header */ " C_RESET);
+ 	tprint_struct_begin();
+ 	PRINT_FIELD_0X(*hdr, infhflg1);
+ 
+@@ -1284,7 +1285,7 @@ SYS_FUNC(s390_sthyi)
+ 
+ 		tprints(", ");
+ 		printnum_int64(tcp, return_code_ptr, "%" PRIu64);
+-		tprintf(", %#" PRI_klx, flags);
++		tprintf(", " C_CYAN "%#" PRI_klx C_RESET, flags);
+ 	}
+ 
+ 	return 0;
+@@ -1348,7 +1349,7 @@ guard_storage_print_gsepl(struct tcb *tcp, uint64_t addr)
+ 	/* Since it is 64-bit even on 31-bit s390... */
+ 	if (sizeof(addr) > current_klongsize &&
+ 	    addr >= (1ULL << (current_klongsize * 8))) {
+-		tprintf("%#" PRIx64, addr);
++		tprintf(C_CYAN "%#" PRIx64 C_RESET, addr);
+ 
+ 		return;
+ 	}
+@@ -1515,9 +1516,9 @@ SYS_FUNC(s390_pci_mmio_write)
+ 	kernel_ulong_t user_buf  = tcp->u_arg[1];
+ 	kernel_ulong_t length    = tcp->u_arg[2];
+ 
+-	tprintf("%#" PRI_klx ", ", mmio_addr);
++	tprintf(C_CYAN "%#" PRI_klx C_RESET ", ", mmio_addr);
+ 	printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
+-	tprintf(", %" PRI_klu, length);
++	tprintf(", " C_CYAN "%" PRI_klu C_RESET, length);
+ 
+ 	return RVAL_DECODED;
+ }
+@@ -1529,14 +1530,14 @@ SYS_FUNC(s390_pci_mmio_read)
+ 	kernel_ulong_t length    = tcp->u_arg[2];
+ 
+ 	if (entering(tcp)) {
+-		tprintf("%#" PRI_klx ", ", mmio_addr);
++		tprintf(C_CYAN "%#" PRI_klx C_RESET ", ", mmio_addr);
+ 	} else {
+ 		if (!syserror(tcp))
+ 			printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
+ 		else
+ 			printaddr(user_buf);
+ 
+-		tprintf(", %" PRI_klu, length);
++		tprintf(", " C_CYAN "%" PRI_klu C_RESET, length);
+ 	}
+ 
+ 	return 0;
+diff --git a/src/signal.c b/src/signal.c
+index fc13a6613..2f5a6e125 100644
+--- a/src/signal.c
++++ b/src/signal.c
+@@ -15,6 +15,7 @@
+ #include "defs.h"
+ #include "nsig.h"
+ #include "xstring.h"
++#include "color.h"
+ 
+ /* The libc headers do not define this constant since it should only be
+    used by the implementation.  So we define it here.  */
+@@ -241,8 +242,12 @@ printsignal(int nr)
+ 		PRINT_VAL_D(nr);
+ 	if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+ 		return;
+-	(xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
+-		? tprints_comment : tprints)(str);
++
++	if(xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE) {
++		tprints_comment(str);
++	} else {
++		tprintf(C_YELLOW "%s" C_RESET, str);
++	}
+ }
+ 
+ static void
+@@ -810,8 +815,10 @@ SYS_FUNC(rt_sigtimedwait_time64)
+ 
+ SYS_FUNC(restart_syscall)
+ {
+-	tprintf("<... resuming interrupted %s ...>",
+-		tcp->s_prev_ent ? tcp->s_prev_ent->sys_name : "system call");
+-
++	if(tcp->s_prev_ent) {
++		tprintf("<... resuming interrupted " C_RED "%s" C_RESET " ...>", tcp->s_prev_ent->sys_name);
++	} else {
++		tprints("<... resuming interrupted system call ...>");
++	}
+ 	return RVAL_DECODED;
+ }
+diff --git a/src/sockaddr.c b/src/sockaddr.c
+index a6e698d4b..910b887f1 100644
+--- a/src/sockaddr.c
++++ b/src/sockaddr.c
+@@ -39,6 +39,7 @@
+ #include "xlat/bluetooth_l2_cid.h"
+ #include "xlat/bluetooth_l2_psm.h"
+ #include "xlat/hci_channels.h"
++#include "color.h"
+ 
+ #include "xlat/rxrpc_services.h"
+ 
+@@ -178,7 +179,7 @@ print_inet_addr(const int af,
+ 			if (var_name &&
+ 			    (xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV)) {
+ 				tprint_arg_next();
+-				tprintf("&%s", var_name);
++				tprintf(C_BLUE "&%s" C_RESET, var_name);
+ 			}
+ 			tprint_arg_end();
+ 
+@@ -571,7 +572,7 @@ print_sockaddr_data_ll(struct tcb *tcp, const void *const buf,
+ 				tprint_more_data_follows();
+ 				break;
+ 			}
+-			tprintf("%#02x", sa_ll->sll_addr[i]);
++			tprintf(C_CYAN "%#02x" C_RESET, sa_ll->sll_addr[i]);
+ 		}
+ 		tprint_array_end();
+ 	}
+@@ -625,7 +626,7 @@ print_bluetooth_l2_psm(uint16_t psm)
+ 		tprints(" + ");
+ 		PRINT_VAL_U(psm_he - L2CAP_PSM_DYN_START);
+ 	} else {
+-		tprints("L2CAP_PSM_???");
++		tprints(C_YELLOW "L2CAP_PSM_???" C_RESET);
+ 	}
+ 
+ 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE || !psm_str)
+@@ -660,7 +661,7 @@ print_bluetooth_l2_cid(uint16_t cid)
+ 		tprints(" + ");
+ 		PRINT_VAL_U(cid_he - L2CAP_CID_DYN_START);
+ 	} else {
+-		tprints("L2CAP_CID_???");
++		tprints(C_YELLOW "L2CAP_CID_???" C_RESET);
+ 	}
+ 
+ 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE || !cid_str)
+diff --git a/src/strace.c b/src/strace.c
+index ec338fe97..1d73419eb 100644
+--- a/src/strace.c
++++ b/src/strace.c
+@@ -43,6 +43,8 @@
+ #include "wait.h"
+ #include "secontext.h"
+ 
++#include "color.h"
++
+ /* In some libc, these aren't declared. Do it ourself: */
+ extern char **environ;
+ extern int optind;
+@@ -93,6 +95,12 @@ static int rflag_scale = 1000;
+ static int rflag_width = 6;
+ static bool print_pid_pfx;
+ 
++/* -1 = auto
++ *  0 = never
++ *  1 = always
++ */
++int no_color_flag = -1;
++
+ static unsigned int version_verbosity;
+ 
+ /* -I n */
+@@ -343,6 +351,8 @@ Filtering:\n\
+                  print only syscalls that returned with an error code\n\
+ \n\
+ Output format:\n\
++  --color[=WHEN]\n\
++                 colorize the output; WHEN can be 'always', 'auto' (default), or 'never'\n\
+   -a COLUMN, --columns=COLUMN\n\
+                  alignment COLUMN for printing syscall results (default %d)\n\
+   -e abbrev=SET, --abbrev=SET\n\
+@@ -702,7 +712,23 @@ static void
+ tvprintf(const char *const fmt, va_list args)
+ {
+ 	if (current_tcp) {
+-		int n = vfprintf(current_tcp->outf, fmt, args);
++		int n;
++		if(no_color_flag) {
++			char new_fmt[strlen(fmt) + 1];
++			int i = 0;
++			for(const char *c = fmt; *c; c++) {
++				if(*c == '\033') {
++					for(c++; *c && *c != 'm'; c++);
++					continue;
++				}
++
++				new_fmt[i++] = *c;
++			}
++			new_fmt[i] = '\0';
++			n = vfprintf(current_tcp->outf, new_fmt, args);
++		} else
++			n = vfprintf(current_tcp->outf, fmt, args);
++
+ 		if (n < 0) {
+ 			/* very unlikely due to vfprintf buffering */
+ 			outf_perror(current_tcp);
+@@ -728,7 +754,22 @@ void
+ tprints(const char *str)
+ {
+ 	if (current_tcp) {
+-		int n = fputs_unlocked(str, current_tcp->outf);
++		int n;
++		if(no_color_flag) {
++			char new_str[strlen(str) + 1];
++			int i = 0;
++			for(const char *c = str; *c; c++) {
++				if(*c == '\033') {
++					for(c++; *c && *c != 'm'; c++);
++					continue;
++				}
++				new_str[i++] = *c;
++			}
++			new_str[i] = '\0';
++			n = fputs_unlocked(new_str, current_tcp->outf);
++		} else
++			n = fputs_unlocked(str, current_tcp->outf);
++
+ 		if (n >= 0) {
+ 			current_tcp->curcol += strlen(str);
+ 			return;
+@@ -742,7 +783,7 @@ void
+ tprints_comment(const char *const str)
+ {
+ 	if (str && *str)
+-		tprintf(" /* %s */", str);
++		tprintf(C_MAGENTA " /* %s */" C_RESET, str);
+ }
+ 
+ void
+@@ -863,7 +904,7 @@ printleader(struct tcb *tcp)
+ 		else
+ 			xsprintf(str, "%lld", (long long) local);
+ 		if (tflag_width)
+-			tprintf("%s.%0*ld ", str, tflag_width,
++			tprintf("%s." C_CYAN "%0*ld" C_RESET " ", str, tflag_width,
+ 				(long) ts.tv_nsec / tflag_scale);
+ 		else
+ 			tprintf("%s ", str);
+@@ -881,9 +922,9 @@ printleader(struct tcb *tcp)
+ 		ts_sub(&dts, &ts, &ots);
+ 		ots = ts;
+ 
+-		tprintf("%s%6ld", tflag_format ? "(+" : "", (long) dts.tv_sec);
++		tprintf("%s" C_CYAN "%6ld" C_RESET, tflag_format ? "(+" : "", (long) dts.tv_sec);
+ 		if (rflag_width) {
+-			tprintf(".%0*ld",
++			tprintf("." C_CYAN "%0*ld" C_RESET,
+ 				rflag_width, (long) dts.tv_nsec / rflag_scale);
+ 		}
+ 		tprints(tflag_format ? ") " : " ");
+@@ -2222,6 +2263,7 @@ init(int argc, char *argv[])
+ 
+ 	enum {
+ 		GETOPT_SECCOMP = 0x100,
++		GETOPT_COLOR,
+ 		GETOPT_DAEMONIZE,
+ 		GETOPT_HEX_STR,
+ 		GETOPT_FOLLOWFORKS,
+@@ -2247,6 +2289,7 @@ init(int argc, char *argv[])
+ 		GETOPT_QUAL_SECONTEXT,
+ 	};
+ 	static const struct option longopts[] = {
++		{ "color",		optional_argument, 0, GETOPT_COLOR },
+ 		{ "columns",		required_argument, 0, 'a' },
+ 		{ "output-append-mode",	no_argument,	   0, 'A' },
+ 		{ "detach-on",		required_argument, 0, 'b' },
+@@ -2354,6 +2397,23 @@ init(int argc, char *argv[])
+ 		case 'D':
+ 			daemonized_tracer++;
+ 			break;
++		case GETOPT_COLOR:
++			if(optarg) {
++				if(!strcmp(optarg , "always"))
++					no_color_flag = 0;
++				else if(!strcmp(optarg, "never"))
++					no_color_flag = 1;
++				else if(!strcmp(optarg, "auto"))
++					no_color_flag = -1;
++				else
++					error_msg_and_die("invalid argument \"%s\" for \"--color\"\n"
++							  "Valid arguments are:\n"
++							  "  - \"always\"\n"
++							  "  - \"never\"\n"
++							  "  - \"auto\"",
++							  optarg);
++			}
++			break;
+ 		case GETOPT_DAEMONIZE:
+ 			daemonized_tracer_long =
+ 				find_arg_val(optarg, daemonize_str,
+@@ -2875,6 +2935,14 @@ init(int argc, char *argv[])
+ 			      qflag_short == 2 ? qqflag_qual : qqqflag_qual);
+ 	}
+ 
++	// --color=auto (default)
++	if(no_color_flag == -1)
++		no_color_flag = !isatty(STDOUT_FILENO);
++
++	// if we set NO_COLOR or use --output
++	if((getenv("NO_COLOR")) || outfname)
++		no_color_flag = 1;
++
+ 	/*
+ 	 * startup_child() must be called before the signal handlers get
+ 	 * installed below as they are inherited into the spawned process.
+diff --git a/src/swapon.c b/src/swapon.c
+index 72ac42308..214d49ad6 100644
+--- a/src/swapon.c
++++ b/src/swapon.c
+@@ -10,6 +10,7 @@
+ #include <sys/swap.h>
+ 
+ #include "xlat/swap_flags.h"
++#include "color.h"
+ 
+ SYS_FUNC(swapon)
+ {
+@@ -24,7 +25,7 @@ SYS_FUNC(swapon)
+ 	/* swapflags */
+ 	if (flags) {
+ 		printflags(swap_flags, flags, "SWAP_FLAG_???");
+-		tprintf("|%u", prio);
++		tprintf("|" C_CYAN "%u" C_RESET, prio);
+ 	} else {
+ 		PRINT_VAL_U(prio);
+ 	}
+diff --git a/src/syscall.c b/src/syscall.c
+index 92aaee092..22acd6a05 100644
+--- a/src/syscall.c
++++ b/src/syscall.c
+@@ -421,7 +421,7 @@ print_err(int64_t err, bool negated)
+ 	const char *str = err_name(negated ? -err : err);
+ 
+ 	if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
+-		tprintf(negated ? "%" PRId64 : "%" PRIu64, err);
++		tprintf(negated ? C_CYAN "%" PRId64 C_RESET : C_CYAN "%" PRIu64 C_RESET, err);
+ 	if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+ 		return;
+ 	(xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV
+@@ -435,10 +435,10 @@ print_err_ret(kernel_ulong_t ret, unsigned long u_error)
+ 	const char *u_error_str = err_name(u_error);
+ 
+ 	if (u_error_str)
+-		tprintf("= %" PRI_kld " %s (%s)",
++		tprintf("= " C_CYAN "%" PRI_kld C_RESET " %s (%s)",
+ 			ret, u_error_str, strerror(u_error));
+ 	else
+-		tprintf("= %" PRI_kld " (errno %lu)", ret, u_error);
++		tprintf("= " C_CYAN "%" PRI_kld C_RESET " (errno " C_CYAN "%lu" C_RESET ")", ret, u_error);
+ }
+ 
+ static long get_regs(struct tcb *);
+@@ -753,7 +753,7 @@ print_syscall_resume(struct tcb *tcp)
+ 	    || (tcp->flags & TCB_REPRINT)) {
+ 		tcp->flags &= ~TCB_REPRINT;
+ 		printleader(tcp);
+-		tprintf("<... %s resumed>", tcp_sysent(tcp)->sys_name);
++		tprintf("<... " C_RED "%s" C_RESET " resumed>", tcp_sysent(tcp)->sys_name);
+ 	}
+ }
+ 
+@@ -835,7 +835,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
+ 		if (tcp->u_error)
+ 			print_err_ret(tcp->u_rval, tcp->u_error);
+ 		else
+-			tprintf("= %#" PRI_klx, tcp->u_rval);
++			tprintf("= " C_CYAN "%#" PRI_klx C_RESET, tcp->u_rval);
+ 
+ 		print_injected_note(tcp);
+ 	} else if (!(sys_res & RVAL_NONE) && tcp->u_error) {
+@@ -908,12 +908,12 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
+ 			case RVAL_HEX:
+ #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
+ 				if (current_klongsize < sizeof(tcp->u_rval)) {
+-					tprintf("= %#x",
++					tprintf("= " C_CYAN "%#x" C_RESET,
+ 						(unsigned int) tcp->u_rval);
+ 				} else
+ #endif
+ 				{
+-					tprintf("= %#" PRI_klx, tcp->u_rval);
++					tprintf("= " C_CYAN "%#" PRI_klx C_RESET, tcp->u_rval);
+ 				}
+ 				break;
+ 			case RVAL_OCTAL: {
+@@ -930,12 +930,12 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
+ 			case RVAL_UDECIMAL:
+ #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
+ 				if (current_klongsize < sizeof(tcp->u_rval)) {
+-					tprintf("= %u",
++					tprintf("= " C_CYAN "%u" C_RESET,
+ 						(unsigned int) tcp->u_rval);
+ 				} else
+ #endif
+ 				{
+-					tprintf("= %" PRI_klu, tcp->u_rval);
++					tprintf("= " C_CYAN "%" PRI_klu C_RESET, tcp->u_rval);
+ 				}
+ 				break;
+ 			case RVAL_FD:
+@@ -948,7 +948,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
+ 					tprints("= ");
+ 					printfd(tcp, tcp->u_rval);
+ 				} else {
+-					tprintf("= %" PRI_kld, tcp->u_rval);
++					tprintf("= " C_CYAN "%" PRI_kld C_RESET, tcp->u_rval);
+ 				}
+ 				break;
+ 			case RVAL_TID:
+@@ -977,9 +977,9 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
+ 	}
+ 	if (Tflag) {
+ 		ts_sub(ts, ts, &tcp->etime);
+-		tprintf(" <%ld", (long) ts->tv_sec);
++		tprintf(" <" C_CYAN "%ld" C_RESET, (long) ts->tv_sec);
+ 		if (Tflag_width) {
+-			tprintf(".%0*ld",
++			tprintf("." C_CYAN "%0*ld" C_RESET,
+ 				Tflag_width, (long) ts->tv_nsec / Tflag_scale);
+ 		}
+ 		tprints(">");
+diff --git a/src/sysctl.c b/src/sysctl.c
+index 55911d865..7ea71a198 100644
+--- a/src/sysctl.c
++++ b/src/sysctl.c
+@@ -23,6 +23,7 @@
+ #include "xlat/sysctl_net_ipv4_conf.h"
+ #include "xlat/sysctl_net_ipv6.h"
+ #include "xlat/sysctl_net_ipv6_route.h"
++#include "color.h"
+ 
+ SYS_FUNC(sysctl)
+ {
+@@ -39,7 +40,7 @@ SYS_FUNC(sysctl)
+ 	    umoven(tcp, (unsigned long) info.name, size, name) < 0) {
+ 		free(name);
+ 		if (entering(tcp))
+-			tprintf("{%p, %d, %p, %p, %p, %lu}",
++			tprintf("{" C_CYAN "%p" C_RESET ", " C_CYAN "%d" C_RESET ", " C_CYAN "%p" C_RESET ", " C_CYAN "%p" C_RESET ", " C_CYAN "%p" C_RESET ", " C_CYAN "%lu" C_RESET "}",
+ 				info.name, info.nlen, info.oldval,
+ 				info.oldlenp, info.newval, (unsigned long)info.newlen);
+ 		return RVAL_DECODED;
+@@ -140,14 +141,14 @@ out:
+ 		if (abbrev(tcp) && max_cnt > max_strlen)
+ 			max_cnt = max_strlen;
+ 		while (cnt < max_cnt)
+-			tprintf(", %x", name[cnt++]);
++			tprintf(", " C_CYAN "%x" C_RESET, name[cnt++]);
+ 		if (cnt < (unsigned) info.nlen)
+ 			tprints(", ...");
+-		tprintf("}, %d, ", info.nlen);
++		tprintf("}," C_CYAN "%d" C_RESET ", ", info.nlen);
+ 	} else {
+ 		size_t oldlen = 0;
+ 		if (info.oldval == NULL) {
+-			tprints("NULL");
++			tprints(C_CYAN "NULL" C_RESET);
+ 		} else if (umove(tcp, ptr_to_kulong(info.oldlenp), &oldlen) >= 0
+ 			   && info.nlen >= 2
+ 			   && ((name[0] == CTL_KERN
+@@ -156,16 +157,16 @@ out:
+ 					)))) {
+ 			printpath(tcp, ptr_to_kulong(info.oldval));
+ 		} else {
+-			tprintf("%p", info.oldval);
++			tprintf(C_CYAN "%p" C_RESET, info.oldval);
+ 		}
+-		tprintf(", %lu, ", (unsigned long)oldlen);
++		tprintf(", " C_CYAN "%lu" C_RESET ", ", (unsigned long)oldlen);
+ 		if (info.newval == NULL)
+-			tprints("NULL");
++			tprints(C_CYAN "NULL" C_RESET);
+ 		else if (syserror(tcp))
+-			tprintf("%p", info.newval);
++			tprintf(C_CYAN "%p" C_RESET, info.newval);
+ 		else
+ 			printpath(tcp, ptr_to_kulong(info.newval));
+-		tprintf(", %lu", (unsigned long)info.newlen);
++		tprintf(", " C_CYAN "%lu" C_RESET, (unsigned long)info.newlen);
+ 	}
+ 
+ 	free(name);
+diff --git a/src/term.c b/src/term.c
+index 73cc7d63c..0a07010d1 100644
+--- a/src/term.c
++++ b/src/term.c
+@@ -17,6 +17,7 @@
+ #include "xlat/tcflsh_options.h"
+ #include "xlat/baud_options.h"
+ #include "xlat/modem_flags.h"
++#include "color.h"
+ 
+ static void
+ decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
+@@ -36,15 +37,15 @@ decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
+ 			(tios.c_lflag & ECHO) ? "" : "-");
+ 		return;
+ 	}
+-	tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
++	tprintf("{" C_BLUE "c_iflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", " C_BLUE "c_oflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", ",
+ 		(long) tios.c_iflag, (long) tios.c_oflag);
+-	tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
++	tprintf(C_BLUE "c_cflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", " C_BLUE "c_lflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", ",
+ 		(long) tios.c_cflag, (long) tios.c_lflag);
+-	tprintf("c_line=%u, ", tios.c_line);
++	tprintf(C_BLUE "c_line" C_RESET "=" C_CYAN "%u" C_RESET ", ", tios.c_line);
+ 	if (!(tios.c_lflag & ICANON))
+-		tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
++		tprintf(C_BLUE "c_cc[VMIN]" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "c_cc[VTIME]" C_RESET "=" C_CYAN "%d" C_RESET ", ",
+ 			tios.c_cc[VMIN], tios.c_cc[VTIME]);
+-	tprints("c_cc=");
++	tprints(C_BLUE "c_cc=" C_RESET);
+ 	print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX);
+ 	tprints("}");
+ }
+@@ -67,24 +68,24 @@ decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
+ 			(tio.c_lflag & ECHO) ? "" : "-");
+ 		return;
+ 	}
+-	tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
++	tprintf("{" C_BLUE "c_iflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", " C_BLUE "c_oflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", ",
+ 		(long) tio.c_iflag, (long) tio.c_oflag);
+-	tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
++	tprintf(C_BLUE "c_cflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", " C_BLUE "c_lflags" C_RESET "=" C_CYAN "%#lx" C_RESET ", ",
+ 		(long) tio.c_cflag, (long) tio.c_lflag);
+-	tprintf("c_line=%u, ", tio.c_line);
++	tprintf(C_BLUE "c_line" C_RESET "=" C_CYAN "%u" C_RESET ", ", tio.c_line);
+ #ifdef _VMIN
+ 	if (!(tio.c_lflag & ICANON))
+-		tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
++		tprintf(C_BLUE "c_cc[_VMIN]" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "c_cc[_VTIME]" C_RESET "="  C_CYAN "%d" C_RESET ", ",
+ 			tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
+ #else /* !_VMIN */
+ 	if (!(tio.c_lflag & ICANON))
+-		tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
++		tprintf(C_BLUE "c_cc[VMIN]" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "c_cc[VTIME]" C_RESET "=" C_CYAN "%d" C_RESET ", ",
+ 			tio.c_cc[VMIN], tio.c_cc[VTIME]);
+ #endif /* !_VMIN */
+-	tprints("c_cc=\"");
++	tprints(C_BLUE "c_cc" C_RESET "=" C_GREEN "\"");
+ 	for (int i = 0; i < NCC; ++i)
+ 		tprintf("\\x%02x", tio.c_cc[i]);
+-	tprints("\"}");
++	tprints("\"" C_RESET "}");
+ }
+ 
+ static void
+@@ -95,7 +96,7 @@ decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr)
+ 	tprints(", ");
+ 	if (umove_or_printaddr(tcp, addr, &ws))
+ 		return;
+-	tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
++	tprintf("{" C_BLUE "ws_row" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "ws_col" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "ws_xpixel" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "ws_ypixel" C_RESET "=" C_CYAN "%d" C_RESET "}",
+ 		ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
+ }
+ 
+@@ -108,7 +109,7 @@ decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr)
+ 	tprints(", ");
+ 	if (umove_or_printaddr(tcp, addr, &ts))
+ 		return;
+-	tprintf("{ts_lines=%d, ts_cols=%d}",
++	tprintf("{" C_BLUE "ts_lines" C_RESET "=" C_CYAN "%d" C_RESET ", " C_BLUE "ts_cols" C_RESET "=" C_CYAN "%d" C_RESET "}",
+ 		ts.ts_lines, ts.ts_cols);
+ }
+ #endif
+@@ -199,7 +200,7 @@ term_ioctl(struct tcb *const tcp, const unsigned int code,
+ 	case TCSBRK:
+ 	case TCSBRKP:
+ 	case TIOCSCTTY:
+-		tprintf(", %d", (int) arg);
++		tprintf(", " C_CYAN "%d" C_RESET, (int) arg);
+ 		break;
+ 
+ 	/* ioctls with an indirect parameter displayed as modem flags */
+diff --git a/src/util.c b/src/util.c
+index 5f87acb91..a93a857ed 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -32,6 +32,7 @@
+ #include "string_to_uint.h"
+ #include "xlat.h"
+ #include "xstring.h"
++#include "color.h"
+ 
+ const struct xlat_data *
+ find_xlat_val_ex(const struct xlat_data *items, const char *s, size_t num_items,
+@@ -394,7 +395,7 @@ void
+ printaddr64(const uint64_t addr)
+ {
+ 	if (!addr)
+-		tprints("NULL");
++		tprints(C_CYAN "NULL" C_RESET);
+ 	else
+ 		PRINT_VAL_X(addr);
+ }
+@@ -659,7 +660,7 @@ printdev(struct tcb *tcp, int fd, const char *path)
+ 		print_quoted_string_ex(path, strlen(path),
+ 				       QUOTE_OMIT_LEADING_TRAILING_QUOTES,
+ 				       "<>");
+-		tprintf("<%s %u:%u>>",
++		tprintf("<" C_BLUE "%s" C_RESET " " C_CYAN "%u" C_RESET ":" C_CYAN "%u" C_RESET ">>",
+ 			S_ISBLK(st.st_mode)? "block" : "char",
+ 			major(st.st_rdev), minor(st.st_rdev));
+ 		return true;
+@@ -1049,7 +1050,8 @@ print_quoted_string_ex(const char *str, unsigned int size,
+ 	}
+ 
+ 	rc = string_quote(str, outstr, size, style, escape_chars);
+-	tprints(outstr);
++
++	tprintf(C_GREEN "%s" C_RESET, outstr);
+ 
+ 	if (((style & (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0))
+ 	     == (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0)) && rc) {
+@@ -1098,7 +1100,7 @@ printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
+ 	int nul_seen;
+ 
+ 	if (!addr) {
+-		tprints("NULL");
++		tprints(C_CYAN "NULL" C_RESET);
+ 		return -1;
+ 	}
+ 
+@@ -1152,7 +1154,7 @@ printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
+ 	int ellipsis;
+ 
+ 	if (!addr) {
+-		tprints("NULL");
++		tprints(C_CYAN "NULL" C_RESET);
+ 		return -1;
+ 	}
+ 	/* Allocate static buffers if they are not allocated yet. */
+@@ -1202,7 +1204,7 @@ printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
+ 		   && ((style & (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0))
+ 		       || len > max_strlen);
+ 
+-	tprints(outstr);
++	tprintf(C_GREEN "%s" C_RESET, outstr);
+ 	if (ellipsis)
+ 		tprint_more_data_follows();
+ 
+@@ -1243,7 +1245,7 @@ print_nonzero_bytes(struct tcb *const tcp,
+ 		ret = false;
+ 	} else {
+ 		prefix_fun();
+-		tprintf("/* bytes %u..%u */ ", start_offs, total_len - 1);
++		tprintf(C_MAGENTA "/* bytes %u..%u */ " C_RESET, start_offs, total_len - 1);
+ 
+ 		print_quoted_string(str, size, style);
+ 
+@@ -1301,7 +1303,7 @@ dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
+ 			data_size -= iov_len;
+ 			/* include the buffer number to make it easy to
+ 			 * match up the trace with the source */
+-			tprintf(" * %" PRI_klu " bytes in buffer %d\n", iov_len, i);
++			tprintf(" * " C_CYAN "%" PRI_klu C_RESET " bytes in buffer " C_CYAN "%d" C_RESET "\n", iov_len, i);
+ 			dumpstr(tcp, iov_iov_base(i), iov_len);
+ 		}
+ 	}
+@@ -1441,7 +1443,7 @@ dumpstr(struct tcb *const tcp, const kernel_ulong_t addr,
+ 			src++;
+ 		} while (++i & DUMPSTR_BYTES_MASK);
+ 
+-		tprintf(" | %0*" PRI_klx "  %s |\n",
++		tprintf(" | " C_CYAN "%0*" PRI_klx C_RESET "  %s |\n",
+ 			offs_chars, i - DUMPSTR_WIDTH_BYTES, outbuf);
+ 	}
+ }
+@@ -1608,7 +1610,7 @@ print_array_ex(struct tcb *const tcp,
+ 	       const char *index_dflt)
+ {
+ 	if (!start_addr) {
+-		tprints("NULL");
++		tprints(C_CYAN "NULL" C_RESET);
+ 		return false;
+ 	}
+ 
+@@ -1744,7 +1746,7 @@ print_abnormal_hi(const kernel_ulong_t val)
+ 	if (current_klongsize > 4) {
+ 		const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
+ 		if (hi)
+-			tprintf("%#x<<32|", hi);
++			tprintf(C_CYAN "%#x" C_RESET "<<" C_CYAN "32" C_RESET "|", hi);
+ 	}
+ }
+ 
+diff --git a/src/wait.c b/src/wait.c
+index 9880831c3..7bc4985e9 100644
+--- a/src/wait.c
++++ b/src/wait.c
+@@ -20,6 +20,7 @@
+ 
+ #include "xlat/wait4_options.h"
+ #include "xlat/ptrace_events.h"
++#include "color.h"
+ 
+ static int
+ printstatus(int status)
+@@ -36,7 +37,7 @@ printstatus(int status)
+ 		int sig = WSTOPSIG(status);
+ 		tprintf("{WIFSTOPPED(s) && WSTOPSIG(s) == %s%s}",
+ 			sprintsigname(sig & 0x7f),
+-			sig & 0x80 ? " | 0x80" : "");
++			sig & 0x80 ? " |" C_CYAN "0x80" C_RESET : "");
+ 		status &= ~W_STOPCODE(sig);
+ 	} else if (WIFSIGNALED(status)) {
+ 		tprintf("{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
+@@ -44,7 +45,7 @@ printstatus(int status)
+ 			WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
+ 		status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
+ 	} else if (WIFEXITED(status)) {
+-		tprintf("{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
++		tprintf("{WIFEXITED(s) && WEXITSTATUS(s) == " C_CYAN "%d" C_RESET "}",
+ 			WEXITSTATUS(status));
+ 		exited = 1;
+ 		status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
+@@ -66,7 +67,7 @@ printstatus(int status)
+ 		if (event) {
+ 			tprints(" | ");
+ 			printxval(ptrace_events, event, "PTRACE_EVENT_???");
+-			tprints(" << 16");
++			tprints(" << " C_CYAN "16" C_RESET);
+ 			status &= 0xffff;
+ 		}
+ 		if (status) {
+diff --git a/src/xlat.c b/src/xlat.c
+index b240fdd34..55be995e2 100644
+--- a/src/xlat.c
++++ b/src/xlat.c
+@@ -12,6 +12,7 @@
+ #include "defs.h"
+ #include "xstring.h"
+ #include <stdarg.h>
++#include "color.h"
+ 
+ static enum xlat_style
+ get_xlat_style(enum xlat_style style)
+@@ -47,7 +48,7 @@ sprint_xlat_val(uint64_t val, enum xlat_style style)
+ static void
+ print_xlat_val(uint64_t val, enum xlat_style style)
+ {
+-	tprints(sprint_xlat_val(val, style));
++	tprintf(C_CYAN "%s" C_RESET, sprint_xlat_val(val, style));
+ }
+ 
+ static int
+@@ -235,7 +236,7 @@ printxvals_ex(const uint64_t val, const char *dflt, enum xlat_style style,
+ 				print_xlat_val(val, style);
+ 				tprints_comment(str);
+ 			} else {
+-				tprints(str);
++				tprintf(C_YELLOW "%s" C_RESET, str);
+ 			}
+ 
+ 			goto printxvals_ex_end;
+@@ -445,7 +446,7 @@ printflags_ex(uint64_t flags, const char *dflt, enum xlat_style style,
+ 					tprints("|");
+ 				else if (need_comment)
+ 					tprint_comment_begin();
+-				tprints(xlat->data[idx].str);
++				tprintf(C_YELLOW "%s" C_RESET, xlat->data[idx].str);
+ 				flags &= ~v;
+ 			}
+ 			if (!flags)
+@@ -490,7 +491,7 @@ print_xlat_ex(const uint64_t val, const char *str, uint32_t style)
+ 				print_xlat_val(val, style);
+ 				tprints_comment(str);
+ 			} else {
+-				tprints(str);
++				tprintf(C_YELLOW "%s" C_RESET, str);
+ 			}
+ 			break;
+ 		}