diff --git a/jerry-libc/include/stdlib.h b/jerry-libc/include/stdlib.h index c88e5a765c..c9cfe6a17d 100644 --- a/jerry-libc/include/stdlib.h +++ b/jerry-libc/include/stdlib.h @@ -23,5 +23,6 @@ #endif /* !__cplusplus */ extern EXTERN_C void __attribute__ ((noreturn)) exit (int); +extern EXTERN_C void __attribute__ ((noreturn)) abort (void); #endif /* !JERRY_LIBC_STDLIB_H */ diff --git a/jerry-libc/jerry-libc-defs.h b/jerry-libc/jerry-libc-defs.h index a3ed58950e..38ce12a52b 100644 --- a/jerry-libc/jerry-libc-defs.h +++ b/jerry-libc/jerry-libc-defs.h @@ -28,11 +28,6 @@ #define __attr_noreturn___ __attribute__((noreturn)) #define __attr_noinline___ __attribute__((noinline)) -/** - * Constants - */ -#define LIBC_FATAL_ERROR_EXIT_CODE (2) - /** * Assertions */ diff --git a/jerry-libc/jerry-libc-fatals.c b/jerry-libc/jerry-libc-fatals.c index eb2f11c7f0..e741e41659 100644 --- a/jerry-libc/jerry-libc-fatals.c +++ b/jerry-libc/jerry-libc-fatals.c @@ -41,5 +41,5 @@ libc_fatal (const char *msg, /**< fatal error description */ msg, function_name, file_name, line_number); } - exit (LIBC_FATAL_ERROR_EXIT_CODE); + abort (); } /* libc_fatal */ diff --git a/jerry-libc/jerry-libc.c b/jerry-libc/jerry-libc.c index bac7185860..78681580a0 100644 --- a/jerry-libc/jerry-libc.c +++ b/jerry-libc/jerry-libc.c @@ -31,8 +31,6 @@ FILE *stdin = (FILE*) 0; FILE *stdout = (FILE*) 1; FILE *stderr = (FILE*) 2; -LIBC_UNREACHABLE_STUB_FOR (void abort (void)) - #ifdef __GNUC__ /* * Making GCC not to replace: diff --git a/jerry-libc/target/linux/asm_arm.h b/jerry-libc/target/linux/asm_arm.h index 4598a424c8..c1ae263ee3 100644 --- a/jerry-libc/target/linux/asm_arm.h +++ b/jerry-libc/target/linux/asm_arm.h @@ -16,6 +16,19 @@ #ifndef ASM_ARM_H #define ASM_ARM_H +/* + * mov syscall_no (%r0) -> %r7 + * svc #0 + */ +#define SYSCALL_0 \ + push {r4-r12, lr}; \ + \ + mov r7, r0; \ + \ + svc #0; \ + \ + pop {r4-r12, pc}; + /* * mov syscall_no (%r0) -> %r7 * mov arg1 (%r1) -> %r0 diff --git a/jerry-libc/target/linux/asm_x64.h b/jerry-libc/target/linux/asm_x64.h index ae4b74f789..e709199f8e 100644 --- a/jerry-libc/target/linux/asm_x64.h +++ b/jerry-libc/target/linux/asm_x64.h @@ -16,6 +16,15 @@ #ifndef ASM_X64_H #define ASM_X64_H +/* + * mov syscall_no (%rdi) -> %rax + * syscall + */ +#define SYSCALL_0 \ + mov %rdi, %rax; \ + syscall; \ + ret; + /* * mov syscall_no (%rdi) -> %rax * mov arg1 (%rsi) -> %rdi diff --git a/jerry-libc/target/linux/asm_x86.h b/jerry-libc/target/linux/asm_x86.h index c4dcefceed..2370a3904a 100644 --- a/jerry-libc/target/linux/asm_x86.h +++ b/jerry-libc/target/linux/asm_x86.h @@ -16,6 +16,22 @@ #ifndef ASM_X86_H #define ASM_X86_H +/* + * mov syscall_no -> %eax + * int $0x80 + * mov %eax -> ret + */ +#define SYSCALL_0 \ + push %edi; \ + push %esi; \ + push %ebx; \ + mov 0x10 (%esp), %eax; \ + int $0x80; \ + pop %ebx; \ + pop %esi; \ + pop %edi; \ + ret; + /* * mov syscall_no -> %eax * mov arg1 -> %ebx diff --git a/jerry-libc/target/linux/jerry-asm.S b/jerry-libc/target/linux/jerry-asm.S index 6162650b05..69fc3c74b9 100644 --- a/jerry-libc/target/linux/jerry-asm.S +++ b/jerry-libc/target/linux/jerry-asm.S @@ -14,6 +14,12 @@ _start: _START .size _start, . - _start +.global syscall_0_asm +.type syscall_0_asm, %function +syscall_0_asm: + SYSCALL_0 +.size syscall_0_asm, . - syscall_0_asm + .global syscall_1_asm .type syscall_1_asm, %function syscall_1_asm: diff --git a/jerry-libc/target/linux/jerry-libc-target.c b/jerry-libc/target/linux/jerry-libc-target.c index 7de754a5cf..53c20791fc 100644 --- a/jerry-libc/target/linux/jerry-libc-target.c +++ b/jerry-libc/target/linux/jerry-libc-target.c @@ -48,17 +48,34 @@ LIBC_UNREACHABLE_STUB_FOR (int raise (int sig_no __attr_unused___)) #define LIBC_EXIT_ON_ERROR(syscall_ret_val) \ if ((syscall_ret_val) < 0) \ { \ - libc_fatal ("Syscall successful", __FILE__, __FUNCTION__, __LINE__); \ + libc_fatal ("Syscall", __FILE__, __FUNCTION__, __LINE__); \ } +static long int syscall_0 (long int syscall_no); static long int syscall_1 (long int syscall_no, long int arg1); static long int syscall_2 (long int syscall_no, long int arg1, long int arg2); static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int arg3); +extern long int syscall_0_asm (long int syscall_no); extern long int syscall_1_asm (long int syscall_no, long int arg1); extern long int syscall_2_asm (long int syscall_no, long int arg1, long int arg2); extern long int syscall_3_asm (long int syscall_no, long int arg1, long int arg2, long int arg3); +/** + * System call with no argument. + * + * @return syscall's return value + */ +static __attr_noinline___ long int +syscall_0 (long int syscall_no) /**< syscall number */ +{ + long int ret = syscall_0_asm (syscall_no); + + LIBC_EXIT_ON_ERROR (ret); + + return ret; +} /* syscall_0 */ + /** * System call with one argument. * @@ -153,6 +170,25 @@ exit (int status) /**< status code */ } } /* exit */ +/** + * Abort current process, producing an abnormal program termination. + * The function raises the SIGABRT signal. + */ +void __attr_noreturn___ __attr_used___ +abort (void) +{ + syscall_1 (__NR_close, (long int)stdin); + syscall_1 (__NR_close, (long int)stdout); + syscall_1 (__NR_close, (long int)stderr); + + syscall_2 (__NR_kill, syscall_0 (__NR_getpid), SIGABRT); + + while (true) + { + /* unreachable */ + } +} /* abort */ + /** * fopen * diff --git a/jerry-libc/target/mcu-stubs/jerry-libc-target.c b/jerry-libc/target/mcu-stubs/jerry-libc-target.c index fea7fd1d91..893151f609 100644 --- a/jerry-libc/target/mcu-stubs/jerry-libc-target.c +++ b/jerry-libc/target/mcu-stubs/jerry-libc-target.c @@ -38,6 +38,15 @@ exit (int status __attr_unused___) } } /* exit */ +/** abort - cause abnormal process termination */ +void __attr_noreturn___ __attr_used___ +abort (void) +{ + while (true) + { + } +} /* abort */ + /** * fwrite *