diff --git a/cpu/esp8266/Makefile.dep b/cpu/esp8266/Makefile.dep
index 0ea8f2b482a08c151dab81c03450290e7ecbe4a3..f5527b8efbf2bb62f5dadad84934c4e07af778d3 100644
--- a/cpu/esp8266/Makefile.dep
+++ b/cpu/esp8266/Makefile.dep
@@ -2,6 +2,14 @@
 
 ifneq (, $(filter esp_sdk, $(USEMODULE)))
     USEMODULE += core_thread_flags
+    LINKFLAGS += -Wl,-wrap=malloc
+    LINKFLAGS += -Wl,-wrap=free
+    LINKFLAGS += -Wl,-wrap=calloc
+    LINKFLAGS += -Wl,-wrap=realloc
+    LINKFLAGS += -Wl,-wrap=_malloc_r
+    LINKFLAGS += -Wl,-wrap=_free_r
+    LINKFLAGS += -Wl,-wrap=_realloc_r
+    LINKFLAGS += -Wl,-wrap=mallinfo
 endif
 
 ifneq (, $(filter esp_spiffs, $(USEMODULE)))
diff --git a/cpu/esp8266/syscalls.c b/cpu/esp8266/syscalls.c
index 65273ee76ec0a5a4fda02a1efb950ee542f3c65c..c84efb62a38ed1d1b8cf5b8b910952a473b1ae51 100644
--- a/cpu/esp8266/syscalls.c
+++ b/cpu/esp8266/syscalls.c
@@ -27,6 +27,7 @@
 #include <sys/reent.h>
 #include <sys/stat.h>
 
+#include <malloc.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -87,13 +88,13 @@ int /* IRAM */ printf(const char* format, ...)
     return ret;
 }
 
-#ifdef SDK_HEAP_USED
+#ifdef MODULE_ESP_SDK
 /**
  * Map memory management functions to SDK memory management functions.
  * This is necessary to use the same heap as the SDK internally does.
- * Furthermore, these functions do at least avoid interrupts during the
- * execution of memory management functions. Memory management function
- * of ETS are not used and have not to considered therefore.
+ * Furthermore, these functions at least avoid interrupts during the
+ * execution of memory management functions. Memory management functions
+ * of ETS are not used and have not to be considered therefore.
  */
 extern void *pvPortMalloc (size_t size, const char *, unsigned);
 extern void vPortFree (void *ptr, const char *, unsigned);
@@ -102,7 +103,16 @@ extern void *pvPortCalloc (size_t nmemb, size_t size, const char *, unsigned);
 extern void *pvPortRealloc (void *ptr, size_t size, const char *, unsigned);
 extern unsigned int xPortGetFreeHeapSize(void);
 
-void* IRAM malloc(size_t size)
+void *__real_malloc(size_t size);
+void  __real_free(void *ptr);
+void *__real_calloc(size_t nmemb, size_t size);
+void *__real_realloc(void *ptr, size_t size);
+void *__real__malloc_r (struct _reent *r, size_t size);
+void  __real__free_r (struct _reent *r, void *ptr);
+void *__real__realloc_r (struct _reent *r, void *ptr, size_t size);
+struct mallinfo __real_mallinfo(void);
+
+void* IRAM __wrap_malloc(size_t size)
 {
     #if MEMLEAK_DEBUG
     static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
@@ -112,7 +122,7 @@ void* IRAM malloc(size_t size)
     #endif
 }
 
-void IRAM free(void *ptr)
+void IRAM __wrap_free(void *ptr)
 {
     #if MEMLEAK_DEBUG
     static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
@@ -122,7 +132,7 @@ void IRAM free(void *ptr)
     #endif
 }
 
-void* IRAM calloc(size_t nmemb, size_t size)
+void* IRAM __wrap_calloc(size_t nmemb, size_t size)
 {
     #if MEMLEAK_DEBUG
     static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
@@ -132,7 +142,7 @@ void* IRAM calloc(size_t nmemb, size_t size)
     #endif
 }
 
-void* IRAM realloc(void *ptr, size_t size)
+void* IRAM __wrap_realloc(void *ptr, size_t size)
 {
     #if MEMLEAK_DEBUG
     static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
@@ -142,14 +152,19 @@ void* IRAM realloc(void *ptr, size_t size)
     #endif
 }
 
-void* IRAM _malloc_r (struct _reent *r, size_t size)
+void* IRAM __wrap__malloc_r (struct _reent *r, size_t size)
 {
-    return malloc (size);
+    return __wrap_malloc (size);
 }
 
-void IRAM _free_r (struct _reent *r, void *ptr)
+void IRAM __wrap__free_r (struct _reent *r, void *ptr)
 {
-    free (ptr);
+    __wrap_free (ptr);
+}
+
+void IRAM *__wrap__realloc_r (struct _reent *r, void *ptr, size_t size)
+{
+    return __wrap_realloc (ptr, size);
 }
 
 unsigned int get_free_heap_size (void)
@@ -157,14 +172,37 @@ unsigned int get_free_heap_size (void)
     return xPortGetFreeHeapSize();
 }
 
-void IRAM syscalls_init (void) {}
+extern uint8_t  _eheap;     /* end of heap (defined in esp8266.riot-os.app.ld) */
+extern uint8_t  _sheap;     /* start of heap (defined in esp8266.riot-os.app.ld) */
+
+struct mallinfo __wrap_mallinfo(void)
+{
+    struct mallinfo mi;
+
+    mi.arena = &_eheap - &_sheap;
+    mi.fordblks = get_free_heap_size();
+    mi.uordblks = mi.arena - mi.fordblks;
+    mi.keepcost = mi.fordblks;
+    return mi;
+}
+
+void heap_stats(void)
+{
+    struct mallinfo minfo = __wrap_mallinfo();
+    ets_printf("heap: %d (used %d, free %d)\n",
+               minfo.arena, minfo.uordblks, minfo.fordblks);
+}
+
+void IRAM syscalls_init (void)
+{
+}
 
-#else   /* SDK_HEAP_USED */
+#else   /* MODULE_ESP_SDK */
 /*
- * To use the same heap SDK memory management functions have to be replaced by
- * newlib memory functions. In that case the _malloc_lock/_unlock functions
- * have to be defined. Memory management functions of ETS are not used and
- * have not to considered here.
+ * To use the same heap as SDK internally does, SDK memory management
+ * functions have to be replaced by newlib memory functions. In that case,
+ * the _malloc_lock/_unlock functions have to be defined. Memory management
+ * functions of ETS are not used and have not to be considered here.
  */
 
 void* IRAM pvPortMalloc (size_t size, const char *file, unsigned line)
@@ -227,9 +265,11 @@ size_t IRAM xPortGetFreeHeapSize (void)
 }
 
 /*
- * Following function implement the lock mechanism in newlib. The only static
+ * Following functions implement the lock mechanism in newlib. The only static
  * mutex defined here is the __malloc_recursive_mutex to avoid that memory
  * management functions try to lock before RIOT's threads are running.
+ * These lock/unlock functions cannot be used in the SDK version since some ISR
+ * in SDK use malloc/free which does not work in interrupt context.
  */
 
 extern _lock_t __malloc_recursive_mutex;
@@ -342,6 +382,7 @@ void IRAM _lock_release_recursive(_lock_t *lock)
 
 extern char *heap_top;
 extern char _eheap;     /* end of heap (defined in esp8266.riot-os.app.ld) */
+extern char _sheap;     /* start of heap (defined in esp8266.riot-os.app.ld) */
 
 #else /* MODULE_NEWLIB_SYSCALLS_DEFAULT */
 
@@ -380,8 +421,6 @@ void* IRAM _sbrk_r (struct _reent *r, ptrdiff_t incr)
     return (void*) _cheap_old;
 }
 
-
-
 #endif  /* MODULE_NEWLIB_SYSCALLS_DEFAULT */
 
 unsigned int IRAM get_free_heap_size (void)
@@ -389,7 +428,15 @@ unsigned int IRAM get_free_heap_size (void)
     return (_cheap) ? &_eheap - _cheap : 0;
 }
 
-#endif /* SDK_HEAP_USED */
+void heap_stats(void)
+{
+    struct mallinfo minfo = mallinfo();
+    ets_printf("heap: %u (free %u), ", &_eheap - &_sheap, get_free_heap_size());
+    ets_printf("sysmem: %d (used %d, free %d)\n",
+               minfo.arena, minfo.uordblks, minfo.fordblks);
+}
+
+#endif /* MODULE_ESP_SDK */
 
 #if !defined(MODULE_NEWLIB_SYSCALLS_DEFAULT)