Skip to content

Commit 4b9e458

Browse files
authored
Add support for init/fini arrays to libc (#1725)
The arrays contain the addresses of functions annotated with constructor or destructor attributes. The support is optional, requires FEATURE_INIT_FINI cmake option to be set. As of now, the option is _not_ available in tools/build.py directly, only via `--cmake-param="-DFEATURE_INIT_FINI=ON"`. JerryScript-DCO-1.0-Signed-off-by: Akos Kiss [email protected]
1 parent 950a0f1 commit 4b9e458

File tree

8 files changed

+193
-31
lines changed

8 files changed

+193
-31
lines changed

jerry-libc/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ cmake_minimum_required (VERSION 2.8.12)
1616
set(JERRY_LIBC_NAME jerry-libc)
1717
project (${JERRY_LIBC_NAME} C ASM)
1818

19+
# Optional features
20+
set(FEATURE_INIT_FINI OFF CACHE BOOL "Enable init/fini arrays?")
21+
22+
# Status messages
23+
message(STATUS "FEATURE_INIT_FINI " ${FEATURE_INIT_FINI})
24+
25+
# Checks the optional features
26+
# Enable init/fini arrays
27+
if(FEATURE_INIT_FINI)
28+
set(DEFINES_LIBC ${DEFINES_LIBC} ENABLE_INIT_FINI)
29+
endif()
30+
1931
# Architecture-specific configuration
2032
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
2133
set(DEFINES_LIBC ${DEFINES_LIBC} __TARGET_HOST_x64)

jerry-libc/arch/arm-v7.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,37 @@
8080
\
8181
pop {r4-r12, pc};
8282

83+
#ifdef ENABLE_INIT_FINI
8384
/*
85+
* bl libc_init_array
86+
*/
87+
#define _INIT \
88+
bl libc_init_array;
89+
#else /* !ENABLE_INIT_FINI */
90+
#define _INIT
91+
#endif /* ENABLE_INIT_FINI */
92+
93+
/*
94+
* bl libc_init_array
95+
*
8496
* ldr argc ([sp + 0x0]) -> r0
8597
* add argv (sp + 0x4) -> r1
86-
*
8798
* bl main
8899
*
89100
* bl exit
90101
*
91102
* infinite loop
92103
*/
93-
#define _START \
94-
ldr r0, [sp, #0]; \
95-
add r1, sp, #4; \
96-
bl main; \
97-
\
98-
bl exit; \
99-
1: \
100-
b 1b
104+
#define _START \
105+
_INIT; \
106+
\
107+
ldr r0, [sp, #0]; \
108+
add r1, sp, #4; \
109+
bl main; \
110+
\
111+
bl exit; \
112+
1: \
113+
b 1b;
101114

102115
/**
103116
* If hard-float mode:

jerry-libc/arch/x86-32.h

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,19 @@
9292
pop %edi; \
9393
ret;
9494

95+
#ifdef ENABLE_INIT_FINI
9596
/*
97+
* call libc_init_array
98+
*/
99+
#define _INIT \
100+
call libc_init_array;
101+
#else /* !ENABLE_INIT_FINI */
102+
#define _INIT
103+
#endif /* ENABLE_INIT_FINI */
104+
105+
/*
106+
* call libc_init_array
107+
*
96108
* push argv (%esp + 4)
97109
* push argc ([%esp + 0x4])
98110
*
@@ -103,20 +115,22 @@
103115
*
104116
* infinite loop
105117
*/
106-
#define _START \
107-
mov %esp, %eax; \
108-
add $4, %eax; \
109-
push %eax; \
110-
mov 0x4 (%esp), %eax; \
111-
push %eax; \
112-
\
113-
call main; \
114-
\
115-
push %eax; \
116-
call exit; \
117-
\
118-
1: \
119-
jmp 1b
118+
#define _START \
119+
_INIT; \
120+
\
121+
mov %esp, %eax; \
122+
add $4, %eax; \
123+
push %eax; \
124+
mov 0x4 (%esp), %eax; \
125+
push %eax; \
126+
\
127+
call main; \
128+
\
129+
push %eax; \
130+
call exit; \
131+
\
132+
1: \
133+
jmp 1b;
120134

121135
/*
122136
* setjmp

jerry-libc/arch/x86-64.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,19 @@
6464
syscall; \
6565
ret;
6666

67+
#ifdef ENABLE_INIT_FINI
6768
/*
69+
* call libc_init_array
70+
*/
71+
#define _INIT \
72+
call libc_init_array;
73+
#else /* !ENABLE_INIT_FINI */
74+
#define _INIT
75+
#endif /* ENABLE_INIT_FINI */
76+
77+
/*
78+
* call libc_init_array
79+
*
6880
* mov argc ([%rsp]) -> %rdi
6981
* mov argv (%rsp + 0x8) -> %rsi
7082
*
@@ -76,15 +88,17 @@
7688
* infinite loop
7789
*/
7890
#define _START \
79-
mov (%rsp), %rdi; \
80-
mov %rsp, %rsi; \
81-
add $8, %rsi; \
82-
callq main; \
91+
_INIT; \
92+
\
93+
mov (%rsp), %rdi; \
94+
mov %rsp, %rsi; \
95+
add $8, %rsi; \
96+
callq main; \
8397
\
84-
mov %rax, %rdi; \
85-
callq exit; \
86-
1: \
87-
jmp 1b
98+
mov %rax, %rdi; \
99+
callq exit; \
100+
1: \
101+
jmp 1b;
88102

89103
/*
90104
* setjmp

jerry-libc/jerry-libc-defs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,11 @@
2727
#define __attr_used___ __attribute__((used))
2828
#define __attr_noreturn___ __attribute__((noreturn))
2929
#define __attr_noinline___ __attribute__((noinline))
30+
#define __attr_weak___ __attribute__((weak))
31+
32+
#ifdef ENABLE_INIT_FINI
33+
void libc_init_array (void);
34+
void libc_fini_array (void);
35+
#endif /* ENABLE_INIT_FINI */
3036

3137
#endif /* !DEFS_H */

jerry-libc/jerry-libc-init.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
* This file is based on work under the following copyright and permission
16+
* notice:
17+
*
18+
* Copyright (C) 2004 CodeSourcery, LLC
19+
*
20+
* Permission to use, copy, modify, and distribute this file
21+
* for any purpose is hereby granted without fee, provided that
22+
* the above copyright notice and this notice appears in all
23+
* copies.
24+
*
25+
* This file is distributed WITHOUT ANY WARRANTY; without even the implied
26+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27+
*/
28+
29+
#include "jerry-libc-defs.h"
30+
31+
#ifdef ENABLE_INIT_FINI
32+
33+
/* These magic symbols are provided by the linker. */
34+
typedef void (*libc_init_fn_t) (void);
35+
36+
extern libc_init_fn_t __preinit_array_start[] __attr_weak___;
37+
extern libc_init_fn_t __preinit_array_end[] __attr_weak___;
38+
extern libc_init_fn_t __init_array_start[] __attr_weak___;
39+
extern libc_init_fn_t __init_array_end[] __attr_weak___;
40+
extern libc_init_fn_t __fini_array_start[] __attr_weak___;
41+
extern libc_init_fn_t __fini_array_end[] __attr_weak___;
42+
extern void _init (void);
43+
extern void _fini (void);
44+
45+
46+
/**
47+
* No-op default _init.
48+
*/
49+
void __attr_weak___
50+
_init (void)
51+
{
52+
} /* _init */
53+
54+
/**
55+
* No-op default _fini.
56+
*/
57+
void __attr_weak___
58+
_fini (void)
59+
{
60+
} /* _fini */
61+
62+
/**
63+
* Iterate over all the init routines.
64+
*/
65+
void
66+
libc_init_array (void)
67+
{
68+
size_t count = (size_t) (__preinit_array_end - __preinit_array_start);
69+
for (size_t i = 0; i < count; i++)
70+
{
71+
__preinit_array_start[i] ();
72+
}
73+
74+
_init ();
75+
76+
count = (size_t) (__init_array_end - __init_array_start);
77+
for (size_t i = 0; i < count; i++)
78+
{
79+
__init_array_start[i] ();
80+
}
81+
} /* libc_init_array */
82+
83+
/**
84+
* Run all the cleanup routines.
85+
*/
86+
void
87+
libc_fini_array (void)
88+
{
89+
size_t count = (size_t) (__fini_array_end - __fini_array_start);
90+
for (size_t i = count; i > 0; i--)
91+
{
92+
__fini_array_start[i - 1] ();
93+
}
94+
95+
_fini ();
96+
} /* libc_fini_array */
97+
98+
#endif /* ENABLE_INIT_FINI */

jerry-libc/target/posix/jerry-libc-target.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int
5151
void __attr_noreturn___ __attr_used___
5252
exit (int status) /**< status code */
5353
{
54+
#ifdef ENABLE_INIT_FINI
55+
libc_fini_array ();
56+
#endif /* ENABLE_INIT_FINI */
57+
5458
syscall_1 (SYSCALL_NO (close), (long int) stdin);
5559
syscall_1 (SYSCALL_NO (close), (long int) stdout);
5660
syscall_1 (SYSCALL_NO (close), (long int) stderr);

tools/cppcheck/suppressions-list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
wrongmathcall:tests/unit/test-libm.inc.h
22
variableScope:jerry-libm/*.c
33
invalidPointerCast:jerry-libm/*.c
4+
arithOperationsOnVoidPointer:jerry-libc/*.c

0 commit comments

Comments
 (0)