Skip to content

Commit 41420bf

Browse files
committed
stdlib: Add pico version of __cxa_atexit
This is required for C++ applications. Signed-off-by: Keith Packard <keithp@keithp.com>
1 parent 4d2ad0d commit 41420bf

File tree

5 files changed

+136
-23
lines changed

5 files changed

+136
-23
lines changed

newlib/libc/stdlib/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pico_exit_srcs_stdlib = [
6666
'pico-atexit.c',
6767
'pico-exit.c',
6868
'pico-onexit.c',
69+
'pico-cxa-atexit.c',
6970
]
7071

7172
newlib_exit_srcs_stdlib = [

newlib/libc/stdlib/pico-atexit.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,11 @@
3434
*/
3535

3636
#include <stdlib.h>
37-
38-
static void __atexit_call(int status, void *arg)
39-
{
40-
void (*func)(void) = arg;
41-
(*func)();
42-
}
37+
#include "pico-onexit.h"
4338

4439
int
4540
atexit (void (*func)(void))
4641
{
47-
return on_exit(__atexit_call, func);
42+
union on_exit_func func_u = { .atexit = func };
43+
return _on_exit(PICO_ONEXIT_ATEXIT, func_u, NULL);
4844
}

newlib/libc/stdlib/pico-cxa-atexit.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
*
4+
* Copyright © 2021 Keith Packard
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above
14+
* copyright notice, this list of conditions and the following
15+
* disclaimer in the documentation and/or other materials provided
16+
* with the distribution.
17+
*
18+
* 3. Neither the name of the copyright holder nor the names of its
19+
* contributors may be used to endorse or promote products derived
20+
* from this software without specific prior written permission.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33+
* OF THE POSSIBILITY OF SUCH DAMAGE.
34+
*/
35+
36+
#define _GNU_SOURCE
37+
#include <stdlib.h>
38+
#include "pico-onexit.h"
39+
40+
int
41+
__cxa_atexit (void (*func) (void *), void *arg, void *d)
42+
{
43+
union on_exit_func func_u = { .cxa_atexit = func };
44+
return _on_exit(PICO_ONEXIT_CXA_ATEXIT, func_u, arg);
45+
}

newlib/libc/stdlib/pico-onexit.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,29 @@
3434
*/
3535

3636
#include <stdlib.h>
37+
#include <string.h>
3738
#include <sys/lock.h>
39+
#include "pico-onexit.h"
3840

39-
struct _on_exit {
40-
void (*func)(int, void *);
41-
void *arg;
41+
struct on_exit {
42+
union on_exit_func func;
43+
void *arg;
44+
int kind;
4245
};
4346

44-
static struct _on_exit on_exits[ATEXIT_MAX];
47+
static struct on_exit on_exits[ATEXIT_MAX];
4548

4649
int
47-
on_exit (void (*func)(int, void *),void *arg)
50+
_on_exit(int kind, union on_exit_func func, void *arg)
4851
{
4952
int ret = -1;
5053
int o;
5154
__LIBC_LOCK();
5255
for (o = 0; o < ATEXIT_MAX; o++) {
53-
if (!on_exits[o].func) {
56+
if (on_exits[o].kind == PICO_ONEXIT_EMPTY) {
5457
on_exits[o].func = func;
5558
on_exits[o].arg = arg;
59+
on_exits[o].kind = kind;
5660
ret = 0;
5761
break;
5862
}
@@ -61,26 +65,45 @@ on_exit (void (*func)(int, void *),void *arg)
6165
return ret;
6266
}
6367

68+
int
69+
on_exit (void (*func)(int, void *),void *arg)
70+
{
71+
union on_exit_func func_u = { .on_exit = func };
72+
return _on_exit(PICO_ONEXIT_ONEXIT, func_u, arg);
73+
}
74+
6475
void
6576
__call_exitprocs(int code, void *param)
6677
{
6778
for (;;) {
68-
int i;
69-
void (*func)(int, void *) = NULL;
70-
void *arg;
79+
int i;
80+
union on_exit_func func;
81+
int kind = PICO_ONEXIT_EMPTY;
82+
void *arg;
7183

7284
__LIBC_LOCK();
7385
for (i = ATEXIT_MAX - 1; i >= 0; i--) {
74-
if ((func = on_exits[i].func) != NULL) {
75-
arg = on_exits[i].arg;
76-
on_exits[i].func = NULL;
77-
on_exits[i].arg = NULL;
86+
kind = on_exits[i].kind;
87+
if (kind != PICO_ONEXIT_EMPTY) {
88+
func = on_exits[i].func;
89+
arg = on_exits[i].arg;
90+
memset(&on_exits[i], '\0', sizeof(struct on_exit));
7891
break;
7992
}
8093
}
8194
__LIBC_UNLOCK();
82-
if (func == NULL)
83-
break;
84-
func(code, arg);
95+
switch (kind) {
96+
case PICO_ONEXIT_EMPTY:
97+
return;
98+
case PICO_ONEXIT_ONEXIT:
99+
func.on_exit(code, arg);
100+
break;
101+
case PICO_ONEXIT_ATEXIT:
102+
func.atexit();
103+
break;
104+
case PICO_ONEXIT_CXA_ATEXIT:
105+
func.cxa_atexit(arg);
106+
break;
107+
}
85108
}
86109
}

newlib/libc/stdlib/pico-onexit.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
*
4+
* Copyright © 2021 Keith Packard
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above
14+
* copyright notice, this list of conditions and the following
15+
* disclaimer in the documentation and/or other materials provided
16+
* with the distribution.
17+
*
18+
* 3. Neither the name of the copyright holder nor the names of its
19+
* contributors may be used to endorse or promote products derived
20+
* from this software without specific prior written permission.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33+
* OF THE POSSIBILITY OF SUCH DAMAGE.
34+
*/
35+
36+
#define PICO_ONEXIT_EMPTY 0
37+
#define PICO_ONEXIT_ONEXIT 1
38+
#define PICO_ONEXIT_ATEXIT 2
39+
#define PICO_ONEXIT_CXA_ATEXIT 3
40+
41+
union on_exit_func {
42+
void (*on_exit)(int, void *);
43+
void (*atexit)(void);
44+
void (*cxa_atexit)(void *);
45+
};
46+
47+
int
48+
_on_exit(int kind, union on_exit_func func, void *arg);

0 commit comments

Comments
 (0)