Skip to content

Commit c412a0c

Browse files
committed
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.
1 parent 3b20e4b commit c412a0c

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

EthernetInterface.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mbed.h"
1818
#include "EthernetInterface.h"
1919
#include "NetworkStack.h"
20+
#include "SingletonPtr.h"
2021

2122
#include "eth_arch.h"
2223
#include "lwip/opt.h"
@@ -29,7 +30,7 @@
2930

3031

3132
/* Predeclared LWIPStack class */
32-
static class LWIPStack : public NetworkStack
33+
class LWIPStack : public NetworkStack
3334
{
3435
virtual const char *get_ip_address();
3536
virtual int socket_open(void **handle, nsapi_protocol_t proto);
@@ -44,7 +45,9 @@ static class LWIPStack : public NetworkStack
4445
virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
4546
virtual int setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen);
4647
virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
47-
} lwip_stack;
48+
};
49+
50+
static SingletonPtr<LWIPStack> lwip_stack;
4851

4952

5053
/* Static arena of sockets */
@@ -108,26 +111,26 @@ static struct netif lwip_netif;
108111
static char lwip_ip_addr[NSAPI_IP_SIZE] = "\0";
109112
static char lwip_mac_addr[NSAPI_MAC_SIZE] = "\0";
110113

111-
static Semaphore lwip_tcpip_inited(0);
114+
static SingletonPtr<Semaphore> lwip_tcpip_inited;
112115
static void lwip_tcpip_init_irq(void *)
113116
{
114-
lwip_tcpip_inited.release();
117+
lwip_tcpip_inited->release();
115118
}
116119

117-
static Semaphore lwip_netif_linked(0);
120+
static SingletonPtr<Semaphore> lwip_netif_linked;
118121
static void lwip_netif_link_irq(struct netif *lwip_netif)
119122
{
120123
if (netif_is_link_up(lwip_netif)) {
121-
lwip_netif_linked.release();
124+
lwip_netif_linked->release();
122125
}
123126
}
124127

125-
static Semaphore lwip_netif_up(0);
128+
static SingletonPtr<Semaphore> lwip_netif_up;
126129
static void lwip_netif_status_irq(struct netif *lwip_netif)
127130
{
128131
if (netif_is_up(lwip_netif)) {
129132
strcpy(lwip_ip_addr, inet_ntoa(lwip_netif->ip_addr));
130-
lwip_netif_up.release();
133+
lwip_netif_up->release();
131134
}
132135
}
133136

@@ -166,7 +169,7 @@ static int lwip_init()
166169
lwip_set_mac_address();
167170

168171
tcpip_init(lwip_tcpip_init_irq, NULL);
169-
lwip_tcpip_inited.wait();
172+
lwip_tcpip_inited->wait();
170173

171174
memset(&lwip_netif, 0, sizeof lwip_netif);
172175
netif_add(&lwip_netif, 0, 0, 0, NULL, eth_arch_enetif_init, tcpip_input);
@@ -184,7 +187,7 @@ static int lwip_init()
184187

185188
// Wait for an IP Address
186189
// -1: error, 0: timeout
187-
if (lwip_netif_up.wait(15000) <= 0) {
190+
if (lwip_netif_up->wait(15000) <= 0) {
188191
return NSAPI_ERROR_DHCP_FAILURE;
189192
}
190193

@@ -457,5 +460,5 @@ const char *EthernetInterface::get_mac_address()
457460

458461
NetworkStack *EthernetInterface::get_stack()
459462
{
460-
return &lwip_stack;
463+
return lwip_stack.get();
461464
}

0 commit comments

Comments
 (0)