| #ifndef HOST_GCC |
| |
| #include <stdint.h> |
| #include <irt_syscalls.h> |
| |
| typedef void (*irt_exit_t)(int status); |
| typedef size_t (*irt_query_t)(const char* interface_ident, void* table, size_t tablesize); |
| typedef int (*irt_write_t)(int fd, const void* buf, size_t count, size_t* nwrote); |
| |
| static irt_query_t s_query; |
| static irt_exit_t s_exit; |
| static irt_write_t s_write; |
| |
| |
| #define AT_NULL 0 |
| #define AT_SYSINFO 32 |
| void _init_basic(uintptr_t* auxv) { |
| for (; *auxv != AT_NULL; auxv += 2) { |
| if (*auxv == AT_SYSINFO) { |
| s_query = (irt_query_t) auxv[1]; |
| break; |
| } |
| } |
| |
| if (s_query) { |
| struct nacl_irt_basic basic; |
| s_query(NACL_IRT_BASIC_v0_1, &basic, sizeof(basic)); |
| s_exit = basic.exit; |
| |
| struct nacl_irt_dev_fdio fdio; |
| do { |
| if (s_query(NACL_IRT_DEV_FDIO_v0_3, &fdio, sizeof(struct nacl_irt_dev_fdio)) |
| == sizeof(struct nacl_irt_dev_fdio)) break; |
| if (s_query(NACL_IRT_DEV_FDIO_v0_2, &fdio, sizeof(struct nacl_irt_dev_fdio_v0_2)) |
| == sizeof(struct nacl_irt_dev_fdio_v0_2)) break; |
| if (s_query(NACL_IRT_DEV_FDIO_v0_1, &fdio, sizeof(struct nacl_irt_fdio)) |
| == sizeof(struct nacl_irt_fdio)) break; |
| } while (0); |
| s_write = fdio.write; |
| } |
| } |
| |
| void exit(int val) { |
| s_exit(val); |
| while(1); |
| } |
| |
| int puts(const char *str) { |
| size_t len = 0; |
| for (;str[len];len++); |
| |
| size_t written; |
| s_write(1, str, len, &written); |
| return written; |
| } |
| |
| int main(int argc, char* argv[]); |
| |
| void _start(unsigned **info) { |
| int envc = (int)info[1]; |
| int argc = (int)info[2]; |
| char **argv = (char**)&info[3]; |
| char **envp = argv + argc + 1; |
| unsigned *auxv = (unsigned *)(envp + envc + 1); |
| static char buf[sizeof(void*) * 7]; |
| |
| _init_basic(auxv); |
| exit(main(argc, argv)); |
| } |
| |
| #endif |