diff options
author | Sung-Jae Lee <sjlee@mail.com> | 2015-09-15 09:43:03 +0900 |
---|---|---|
committer | Sung-Jae Lee <sjlee@mail.com> | 2015-09-15 10:31:57 +0900 |
commit | 01f66f7b04afdc6355a78c85557656ac33b23418 (patch) | |
tree | 7fd12a1fe6347bfce9cd58521fd1b345445c6867 /jerry-libc | |
parent | 311cc65b33a150c1eed055f4a96670922d5478ca (diff) |
Enable build on Mac OS X with clang
* Add build target 'darwin'
* Modify compiler options to work with clang
* Support 'jerry-libc' on Mac OS X
For MPU target build, install `gcc-arm-none-eabi` tool chain using `Homebrew` as following.
````
brew tap PX4/homebrew-px4
brew update
brew install gcc-arm-none-eabi
````
https://pixhawk.org/dev/toolchain_installation_mac
JerryScript-DCO-1.0-Signed-off-by: Sung-Jae Lee sjlee@mail.com
Diffstat (limited to 'jerry-libc')
-rw-r--r-- | jerry-libc/CMakeLists.txt | 8 | ||||
-rw-r--r-- | jerry-libc/target/darwin/jerry-asm.S | 56 | ||||
-rw-r--r-- | jerry-libc/target/darwin/jerry-libc-target.c | 386 |
3 files changed, 450 insertions, 0 deletions
diff --git a/jerry-libc/CMakeLists.txt b/jerry-libc/CMakeLists.txt index 19791eff..adbc746a 100644 --- a/jerry-libc/CMakeLists.txt +++ b/jerry-libc/CMakeLists.txt @@ -40,6 +40,8 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}") # Platform-specific # Linux set(DEFINES_LIBC_LINUX __TARGET_HOST) + # Darwin + set(DEFINES_LIBC_DARWIN __TARGET_HOST) # MCU set(DEFINES_LIBC_MCU __TARGET_MCU) # stm32f3 @@ -57,6 +59,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}") # Linux set(INCLUDE_THIRD_PARTY_LINUX ) + # Darwin + set(INCLUDE_THIRD_PARTY_DARWIN ) + # MCU # STM32F3 set(INCLUDE_THIRD_PARTY_MCU_STM32F3 @@ -74,6 +79,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}") # Linux file(GLOB SOURCE_LIBC_LINUX target/linux/*.c target/linux/*.S) + # Darwin + file(GLOB SOURCE_LIBC_DARWIN target/darwin/*.c target/darwin/*.S) + # MCU # stm32f3 file(GLOB SOURCE_LIBC_MCU_STM32F3 target/mcu-stubs/*.c target/mcu-stubs/*.S) diff --git a/jerry-libc/target/darwin/jerry-asm.S b/jerry-libc/target/darwin/jerry-asm.S new file mode 100644 index 00000000..7219f4fe --- /dev/null +++ b/jerry-libc/target/darwin/jerry-asm.S @@ -0,0 +1,56 @@ +#ifdef __TARGET_HOST_x64 +# include "arch/x86-64.h" +#elif defined (__TARGET_HOST_x86) +# include "arch/x86-32.h" +#elif defined (__TARGET_HOST_ARMv7) +# include "arch/arm-v7.h" +#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */ +# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7" +#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */ + +.global _start +_start: + _START + +.global syscall_0_asm +syscall_0_asm: + SYSCALL_0 + +.global syscall_1_asm +syscall_1_asm: + SYSCALL_1 + +.global syscall_2_asm +syscall_2_asm: + SYSCALL_2 + +.global syscall_3_asm +syscall_3_asm: + SYSCALL_3 + +/** + * setjmp (jmp_buf env) + * + * See also: + * longjmp + * + * @return 0 - if returns from direct call, + * nonzero - if returns after longjmp. + */ +.global setjmp +setjmp: + _SETJMP + +/** + * longjmp (jmp_buf env, int val) + * + * Note: + * if val is not 0, then it would be returned from setjmp, + * otherwise - 0 would be returned. + * + * See also: + * setjmp + */ +.global longjmp +longjmp: + _LONGJMP diff --git a/jerry-libc/target/darwin/jerry-libc-target.c b/jerry-libc/target/darwin/jerry-libc-target.c new file mode 100644 index 00000000..6004af15 --- /dev/null +++ b/jerry-libc/target/darwin/jerry-libc-target.c @@ -0,0 +1,386 @@ +/* Copyright 2014-2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Jerry libc platform-specific functions darwin implementation + */ + +#include <ctype.h> +#include <fcntl.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/syscall.h> +#include <sys/resource.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "jerry-libc-defs.h" + +LIBC_UNREACHABLE_STUB_FOR (int raise (int sig_no __attr_unused___)) + +/** + * Exit program with ERR_SYSCALL if syscall_ret_val is negative + */ +#define LIBC_EXIT_ON_ERROR(syscall_ret_val) \ + if ((syscall_ret_val) < 0) \ +{ \ + libc_fatal ("Syscall", __FILE__, __func__, __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. + * + * @return syscall's return value + */ +static __attr_noinline___ long int +syscall_1 (long int syscall_no, /**< syscall number */ + long int arg1) /**< argument */ +{ + long int ret = syscall_1_asm (syscall_no, arg1); + + LIBC_EXIT_ON_ERROR (ret); + + return ret; +} /* syscall_1 */ + +/** + * System call with two arguments. + * + * @return syscall's return value + */ +static __attr_noinline___ long int +syscall_2 (long int syscall_no, /**< syscall number */ + long int arg1, /**< first argument */ + long int arg2) /**< second argument */ +{ + long int ret = syscall_2_asm (syscall_no, arg1, arg2); + + LIBC_EXIT_ON_ERROR (ret); + + return ret; +} /* syscall_2 */ + +/** + * System call with three arguments. + * + * @return syscall's return value + */ +static __attr_noinline___ long int +syscall_3 (long int syscall_no, /**< syscall number */ + long int arg1, /**< first argument */ + long int arg2, /**< second argument */ + long int arg3) /**< third argument */ +{ + long int ret = syscall_3_asm (syscall_no, arg1, arg2, arg3); + + LIBC_EXIT_ON_ERROR (ret); + + return ret; +} /* syscall_3 */ + +/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */ +int +putchar (int c) +{ + fwrite (&c, 1, sizeof (char), stdout); + + return c; +} /* putchar */ + +/** + * Output specified string + */ +int +puts (const char *s) /**< string to print */ +{ + while (*s) + { + putchar (*s); + + s++; + } + + return 0; +} /* puts */ + +/** + * Exit - cause normal process termination with specified status code + */ +void __attr_noreturn___ __attr_used___ +exit (int status) /**< status code */ +{ + syscall_1 (SYS_close, (long int)stdin); + syscall_1 (SYS_close, (long int)stdout); + syscall_1 (SYS_close, (long int)stderr); + + syscall_1 (SYS_exit, status); + + while (true) + { + /* unreachable */ + } +} /* exit */ + +/** + * Abort current process, producing an abnormal program termination. + * The function raises the SIGABRT signal. + */ +void __attr_noreturn___ __attr_used___ +abort (void) +{ + syscall_1 (SYS_close, (long int)stdin); + syscall_1 (SYS_close, (long int)stdout); + syscall_1 (SYS_close, (long int)stderr); + + syscall_2 (SYS_kill, syscall_0 (SYS_getpid), SIGABRT); + + while (true) + { + /* unreachable */ + } +} /* abort */ + +/** + * fopen + * + * @return FILE pointer - upon successful completion, + * NULL - otherwise + */ +FILE* +fopen (const char *path, /**< file path */ + const char *mode) /**< file open mode */ +{ + bool may_read = false; + bool may_write = false; + bool truncate = false; + bool create_if_not_exist = false; + bool position_at_end = false; + + LIBC_ASSERT (path != NULL && mode != NULL); + LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0'); + + switch (mode[0]) + { + case 'r': + { + may_read = true; + may_write = (mode[1] == '+'); + break; + } + case 'w': + { + may_write = true; + truncate = true; + create_if_not_exist = true; + may_read = (mode[1] == '+'); + break; + } + case 'a': + { + may_write = true; + position_at_end = true; + create_if_not_exist = true; + if (mode[1] == '+') + { + /* Not supported */ + LIBC_UNREACHABLE (); + } + break; + } + default: + { + LIBC_UNREACHABLE (); + } + } + + int flags = 0; + int access = S_IRUSR | S_IWUSR; + if (may_read && !may_write) + { + flags = O_RDONLY; + } + else if (!may_read && may_write) + { + flags = O_WRONLY; + } + else + { + LIBC_ASSERT (may_read && may_write); + + flags = O_RDWR; + } + + if (truncate) + { + flags |= O_TRUNC; + } + + if (create_if_not_exist) + { + flags |= O_CREAT; + } + + if (position_at_end) + { + flags |= O_APPEND; + } + + long int ret = syscall_3 (SYS_open, (long int) path, flags, access); + + return (void*) (uintptr_t) (ret); +} /* fopen */ + +/** + * The rewind () function sets the file position indicator + * for the stream pointed to by STREAM to the beginning of the file. + */ +void +rewind (FILE *stream) /**< stream pointer */ +{ + syscall_3 (SYS_lseek, (long int) stream, 0, SEEK_SET); +} /* rewind */ + +/** + * fclose + * + * @return 0 - upon successful completion, + * non-zero value - otherwise. + */ +int +fclose (FILE *fp) /**< stream pointer */ +{ + syscall_2 (SYS_close, (long int)fp, 0); + + return 0; +} /* fclose */ + +/** + * fseek + */ +int +fseek (FILE * fp, /**< stream pointer */ + long offset, /**< offset */ + int whence) /**< specifies position type + * to add offset to */ +{ + syscall_3 (SYS_lseek, (long int)fp, offset, whence); + + return 0; +} /* fseek */ + +/** + * ftell + */ +long +ftell (FILE * fp) /**< stream pointer */ +{ + long int ret = syscall_3 (SYS_lseek, (long int)fp, 0, SEEK_CUR); + + return ret; +} /* ftell */ + +/** + * fread + * + * @return number of elements read + */ +size_t +fread (void *ptr, /**< address of buffer to read to */ + size_t size, /**< size of elements to read */ + size_t nmemb, /**< number of elements to read */ + FILE *stream) /**< stream pointer */ +{ + long int ret; + size_t bytes_read = 0; + + if (size == 0) + { + return 0; + } + + do + { + ret = syscall_3 (SYS_read, + (long int) stream, + (long int) ((uint8_t*) ptr + bytes_read), + (long int) (size * nmemb - bytes_read)); + + bytes_read += (size_t)ret; + } + while (bytes_read != size * nmemb && ret != 0); + + return bytes_read / size; +} /* fread */ + +/** + * fwrite + * + * @return number of elements written + */ +size_t +fwrite (const void *ptr, /**< data to write */ + size_t size, /**< size of elements to write */ + size_t nmemb, /**< number of elements */ + FILE *stream) /**< stream pointer */ +{ + size_t bytes_written = 0; + + if (size == 0) + { + return 0; + } + + do + { + long int ret = syscall_3 (SYS_write, + (long int) stream, + (long int) ((uint8_t*) ptr + bytes_written), + (long int) (size * nmemb - bytes_written)); + + bytes_written += (size_t)ret; + } + while (bytes_written != size * nmemb); + + return bytes_written / size; +} /* fwrite */ + |