]> granicus.if.org Git - esp-idf/commitdiff
newlib: when compiling with GCC8, use newlib headers and libraries from toolchain
authorIvan Grokhotkov <ivan@espressif.com>
Mon, 1 Apr 2019 07:21:12 +0000 (15:21 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Wed, 10 Apr 2019 05:52:30 +0000 (13:52 +0800)
components/esp_rom/esp32/ld/esp32.rom.syscalls.ld
components/newlib/CMakeLists.txt
components/newlib/component.mk
components/newlib/heap.c [new file with mode: 0644]
components/newlib/newlib.lf [new file with mode: 0644]
components/newlib/syscalls.c

index f358bddd37f27dd5cbd3a14aff58308fc342f96a..811d879dd48165efeef226d954f537f728f54f8d 100644 (file)
@@ -28,7 +28,7 @@ PROVIDE ( _write_r = 0x4000bd70 );
 
    I.e.:
 
-   free (in ROM) -> _free_r (in ROM) -> syscall table entry _free_r -> _free_r (in IDF)
+   times (in ROM) -> _times_r (in ROM) -> syscall table entry _times_r -> _times_r (in IDF)
 
    Hence the following entries are provided only for reference
    and commented out.
@@ -36,6 +36,8 @@ PROVIDE ( _write_r = 0x4000bd70 );
 
 /*   <--- the following lines are commented out
 
+PROVIDE ( calloc = 0x4000bee4 );
+PROVIDE ( free = 0x4000beb8 );
 PROVIDE ( _free_r = 0x4000bbcc );
 PROVIDE ( _getpid_r = 0x4000bcfc );
 PROVIDE ( __getreent = 0x4000be8c );
@@ -51,8 +53,10 @@ PROVIDE ( _lock_release = 0x4000be64 );
 PROVIDE ( _lock_release_recursive = 0x4000be78 );
 PROVIDE ( _lock_try_acquire = 0x4000be3c );
 PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 );
+PROVIDE ( malloc = 0x4000bea0 );
 PROVIDE ( _malloc_r = 0x4000bbb4 );
 PROVIDE ( _raise_r = 0x4000bc70 );
+PROVIDE ( realloc = 0x4000becc );
 PROVIDE ( _realloc_r = 0x4000bbe0 );
 PROVIDE ( _sbrk_r = 0x4000bce4 );
 PROVIDE ( _system_r = 0x4000bc10 );
@@ -67,13 +71,9 @@ PROVIDE ( _times_r = 0x4000bc40 );
    as the first argument.
  */
 
-calloc = 0x4000bee4;
 close = 0x40001778;
-free = 0x4000beb8;
-malloc = 0x4000bea0;
 open = 0x4000178c;
 read = 0x400017dc;
-realloc = 0x4000becc;
 sbrk = 0x400017f4;
 times = 0x40001808;
 write = 0x4000181c;
index 6cb6fb8e51d5df53820b55a464d7fe659ccfe518..a5bae29adf7f6315fd6c08f518a129e6d15f64bc 100644 (file)
@@ -1,14 +1,15 @@
-set(COMPONENT_SRCS "locks.c"
+set(COMPONENT_SRCS "heap.c"
+                   "locks.c"
+                   "poll.c"
                    "pthread.c"
                    "random.c"
                    "reent_init.c"
                    "select.c"
-                   "poll.c"
                    "syscall_table.c"
                    "syscalls.c"
                    "termios.c"
-                   "utime.c"
-                   "time.c")
+                   "time.c"
+                   "utime.c")
 set(COMPONENT_ADD_INCLUDEDIRS platform_include)
 
 
@@ -25,9 +26,11 @@ if(GCC_NOT_5_2_0)
         set(COMPONENT_ADD_LDFRAGMENTS esp32-spiram-rom-functions-c.lf)
     endif()
 
-    # Forces the linker to include locks.o from this component, which
-    # replaces weak locking functions defined in libc.a:locks.o
+    # Forces the linker to include locks, heap, and syscalls from this component,
+    # instead of the implementations provided by newlib.
     set(EXTRA_LINK_FLAGS "-u newlib_include_locks_impl")
+    list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_heap_impl")
+    list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_syscalls_impl")
 
 else()
     # Remove this section when GCC 5.2.0 is no longer supported
@@ -54,6 +57,8 @@ else()
 endif()
 set(COMPONENT_REQUIRES vfs)  # for sys/ioctl.h
 
+list(APPEND COMPONENT_ADD_LDFRAGMENTS newlib.lf)
+
 register_component()
 
 if (LIB_PATH)
@@ -61,7 +66,7 @@ if (LIB_PATH)
 endif()
 target_link_libraries(${COMPONENT_TARGET} ${LIBC} ${LIBM})
 
-set_source_files_properties(syscalls.c PROPERTIES COMPILE_FLAGS -fno-builtin)
+set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin)
 
 if(EXTRA_LINK_FLAGS)
     target_link_libraries(${COMPONENT_TARGET} "${EXTRA_LINK_FLAGS}")
index 008497acef36f3953fd945f17c5c7790d93faf8b..1f99816aa9510e5449da5accba959f83ec25fac7 100644 (file)
@@ -7,16 +7,19 @@ else  # CONFIG_NEWLIB_NANO_FORMAT
 LIBC := c
 endif  # CONFIG_NEWLIB_NANO_FORMAT
 
-COMPONENT_ADD_LDFLAGS := -l$(LIBC) -lm -lnewlib
+# Order of linking matters: libnewlib.a should go before libc.a
+COMPONENT_ADD_LDFLAGS := -lnewlib -l$(LIBC) -lm
 COMPONENT_ADD_INCLUDEDIRS := platform_include
 
 ifdef CONFIG_SPIRAM_CACHE_WORKAROUND
 COMPONENT_ADD_LDFRAGMENTS := esp32-spiram-rom-functions-c.lf
 endif
 
-# Forces the linker to include locks.o from this component, which
-# replaces weak locking functions defined in libc.a:locks.o
+# Forces the linker to include locks, heap, and syscalls from this component,
+# instead of the implementations provided by newlib.
 COMPONENT_ADD_LDFLAGS += -u newlib_include_locks_impl
+COMPONENT_ADD_LDFLAGS += -u newlib_include_heap_impl
+COMPONENT_ADD_LDFLAGS += -u newlib_include_syscalls_impl
 
 else # GCC_NOT_5_2_0
 # Remove this section when GCC 5.2.0 is no longer supported
@@ -44,4 +47,6 @@ COMPONENT_ADD_LINKER_DEPS := $(LIBC_PATH) $(LIBM_PATH)
 COMPONENT_ADD_INCLUDEDIRS := platform_include include
 endif  # GCC_NOT_5_2_0
 
-syscalls.o: CFLAGS += -fno-builtin
+COMPONENT_ADD_LDFRAGMENTS += newlib.lf
+
+heap.o: CFLAGS += -fno-builtin
diff --git a/components/newlib/heap.c b/components/newlib/heap.c
new file mode 100644 (file)
index 0000000..37380a3
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/reent.h>
+#include <malloc.h>
+#include "esp_heap_caps.h"
+
+
+/*
+ These contain the business logic for the malloc() and realloc() implementation. Because of heap tracing
+ wrapping reasons, we do not want these to be a public api, however, so they're not defined publicly.
+*/
+extern void *heap_caps_malloc_default( size_t size );
+extern void *heap_caps_realloc_default( void *ptr, size_t size );
+
+
+void* malloc(size_t size)
+{
+    return heap_caps_malloc_default(size);
+}
+
+void* calloc(size_t n, size_t size)
+{
+    return _calloc_r(_REENT, n, size);
+}
+
+void* realloc(void* ptr, size_t size)
+{
+    return heap_caps_realloc_default(ptr, size);
+}
+
+void free(void *ptr)
+{
+    heap_caps_free(ptr);
+}
+
+void* _malloc_r(struct _reent *r, size_t size)
+{
+    return heap_caps_malloc_default(size);
+}
+
+void _free_r(struct _reent *r, void* ptr)
+{
+    heap_caps_free(ptr);
+}
+
+void* _realloc_r(struct _reent *r, void* ptr, size_t size)
+{
+    return heap_caps_realloc_default( ptr, size );
+}
+
+void* _calloc_r(struct _reent *r, size_t nmemb, size_t size)
+{
+    void *result;
+    size_t size_bytes;
+    if (__builtin_mul_overflow(nmemb, size, &size_bytes)) {
+        return NULL;
+    }
+
+    result = heap_caps_malloc_default(size_bytes);
+    if (result != NULL) {
+        bzero(result, size_bytes);
+    }
+    return result;
+}
+
+/* No-op function, used to force linking this file,
+   instead of the heap implementation from newlib.
+ */
+void newlib_include_heap_impl()
+{
+}
+
+/* The following functions are implemented by newlib's heap allocator,
+   but aren't available in the heap component.
+   Define them as non-functional stubs here, so that the application
+   can not cause the newlib heap implementation to be linked in
+ */
+void* memalign(size_t alignment, size_t n)
+{
+    extern void memalign_function_was_linked_but_unsupported_in_esp_idf(void);
+    memalign_function_was_linked_but_unsupported_in_esp_idf();
+    return NULL;
+}
+
+int malloc_trim(size_t pad)
+{
+    return 0; // indicates failure
+}
+
+size_t malloc_usable_size(void* p)
+{
+    return 0;
+}
+
+void malloc_stats()
+{
+}
+
+int mallopt(int parameter_number, int parameter_value)
+{
+    return 0; // indicates failure
+}
+
+struct mallinfo mallinfo()
+{
+    struct mallinfo dummy = {0};
+    return dummy;
+}
+
+void* valloc(size_t n) __attribute__((alias("malloc")));
+void* pvalloc(size_t n) __attribute__((alias("malloc")));
+void cfree(void* p) __attribute__((alias("free")));
diff --git a/components/newlib/newlib.lf b/components/newlib/newlib.lf
new file mode 100644 (file)
index 0000000..59d3ace
--- /dev/null
@@ -0,0 +1,6 @@
+# Places the heap related functions from heap.c into IRAM
+
+[mapping:newlib]
+archive: libnewlib.a
+entries:
+  heap (noflash)
index d1c06a472f5079e43db30436593d5a2e4e19e4a4..899f21d4882956a0c41f78bb7a09765d97094696 100644 (file)
 
 #include <string.h>
 #include <stdbool.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>
 #include <sys/reent.h>
-#include <stdlib.h>
-#include "esp_attr.h"
-#include "freertos/FreeRTOS.h"
-#include "esp_heap_caps.h"
-
-
-/*
- These contain the business logic for the malloc() and realloc() implementation. Because of heap tracing
- wrapping reasons, we do not want these to be a public api, however, so they're not defined publicly.
-*/
-extern void *heap_caps_malloc_default( size_t size );
-extern void *heap_caps_realloc_default( void *ptr, size_t size );
-
 
-void* IRAM_ATTR _malloc_r(struct _reent *r, size_t size)
-{
-    return heap_caps_malloc_default( size );
-}
-
-void IRAM_ATTR _free_r(struct _reent *r, void* ptr)
-{
-    heap_caps_free( ptr );
-}
-
-void* IRAM_ATTR _realloc_r(struct _reent *r, void* ptr, size_t size)
-{
-    return heap_caps_realloc_default( ptr, size );
-}
-
-void* IRAM_ATTR _calloc_r(struct _reent *r, size_t nmemb, size_t size)
-{
-    void *result;
-    size_t size_bytes;
-    if (__builtin_mul_overflow(nmemb, size, &size_bytes)) {
-        return NULL;
-    }
-
-    result = malloc(size_bytes);
-    if (result != NULL) {
-        bzero(result, size_bytes);
-    }
-    return result;
-}
 
 int _system_r(struct _reent *r, const char *str)
 {
@@ -95,3 +54,9 @@ void _exit(int __status)
     abort();
 }
 
+/* No-op function, used to force linking this file,
+   instead of the syscalls implementation from libgloss.
+ */
+void newlib_include_syscalls_impl()
+{
+}