From c412a0cfdeebffc03ad23c7c086ef9e88e82467a Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 18 Jul 2016 12:40:48 -0500 Subject: [PATCH] Adopted SingletonPtr to avoid vtable leak in lwip Globally declared C++ classes with vtables are not gced by current toolchains, even if the C++ class contains no member variables and no constructor. This causes all of lwip to be dragged into resulting binaries, even if lwip is not accessed. Adoption of the SingletonPtr class in lwip allows us to workaround this issue. --- EthernetInterface.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index 5457354796..896a7e22c0 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -17,6 +17,7 @@ #include "mbed.h" #include "EthernetInterface.h" #include "NetworkStack.h" +#include "SingletonPtr.h" #include "eth_arch.h" #include "lwip/opt.h" @@ -29,7 +30,7 @@ /* Predeclared LWIPStack class */ -static class LWIPStack : public NetworkStack +class LWIPStack : public NetworkStack { virtual const char *get_ip_address(); virtual int socket_open(void **handle, nsapi_protocol_t proto); @@ -44,7 +45,9 @@ static class LWIPStack : public NetworkStack virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size); virtual int setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen); virtual void socket_attach(void *handle, void (*callback)(void *), void *data); -} lwip_stack; +}; + +static SingletonPtr lwip_stack; /* Static arena of sockets */ @@ -108,26 +111,26 @@ static struct netif lwip_netif; static char lwip_ip_addr[NSAPI_IP_SIZE] = "\0"; static char lwip_mac_addr[NSAPI_MAC_SIZE] = "\0"; -static Semaphore lwip_tcpip_inited(0); +static SingletonPtr lwip_tcpip_inited; static void lwip_tcpip_init_irq(void *) { - lwip_tcpip_inited.release(); + lwip_tcpip_inited->release(); } -static Semaphore lwip_netif_linked(0); +static SingletonPtr lwip_netif_linked; static void lwip_netif_link_irq(struct netif *lwip_netif) { if (netif_is_link_up(lwip_netif)) { - lwip_netif_linked.release(); + lwip_netif_linked->release(); } } -static Semaphore lwip_netif_up(0); +static SingletonPtr lwip_netif_up; static void lwip_netif_status_irq(struct netif *lwip_netif) { if (netif_is_up(lwip_netif)) { strcpy(lwip_ip_addr, inet_ntoa(lwip_netif->ip_addr)); - lwip_netif_up.release(); + lwip_netif_up->release(); } } @@ -166,7 +169,7 @@ static int lwip_init() lwip_set_mac_address(); tcpip_init(lwip_tcpip_init_irq, NULL); - lwip_tcpip_inited.wait(); + lwip_tcpip_inited->wait(); memset(&lwip_netif, 0, sizeof lwip_netif); netif_add(&lwip_netif, 0, 0, 0, NULL, eth_arch_enetif_init, tcpip_input); @@ -184,7 +187,7 @@ static int lwip_init() // Wait for an IP Address // -1: error, 0: timeout - if (lwip_netif_up.wait(15000) <= 0) { + if (lwip_netif_up->wait(15000) <= 0) { return NSAPI_ERROR_DHCP_FAILURE; } @@ -457,5 +460,5 @@ const char *EthernetInterface::get_mac_address() NetworkStack *EthernetInterface::get_stack() { - return &lwip_stack; + return lwip_stack.get(); }