summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/setjmp/___setjmp.x86-64.s (renamed from src/setjmp/__setjmp.x86-64.s)0
-rw-r--r--src/setjmp/__setjmp.c41
-rw-r--r--src/setjmp/__setjmp_h.c3
-rw-r--r--src/setjmp/_setjmp.h58
-rw-r--r--src/setjmp/longjmp.c2
-rw-r--r--src/setjmp/setjmp.c35
6 files changed, 111 insertions, 28 deletions
diff --git a/src/setjmp/__setjmp.x86-64.s b/src/setjmp/___setjmp.x86-64.s
index 00b139b1..00b139b1 100644
--- a/src/setjmp/__setjmp.x86-64.s
+++ b/src/setjmp/___setjmp.x86-64.s
diff --git a/src/setjmp/__setjmp.c b/src/setjmp/__setjmp.c
new file mode 100644
index 00000000..cbd6a144
--- /dev/null
+++ b/src/setjmp/__setjmp.c
@@ -0,0 +1,41 @@
+#include <setjmp.h>
+#include <string.h>
+#include "_setjmp.h"
+#include "_safety.h"
+
+/** save program state **/
+
+int __setjmp(jmp_buf env)
+{
+ int ret = 0;
+ extern int ___setjmp(jmp_buf);
+ SIGNAL_SAFE(0);
+ memset(env, 0, sizeof(jmp_buf));
+ ret = ___setjmp(env);
+ ADD_JMP_BUF(env);
+ return ret;
+}
+
+CHECK_1(int, 0, __setjmp, jmp_buf)
+
+/***
+saves the current state of the calling environment
+in the TYPEDEF(jmp_buf) ARGUMENT(env).
+***/
+
+/*
+RETURN(0, the environment has been saved by THIS())
+RETURN(NONZERO, the environment has been restored by FUNCTION(longjmp))
+
+CONSTRAINT: entire controlling expression of a selection or iteration statement
+CONSTRAINT: one operand of a relational or equality operator which is the entire controlling expression of a selction or iteration statement
+CONSTRAINT: the operand of a unary ! as the entire controlling expression of a selection or iteration statement
+CONSTRAINT: an entire expression statement
+
+UNSPECIFIED(Whether THIS() is a macro or identifier with external linkage)
+
+UNDEFINED(A macro definition of THIS() is suppressed in order to access an actual function)
+UNDEFINED(A program defines an external identifier named LITERAL(setjmp))
+
+STDC(1)
+*/
diff --git a/src/setjmp/__setjmp_h.c b/src/setjmp/__setjmp_h.c
new file mode 100644
index 00000000..b4d0dcd6
--- /dev/null
+++ b/src/setjmp/__setjmp_h.c
@@ -0,0 +1,3 @@
+#include "_setjmp.h"
+
+struct __setjmp_h __setjmp_h;
diff --git a/src/setjmp/_setjmp.h b/src/setjmp/_setjmp.h
new file mode 100644
index 00000000..1bf19fe6
--- /dev/null
+++ b/src/setjmp/_setjmp.h
@@ -0,0 +1,58 @@
+#ifndef ___SETJMP_H__
+#define ___SETJMP_H__
+
+#include <setjmp.h>
+#include "_safety.h"
+
+struct __valid_jmp_buf {
+};
+
+extern struct __setjmp_h {
+ struct valid_jmp_buf {
+ unsigned long int *buf;
+ unsigned long int sum;
+ } *valid;
+ size_t nvalid;
+} __setjmp_h;
+
+
+#ifndef NDEBUG
+static inline unsigned long int jmp_sum(jmp_buf env)
+{
+ long unsigned int ret = 0;
+ for (size_t i = 0; i < sizeof(jmp_buf) / sizeof(unsigned long int); i++) {
+ ret ^= env[i];
+ }
+ return ret;
+}
+
+#define ADD_JMP_BUF(__env) do { \
+ struct valid_jmp_buf __v = { \
+ (unsigned long int *)(__env), \
+ jmp_sum(__env), \
+ }; \
+ ADD_PREV(__v, __setjmp_h.valid, __setjmp_h.nvalid); \
+} while (0)
+
+#define ASSERT_JMP_BUF(__env) do { \
+ int __found = 0; \
+ for (size_t __i = 0; __i < __setjmp_h.nvalid; __i++) { \
+ if (__setjmp_h.valid[__i].buf == (unsigned long int *)(__env)) { \
+ if (jmp_sum(__env) != __setjmp_h.valid[__i].sum) { \
+ UNDEFINED("jmp_buf has been modified!"); \
+ } \
+ __found = 1; \
+ break; \
+ } \
+ } \
+ if (!__found) { \
+ UNDEFINED("In call to longjmp(): Provided jmp_buf was not returned by a previous call to setjmp()"); \
+ } \
+} while (0)
+
+#else
+#define ADD_JMP_BUF(__env) (void)(__env)
+#define ASSERT_JMP_BUF(__env) (void)(__env)
+#endif
+
+#endif
diff --git a/src/setjmp/longjmp.c b/src/setjmp/longjmp.c
index 117910fc..2208aec7 100644
--- a/src/setjmp/longjmp.c
+++ b/src/setjmp/longjmp.c
@@ -1,4 +1,5 @@
#include <setjmp.h>
+#include "_setjmp.h"
#include "_safety.h"
/** restore calling environment **/
@@ -7,6 +8,7 @@ _Noreturn void longjmp(jmp_buf env, int val)
{
extern _Noreturn void ___longjmp(jmp_buf);
SIGNAL_SAFE(0);
+ ASSERT_JMP_BUF(env);
/* use val if nonzero, otherwise 1 */
env[0] = val ? val : 1;
diff --git a/src/setjmp/setjmp.c b/src/setjmp/setjmp.c
index 091f0993..3c8a199c 100644
--- a/src/setjmp/setjmp.c
+++ b/src/setjmp/setjmp.c
@@ -1,37 +1,16 @@
#include <setjmp.h>
-#include <string.h>
#include "_safety.h"
-/** save program state **/
+#undef setjmp
-int setjmp(jmp_buf env)
+int setjmp(jmp_buf jb)
{
- extern int ___setjmp(jmp_buf);
- SIGNAL_SAFE(0);
- memset(env, 0, sizeof(jmp_buf));
- return ___setjmp(env);
+ (void)jb;
+ UNDEFINED("The setjmp() macro has been suppressed to access an actual function");
+ return 0;
}
-CHECK_1(int, 0, setjmp, jmp_buf)
-
-/***
-saves the current state of the calling environment
-in the TYPEDEF(jmp_buf) ARGUMENT(env).
-***/
-
/*
-RETURN(0, the environment has been saved by THIS())
-RETURN(NONZERO, the environment has been restored by FUNCTION(longjmp))
-
-CONSTRAINT: entire controlling expression of a selection or iteration statement
-CONSTRAINT: one operand of a relational or equality operator which is the entire controlling expression of a selction or iteration statement
-CONSTRAINT: the operand of a unary ! as the entire controlling expression of a selection or iteration statement
-CONSTRAINT: an entire expression statement
-
-UNSPECIFIED(Whether THIS() is a macro or identifier with external linkage)
-
-UNDEFINED(A macro definition of THIS() is suppressed in order to access an actual function)
-UNDEFINED(A program defines an external identifier named LITERAL(setjmp))
-
-STDC(1)
+SIGNAL_SAFE(0)
+STDC(0)
*/