From aaef4b0644ce742bd416a2d2a1d9daf9b9751c44 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 16 Jun 2015 10:02:36 +1000 Subject: [PATCH] Replace all binary SDK libc functions with newlib Adds a new build step to remove the SDK object files listed in .remove. Closes #1. --- FreeRTOS/Source/portable/esp8266/sdk_compat.c | 14 ---- common.mk | 47 +++++++++----- core/sdk_compat.c | 28 ++++++++ examples/http_get/main.c | 2 + examples/http_get_ssl/main.c | 2 + examples/tests/hmac_test_vectors/main.c | 2 + include/espressif/esp_common.h | 1 - include/espressif/esp_libc.h | 64 ------------------- lib/libmain.remove | 3 + lib/libnet80211.remove | 0 lib/libphy.remove | 0 lib/libpp.remove | 0 lib/libwpa.remove | 0 13 files changed, 68 insertions(+), 95 deletions(-) delete mode 100644 FreeRTOS/Source/portable/esp8266/sdk_compat.c create mode 100644 core/sdk_compat.c delete mode 100644 include/espressif/esp_libc.h create mode 100644 lib/libmain.remove create mode 100644 lib/libnet80211.remove create mode 100644 lib/libphy.remove create mode 100644 lib/libpp.remove create mode 100644 lib/libwpa.remove diff --git a/FreeRTOS/Source/portable/esp8266/sdk_compat.c b/FreeRTOS/Source/portable/esp8266/sdk_compat.c deleted file mode 100644 index f377287..0000000 --- a/FreeRTOS/Source/portable/esp8266/sdk_compat.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Wrappers for functions called by binary espressif libraries - * - * Part of esp-open-rtos - * Copyright (C) 2015 Superhouse Automation Pty Ltd - * BSD Licensed as described in the file LICENSE - */ -#include -#include -#include "FreeRTOS.h" - -void *zalloc(size_t nbytes) { - return calloc(1, nbytes); -} diff --git a/common.mk b/common.mk index c1ce356..ff505ff 100644 --- a/common.mk +++ b/common.mk @@ -65,7 +65,7 @@ COMPONENTS ?= core FreeRTOS lwip axtls SDK_LIBS ?= main net80211 phy pp wpa # open source libraries linked in -LIBS ?= gcc hal +LIBS ?= gcc hal cirom # Note: this isn't overridable without a not-yet-merged patch to esptool ENTRY_SYMBOL = call_user_start @@ -186,35 +186,50 @@ endef ## Linking rules for SDK libraries ## SDK libraries are preprocessed to: +# - remove object files named in .remove # - prefix all defined symbols with 'sdk_' # - weaken all global symbols so they can be overriden from the open SDK side - -# SDK binary libraries are preprocessed into build/lib +# +# SDK binary libraries are preprocessed into build/sdklib SDK_PROCESSED_LIBS = $(addsuffix .a,$(addprefix $(BUILD_DIR)sdklib/lib,$(SDK_LIBS))) -# Make rule for preprocessing each SDK library -# -$(BUILD_DIR)sdklib/%.a: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/allsymbols.rename - $(vecho) "Pre-processing SDK library $< -> $@" - $(Q) $(OBJCOPY) --redefine-syms $(word 2,$^) --weaken $< $@ +# Make rules for preprocessing each SDK library +# hacky, but prevents confusing error messages if one of these files disappears +$(ROOT)lib/%.remove: + touch $@ -# Generate a regex to match symbols we don't want to rename, by parsing -# a list of symbol names +# Remove comment lines from .remove files +$(BUILD_DIR)sdklib/%.remove: $(ROOT)lib/%.remove | $(BUILD_DIR)sdklib + $(Q) grep -v "^#" $< | cat > $@ + +# Stage 1: remove unwanted object files listed in .remove alongside each library +$(BUILD_DIR)sdklib/%_stage1.a: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/%.remove | $(BUILD_DIR)sdklib + @echo "SDK processing stage 1: Removing unwanted objects from $<" + $(Q) cat $< > $@ + $(Q) $(AR) d $@ @$(word 2,$^) + +# Generate a regex to match symbols we don't want to rename, listed in +# symbols_norename.txt $(BUILD_DIR)sdklib/norename.match: $(ROOT)lib/symbols_norename.txt | $(BUILD_DIR)sdklib - grep -v "^#" $< | sed ':begin;$!N;s/\n/\\|/;tbegin' > $@ + cat $< | grep -v "^#" | sed ':begin;$!N;s/\n/\\|/;tbegin' > $@ -# Generate list of defined symbols to rename from a single library. Uses grep & sed. -$(BUILD_DIR)sdklib/%.rename: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/norename.match - $(vecho) "Building symbol list for $< -> $@" +# Stage 2: Build a list of defined symbols per library, renamed with sdk_ prefix +$(BUILD_DIR)sdklib/%.rename: $(BUILD_DIR)sdklib/%_stage1.a $(BUILD_DIR)sdklib/norename.match + @echo "SDK processing stage 2: Building symbol list for $< -> $@" $(Q) $(OBJDUMP) -t $< | grep ' g ' \ | sed -r 's/^.+ ([^ ]+)$$/\1 sdk_\1/' \ | grep -v `cat $(BUILD_DIR)sdklib/norename.match` > $@ -# Build master list of all SDK-defined symbols to rename +# Build a master list of all SDK-defined symbols to rename across all libraries $(BUILD_DIR)sdklib/allsymbols.rename: $(patsubst %.a,%.rename,$(SDK_PROCESSED_LIBS)) cat $^ > $@ +# Stage 3: Redefine all SDK symbols as sdk_, weaken all symbols. +$(BUILD_DIR)sdklib/%.a: $(BUILD_DIR)sdklib/%_stage1.a $(BUILD_DIR)sdklib/allsymbols.rename + @echo "SDK processing stage 3: Renaming symbols in SDK library $< -> $@" + $(Q) $(OBJCOPY) --redefine-syms $(word 2,$^) --weaken $< $@ + # include "dummy component" for the 'program' object files, defined in the Makefile PROGRAM_SRC_DIR ?= $(PROGRAM_DIR) PROGRAM_ROOT ?= $(PROGRAM_DIR) @@ -227,7 +242,7 @@ $(foreach component,$(COMPONENTS), $(eval include $(ROOT)$(component)/component. # final linking step to produce .elf $(PROGRAM_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS) $(vecho) "LD $@" - $(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(SDK_LIB_ARGS) $(LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ + $(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(SDK_LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ $(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib: $(Q) mkdir -p $@ diff --git a/core/sdk_compat.c b/core/sdk_compat.c new file mode 100644 index 0000000..5abee60 --- /dev/null +++ b/core/sdk_compat.c @@ -0,0 +1,28 @@ +/* + * Wrappers for functions called by binary espressif libraries + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include + +void *zalloc(size_t nbytes) +{ + return calloc(1, nbytes); +} + +/* this is currently just a stub to see where in the SDK it gets + called, and with what arguments... + + In the binary SDK printf & ets_printf are aliased together, most + references appear to be to printf but libphy, libwpa & libnet80211 + all call ets_printf sometimes... Seems to not be in common code + paths, haven't investigated exactly where. +*/ +int ets_printf(const char *format, ...) { + return printf("ets_printf format=%s\r\n", format); +} + diff --git a/examples/http_get/main.c b/examples/http_get/main.c index 2e68901..0930c49 100644 --- a/examples/http_get/main.c +++ b/examples/http_get/main.c @@ -7,6 +7,8 @@ #include "espressif/esp_common.h" #include "espressif/sdk_private.h" +#include + #include "FreeRTOS.h" #include "task.h" diff --git a/examples/http_get_ssl/main.c b/examples/http_get_ssl/main.c index 7dfbc97..0f099b1 100644 --- a/examples/http_get_ssl/main.c +++ b/examples/http_get_ssl/main.c @@ -9,6 +9,8 @@ #include "espressif/esp_common.h" #include "espressif/sdk_private.h" +#include + #include "FreeRTOS.h" #include "task.h" diff --git a/examples/tests/hmac_test_vectors/main.c b/examples/tests/hmac_test_vectors/main.c index 7fc813b..426f217 100644 --- a/examples/tests/hmac_test_vectors/main.c +++ b/examples/tests/hmac_test_vectors/main.c @@ -12,6 +12,8 @@ #include "FreeRTOS.h" #include "ssl.h" +#include + struct test_vector { const uint8_t *key; const uint8_t key_len; diff --git a/include/espressif/esp_common.h b/include/espressif/esp_common.h index 43f3318..5dabf31 100644 --- a/include/espressif/esp_common.h +++ b/include/espressif/esp_common.h @@ -10,7 +10,6 @@ #include #include -#include "esp_libc.h" #include "esp_misc.h" #include "esp_wifi.h" #include "esp_softap.h" diff --git a/include/espressif/esp_libc.h b/include/espressif/esp_libc.h deleted file mode 100644 index 963fec5..0000000 --- a/include/espressif/esp_libc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2010 - 2011 Espressif System - * - */ - -#ifndef __ESP_LIBC_H__ -#define __ESP_LIBC_H__ - -char *strcpy(char *dst, const char *src); -char *strncpy(char *dst, const char *src, size_t n); -int strcmp(const char *s1, const char *s2); -int strncmp(const char *s1, const char *s2, size_t n); -size_t strlen(const char *s); -char *strstr(const char *s1, const char *s2); -char *strcat(char *dst, const char *src); -char *strncat(char *dst, const char *src, size_t count); -size_t strspn(const char *s, const char *accept); -size_t strcspn(const char *s, const char *reject); -char *strtok_r(char *s, const char *delim, char **ptrptr); -char *strtok(char *s, const char *delim); -char *strrchr(const char *s, int c); -char *strdup(const char *s); -char *strchr(const char *s, int c); -long strtol(const char *str, char **endptr, int base); - -void bzero(void *s, size_t n); - -void *memcpy(void *dst, const void *src, size_t n); -void *memset(void *dst, int c, size_t n); -int memcmp(const void *m1, const void *m2, size_t n); -void *memmove(void *dst, const void *src, size_t n); - -int rand_r(unsigned int *seed); -int rand(void); -void srand(unsigned int i); - -int printf(const char *format, ...); -int sprintf(char *out, const char *format, ...); -int snprintf(char *buf, unsigned int count, const char *format, ...); -int puts(const char *str); -int putchar(int c); - -void *malloc(size_t n); -void free(void *p); -void *calloc(size_t c, size_t n); -void *zalloc(size_t n); -void *realloc(void *p, size_t n); - -int atoi(const char *s); -long atol(const char *s); - -/* NOTE: don't use printf_opt in irq handler, for test */ -#define printf_opt(fmt, ...) do { \ - static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \ - printf(flash_str, ##__VA_ARGS__); \ - } while(0) - -/* NOTE: don't use printf_opt in irq handler, for test */ -#define sprintf_opt(out, fmt, ...) do { \ - static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \ - sprintf(out, flash_str, ##__VA_ARGS__); \ - } while(0) - -#endif /* __LIBC_H__ */ diff --git a/lib/libmain.remove b/lib/libmain.remove new file mode 100644 index 0000000..8e95bd6 --- /dev/null +++ b/lib/libmain.remove @@ -0,0 +1,3 @@ +# Object files to be removed from libmain +printf-stdarg.o +libc.o \ No newline at end of file diff --git a/lib/libnet80211.remove b/lib/libnet80211.remove new file mode 100644 index 0000000..e69de29 diff --git a/lib/libphy.remove b/lib/libphy.remove new file mode 100644 index 0000000..e69de29 diff --git a/lib/libpp.remove b/lib/libpp.remove new file mode 100644 index 0000000..e69de29 diff --git a/lib/libwpa.remove b/lib/libwpa.remove new file mode 100644 index 0000000..e69de29