diff --git a/.vscode/settings.json b/.vscode/settings.json index 36cb05f42..a0047cb00 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -185,7 +185,8 @@ "initializer_list": "c", "spi2.h": "c", "wk2xx.h": "c", - "cwchar": "c" + "cwchar": "c", + "test.h": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": true, diff --git a/mkrtos_knl/knl/ipc.c b/mkrtos_knl/knl/ipc.c index 94415b904..ca90e5591 100755 --- a/mkrtos_knl/knl/ipc.c +++ b/mkrtos_knl/knl/ipc.c @@ -55,7 +55,7 @@ enum ipc_op IPC_BIND, //!< 绑定服务端线程 IPC_UNBIND, //!< 解除绑定 }; -static void wake_up_th(ipc_t *ipc); +static int wake_up_th(ipc_t *ipc); static slist_head_t wait_list; /** @@ -185,12 +185,20 @@ static int add_wait_unlock(ipc_t *ipc, slist_head_t *head, thread_t *th, umword_ * * @param ipc */ -static void wake_up_th(ipc_t *ipc) +static int wake_up_th(ipc_t *ipc) { slist_head_t *mslist = slist_first(&ipc->wait_send); ipc_wait_item_t *item = container_of(mslist, ipc_wait_item_t, node); - thread_ready(item->th, TRUE); + if (thread_get_status(item->th) == THREAD_TODEAD) + { + return -ESHUTDOWN; + } + else + { + thread_ready(item->th, TRUE); + } + return 0; } /** * @brief ipc传输时的数据拷贝 @@ -320,9 +328,16 @@ static int ipc_reply(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag) return ret; } ipc->last_cli_th->msg.tag = tag; - thread_ready(ipc->last_cli_th, TRUE); //!< 直接唤醒接受者 + if (thread_get_status(ipc->last_cli_th) != THREAD_TODEAD) + { + thread_ready(ipc->last_cli_th, TRUE); //!< 直接唤醒接受者 + } + else + { + ret = -EAGAIN; + } spinlock_set(&ipc->lock, status); - return 0; + return ret; } /** @@ -333,19 +348,31 @@ static int ipc_reply(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag) * @param f * @param tag */ -static msg_tag_t ipc_wait(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag) +static msg_tag_t ipc_wait(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t in_tag) { assert(ipc->svr_th == th); umword_t status; + msg_tag_t tag; status = spinlock_lock(&ipc->lock); thread_suspend(th); if (!slist_is_empty(&ipc->wait_send)) { - wake_up_th(ipc); + int ret = wake_up_th(ipc); + + if (-ESHUTDOWN == ret) + { + thread_ready(th, TRUE); + tag = msg_tag_init4(0, 0, 0, -EAGAIN); + } + else + { + preemption(); + tag = th->msg.tag; + } } spinlock_set(&ipc->lock, status); - return th->msg.tag; + return tag; } /** * @brief ipc的系统调用 diff --git a/mkrtos_knl/knl/map.c b/mkrtos_knl/knl/map.c index 7599e3b6b..ebc1fc98f 100755 --- a/mkrtos_knl/knl/map.c +++ b/mkrtos_knl/knl/map.c @@ -107,7 +107,8 @@ void obj_unmap(obj_space_t *obj_space, vpage_t vpage, kobj_del_list_t *del_list) slist_foreach(pos, &kobj->mappable.node, node) { slist_del(&pos->node); - entry->obj = NULL; + pos->obj = NULL; + // slist_init(&pos->node); // 删除一个 kobj->mappable.map_cnt--; if (kobj->mappable.map_cnt <= 0) @@ -124,6 +125,7 @@ void obj_unmap(obj_space_t *obj_space, vpage_t vpage, kobj_del_list_t *del_list) { slist_del(&entry->node); entry->obj = NULL; + // slist_init(&entry->node); // 删除一个 kobj->mappable.map_cnt--; if (kobj->mappable.map_cnt <= 0) diff --git a/mkrtos_user/lib/libc_backend/inc/misc_backend.h b/mkrtos_user/lib/libc_backend/inc/misc_backend.h index 3d62c9930..8992a0428 100644 --- a/mkrtos_user/lib/libc_backend/inc/misc_backend.h +++ b/mkrtos_user/lib/libc_backend/inc/misc_backend.h @@ -1,5 +1,3 @@ #pragma once #include -long be_set_tid_address(va_list ap); -long be_set_thread_area(va_list ap); diff --git a/mkrtos_user/lib/libc_backend/inc/syscall_backend.h b/mkrtos_user/lib/libc_backend/inc/syscall_backend.h index 88bfb4c81..8493e92ad 100644 --- a/mkrtos_user/lib/libc_backend/inc/syscall_backend.h +++ b/mkrtos_user/lib/libc_backend/inc/syscall_backend.h @@ -2,6 +2,7 @@ #include "fs_backend.h" #include "u_types.h" +#include #define ARG_1_BE(ap, arg0, type0) \ do \ @@ -37,6 +38,23 @@ long syscall_backend(long sys_inx, ...); -umword_t be_mmap2(va_list ap); -umword_t be_munmap(va_list ap); -void be_exit(va_list ap); +long be_read(long fd, char *buf, long size); +long be_write(long fd, char *buf, long size); +long be_writev(long fd, const struct iovec *iov, long iovcnt); +long be_ioctl(long fd, long req, void *args); +long be_set_tid_address(int *val); +long be_set_thread_area(void *p); +void be_exit(int code); +umword_t be_munmap(void *start, size_t len); +umword_t be_mmap2(void *start, + size_t len, + long prot, + long flags, + long fd, + long _offset); + +umword_t sys_mmap2(va_list ap); +long sys_set_tid_address(va_list ap); +long sys_set_thread_area(va_list ap); +void sys_exit(va_list ap); +umword_t sys_munmap(va_list ap); diff --git a/mkrtos_user/lib/libc_backend/src/fs_backend.c b/mkrtos_user/lib/libc_backend/src/fs_backend.c index 8587456dd..1131c6f68 100644 --- a/mkrtos_user/lib/libc_backend/src/fs_backend.c +++ b/mkrtos_user/lib/libc_backend/src/fs_backend.c @@ -7,11 +7,11 @@ #include #include #include -static long be_read(long fd, char *buf, long size) +long be_read(long fd, char *buf, long size) { return -ENOSYS; } -static long be_write(long fd, char *buf, long size) +long be_write(long fd, char *buf, long size) { switch (fd) { @@ -25,7 +25,7 @@ static long be_write(long fd, char *buf, long size) } return 0; } -static long be_writev(long fd, const struct iovec *iov, long iovcnt) +long be_writev(long fd, const struct iovec *iov, long iovcnt) { long wlen = 0; for (int i = 0; i < iovcnt; i++) @@ -69,8 +69,9 @@ long sys_be_writev(va_list ap) #undef ARG1 return be_writev(fd, iov, iovcnt); } -static long be_ioctl(long fd, long req, void *args) +long be_ioctl(long fd, long req, void *args) { + /*TODO:*/ return 0; } long sys_be_ioctl(va_list ap) diff --git a/mkrtos_user/lib/libc_backend/src/misc_backend.c b/mkrtos_user/lib/libc_backend/src/misc_backend.c index 961a396c7..ac10a8067 100644 --- a/mkrtos_user/lib/libc_backend/src/misc_backend.c +++ b/mkrtos_user/lib/libc_backend/src/misc_backend.c @@ -6,12 +6,8 @@ #include "u_env.h" #include -long be_set_tid_address(va_list ap) +long be_set_tid_address(int *val) { - int *val; -#define ARG0 int * - ARG_1_BE(ap, val, ARG0); -#undef ARG0 struct pthread *pt = pthread_self(); if (pt) @@ -20,12 +16,18 @@ long be_set_tid_address(va_list ap) } return THREAD_MAIN; } -long be_set_thread_area(va_list ap) + +long sys_set_tid_address(va_list ap) { - void *p; + int *val; #define ARG0 int * - ARG_1_BE(ap, p, ARG0); + ARG_1_BE(ap, val, ARG0); #undef ARG0 + + return be_set_tid_address(val); +} +long be_set_thread_area(void *p) +{ umword_t msg; umword_t len; ipc_msg_t *i_msg; @@ -36,6 +38,14 @@ long be_set_thread_area(va_list ap) i_msg->user[0] = (umword_t)p; return 0; } +long sys_set_thread_area(va_list ap) +{ + void *p; +#define ARG0 int * + ARG_1_BE(ap, p, ARG0); +#undef ARG0 + return be_set_thread_area(p); +} unsigned long get_thread_area(void) { umword_t msg; @@ -47,10 +57,13 @@ unsigned long get_thread_area(void) return i_msg->user[0]; } - -void be_exit(va_list ap) +void be_exit(int code) { /*TODO:暂时先这样*/ task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); ulog_write_str(u_get_global_env()->log_hd, "It shouldn't go here.\n"); +} +void sys_exit(va_list ap) +{ + be_exit(0); } \ No newline at end of file diff --git a/mkrtos_user/lib/libc_backend/src/mm_backend.c b/mkrtos_user/lib/libc_backend/src/mm_backend.c index 2b1246f7c..bbb944d31 100644 --- a/mkrtos_user/lib/libc_backend/src/mm_backend.c +++ b/mkrtos_user/lib/libc_backend/src/mm_backend.c @@ -83,7 +83,7 @@ static void mm_page_free(int st, int nr) pthread_spin_unlock(&lock); } -static int sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t _offset, umword_t *addr) +static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t _offset, umword_t *addr) { if (fd >= 0) { @@ -93,8 +93,24 @@ static int sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t *addr = (umword_t)mm_page_alloc(len / PAGE_SIZE); return 0; } +umword_t be_mmap2(void *start, + size_t len, + long prot, + long flags, + long fd, + long _offset) +{ + umword_t addr; -umword_t be_mmap2(va_list ap) + int ret = _sys_mmap2(start, len, prot, flags, fd, _offset, &addr); + + if (ret < 0) + { + return (umword_t)ret; + } + return addr; +} +umword_t sys_mmap2(va_list ap) { void *start; size_t len; @@ -105,22 +121,10 @@ umword_t be_mmap2(va_list ap) ARG_6_BE(ap, start, void *, len, size_t, prot, long, flags, long, fd, long, _offset, long); - umword_t addr; - - int ret = sys_mmap2(start, len, prot, flags, fd, _offset, &addr); - - if (ret < 0) - { - return (umword_t)ret; - } - return addr; + return be_mmap2(start, len, prot, flags, fd, _offset); } -umword_t be_munmap(va_list ap) +umword_t be_munmap(void *start, size_t len) { - void *start; - size_t len; - - ARG_2_BE(ap, len, size_t, start, void *); app_info_t *info = app_info_get(app_start_addr); assert(info); void *heap_addr = RAM_BASE() + info->i.heap_offset - info->i.data_offset; @@ -128,5 +132,13 @@ umword_t be_munmap(va_list ap) len = ALIGN(len, PAGE_SIZE); // printf("munmap 0x%x, 0x%x.\n", start, len); mm_page_free(((umword_t)(start) - (umword_t)heap_addr) / PAGE_SIZE, len / PAGE_SIZE); - return 0; +} +umword_t sys_munmap(va_list ap) +{ + void *start; + size_t len; + + ARG_2_BE(ap, len, size_t, start, void *); + + return be_munmap(start, len); } diff --git a/mkrtos_user/lib/libc_backend/src/syscall_backend.c b/mkrtos_user/lib/libc_backend/src/syscall_backend.c index c2a6eb8e2..db65de7e6 100644 --- a/mkrtos_user/lib/libc_backend/src/syscall_backend.c +++ b/mkrtos_user/lib/libc_backend/src/syscall_backend.c @@ -1,4 +1,4 @@ - +#ifdef NO_LITTLE_MODE #include "syscall_backend.h" #include "misc_backend.h" #include @@ -8,14 +8,14 @@ typedef long (*sys_call_func)(va_list ap); static const sys_call_func sys_call_list[] = { // TODO: add syscall func pointer. - [SYS_munmap] = be_munmap, - [SYS_mmap2] = be_mmap2, - [SYS_read] = sys_be_read, - [SYS_write] = sys_be_read, - [SYS_writev] = sys_be_writev, - [SYS_ioctl] = sys_be_ioctl, - [SYS_set_tid_address] = be_set_tid_address, - [__ARM_NR_set_tls] = be_set_thread_area, + [SYS_munmap] = sys_munmap, + [SYS_mmap2] = sys_mmap2, + [SYS_read] = sys_be_read, // + [SYS_write] = sys_be_write, // + [SYS_writev] = sys_be_writev, // + [SYS_ioctl] = sys_be_ioctl, // + [SYS_set_tid_address] = sys_set_tid_address, // + [__ARM_NR_set_tls] = sys_set_thread_area, // [SYS_exit] = be_exit, }; @@ -41,3 +41,4 @@ long syscall_backend(long sys_inx, ...) return ret; } +#endif diff --git a/mkrtos_user/lib/mlibc/arch/arm/syscall_arch.h b/mkrtos_user/lib/mlibc/arch/arm/syscall_arch.h index a532bc5f7..833fb2361 100644 --- a/mkrtos_user/lib/mlibc/arch/arm/syscall_arch.h +++ b/mkrtos_user/lib/mlibc/arch/arm/syscall_arch.h @@ -1,6 +1,6 @@ -#define __SYSCALL_LL_E(x) \ -((union { long long ll; long l[2]; }){ .ll = x }).l[0], \ -((union { long long ll; long l[2]; }){ .ll = x }).l[1] +#define __SYSCALL_LL_E(x) \ + ((union { long long ll; long l[2]; }){.ll = x}).l[0], \ + ((union { long long ll; long l[2]; }){.ll = x}).l[1] #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x)) #ifdef __thumb__ @@ -8,19 +8,27 @@ /* Avoid use of r7 in asm constraints when producing thumb code, * since it's reserved as frame pointer and might not be supported. */ #define __ASM____R7__ -#define __asm_syscall(...) do { \ - __asm__ __volatile__ ( "mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1" \ - : "=r"(r0), "=&r"((int){0}) : __VA_ARGS__ : "memory"); \ - return r0; \ +#define __asm_syscall(...) \ + do \ + { \ + __asm__ __volatile__("mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1" \ + : "=r"(r0), "=&r"((int){0}) \ + : __VA_ARGS__ \ + : "memory"); \ + return r0; \ } while (0) #else #define __ASM____R7__ __asm__("r7") -#define __asm_syscall(...) do { \ - __asm__ __volatile__ ( "svc 0" \ - : "=r"(r0) : __VA_ARGS__ : "memory"); \ - return r0; \ +#define __asm_syscall(...) \ + do \ + { \ + __asm__ __volatile__("svc 0" \ + : "=r"(r0) \ + : __VA_ARGS__ \ + : "memory"); \ + return r0; \ } while (0) #endif @@ -35,14 +43,20 @@ #endif // libc backend. +#ifdef NO_LITTLE_MODE extern long syscall_backend(long sys_inx, ...); +#endif static inline long __syscall0(long n) { - // register long r7 __ASM____R7__ = n; - // register long r0 __asm__("r0"); - // __asm_syscall(R7_OPERAND); +// register long r7 __ASM____R7__ = n; +// register long r0 __asm__("r0"); +// __asm_syscall(R7_OPERAND); +#ifdef NO_LITTLE_MODE return syscall_backend(n); +#else + return -ENOSYS; +#endif } static inline long __syscall1(long n, long a) @@ -50,7 +64,11 @@ static inline long __syscall1(long n, long a) // register long r7 __ASM____R7__ = n; // register long r0 __asm__("r0") = a; // __asm_syscall(R7_OPERAND, "0"(r0)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a); +#else + return -ENOSYS; +#endif } static inline long __syscall2(long n, long a, long b) @@ -59,8 +77,11 @@ static inline long __syscall2(long n, long a, long b) // register long r0 __asm__("r0") = a; // register long r1 __asm__("r1") = b; // __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a, b); - +#else + return -ENOSYS; +#endif } static inline long __syscall3(long n, long a, long b, long c) @@ -70,7 +91,11 @@ static inline long __syscall3(long n, long a, long b, long c) // register long r1 __asm__("r1") = b; // register long r2 __asm__("r2") = c; // __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a, b, c); +#else + return -ENOSYS; +#endif } static inline long __syscall4(long n, long a, long b, long c, long d) @@ -81,7 +106,11 @@ static inline long __syscall4(long n, long a, long b, long c, long d) // register long r2 __asm__("r2") = c; // register long r3 __asm__("r3") = d; // __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a, b, c, d); +#else + return -ENOSYS; +#endif } static inline long __syscall5(long n, long a, long b, long c, long d, long e) @@ -93,7 +122,11 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) // register long r3 __asm__("r3") = d; // register long r4 __asm__("r4") = e; // __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a, b, c, d, e); +#else + return -ENOSYS; +#endif } static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) @@ -106,7 +139,11 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo // register long r4 __asm__("r4") = e; // register long r5 __asm__("r5") = f; // __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)); +#ifdef NO_LITTLE_MODE return syscall_backend(n, a, b, c, d, e, f); +#else + return -ENOSYS; +#endif } #define SYSCALL_FADVISE_6_ARG diff --git a/mkrtos_user/lib/mlibc/ldso/dynlink.c b/mkrtos_user/lib/mlibc/ldso/dynlink.c index ceca3c98a..2d2808afd 100644 --- a/mkrtos_user/lib/mlibc/ldso/dynlink.c +++ b/mkrtos_user/lib/mlibc/ldso/dynlink.c @@ -22,7 +22,9 @@ #include "pthread_impl.h" #include "fork_impl.h" #include "dynlink.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif static size_t ldso_page_size; #ifndef PAGE_SIZE #define PAGE_SIZE ldso_page_size @@ -39,13 +41,14 @@ static void error_impl(const char *, ...); static void error_noop(const char *, ...); static void (*error)(const char *, ...) = error_noop; -#define MAXP2(a,b) (-(-(a)&-(b))) -#define ALIGN(x,y) ((x)+(y)-1 & -(y)) +#define MAXP2(a, b) (-(-(a) & -(b))) +#define ALIGN(x, y) ((x) + (y)-1 & -(y)) -#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m))) -#define countof(a) ((sizeof (a))/(sizeof (a)[0])) +#define container_of(p, t, m) ((t *)((char *)(p)-offsetof(t, m))) +#define countof(a) ((sizeof(a)) / (sizeof(a)[0])) -struct debug { +struct debug +{ int ver; void *head; void (*bp)(void); @@ -53,12 +56,14 @@ struct debug { void *base; }; -struct td_index { +struct td_index +{ size_t args[2]; struct td_index *next; }; -struct dso { +struct dso +{ #if DL_FDPIC struct fdpic_loadmap *loadmap; #else @@ -106,7 +111,8 @@ struct dso { #else struct fdpic_loadmap *loadmap; #endif - struct funcdesc { + struct funcdesc + { void *addr; size_t *got; } *funcdescs; @@ -114,14 +120,16 @@ struct dso { char buf[]; }; -struct symdef { +struct symdef +{ Sym *sym; struct dso *dso; }; typedef void (*stage3_func)(size_t *, size_t *); -static struct builtin_tls { +static struct builtin_tls +{ char c; struct pthread pt; void *space[16]; @@ -159,7 +167,7 @@ struct debug *_dl_debug_addr = &debug; extern hidden int __malloc_replaced; -hidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0; +hidden void (*const __init_array_start)(void) = 0, (*const __fini_array_start)(void) = 0; extern hidden void (*const __init_array_end)(void), (*const __fini_array_end)(void); @@ -168,43 +176,51 @@ weak_alias(__fini_array_start, __fini_array_end); static int dl_strcmp(const char *l, const char *r) { - for (; *l==*r && *l; l++, r++); + for (; *l == *r && *l; l++, r++) + ; return *(unsigned char *)l - *(unsigned char *)r; } -#define strcmp(l,r) dl_strcmp(l,r) +#define strcmp(l, r) dl_strcmp(l, r) /* Compute load address for a virtual address in a given dso. */ #if DL_FDPIC static void *laddr(const struct dso *p, size_t v) { - size_t j=0; - if (!p->loadmap) return p->base + v; - for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++); + size_t j = 0; + if (!p->loadmap) + return p->base + v; + for (j = 0; v - p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++) + ; return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); } static void *laddr_pg(const struct dso *p, size_t v) { - size_t j=0; + size_t j = 0; size_t pgsz = PAGE_SIZE; - if (!p->loadmap) return p->base + v; - for (j=0; ; j++) { + if (!p->loadmap) + return p->base + v; + for (j = 0;; j++) + { size_t a = p->loadmap->segs[j].p_vaddr; size_t b = a + p->loadmap->segs[j].p_memsz; a &= -pgsz; - b += pgsz-1; + b += pgsz - 1; b &= -pgsz; - if (v-aloadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); } static void (*fdbarrier(void *p))() { void (*fd)(); - __asm__("" : "=r"(fd) : "0"(p)); + __asm__("" + : "=r"(fd) + : "0"(p)); return fd; } #define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \ - laddr(p, v), (p)->got })) + laddr(p, v), (p)->got})) #else #define laddr(p, v) (void *)((p)->base + (v)) #define laddr_pg(p, v) laddr(p, v) @@ -214,18 +230,22 @@ static void (*fdbarrier(void *p))() static void decode_vec(size_t *v, size_t *a, size_t cnt) { size_t i; - for (i=0; i>24 & 0xf0; + while (*s) + { + h = 16 * h + *s++; + h ^= h >> 24 & 0xf0; } return h & 0xfffffff; } @@ -246,7 +267,7 @@ static uint32_t gnu_hash(const char *s0) const unsigned char *s = (void *)s0; uint_fast32_t h = 5381; for (; *s; s++) - h += h*32 + *s; + h += h * 32 + *s; return h; } @@ -256,10 +277,10 @@ static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso) Sym *syms = dso->syms; Elf_Symndx *hashtab = dso->hashtab; char *strings = dso->strings; - for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) { - if ((!dso->versym || dso->versym[i] >= 0) - && (!strcmp(s, strings+syms[i].st_name))) - return syms+i; + for (i = hashtab[2 + h % hashtab[0]]; i; i = hashtab[2 + hashtab[0] + i]) + { + if ((!dso->versym || dso->versym[i] >= 0) && (!strcmp(s, strings + syms[i].st_name))) + return syms + i; } return 0; } @@ -267,19 +288,21 @@ static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso) static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s) { uint32_t nbuckets = hashtab[0]; - uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4); + uint32_t *buckets = hashtab + 4 + hashtab[2] * (sizeof(size_t) / 4); uint32_t i = buckets[h1 % nbuckets]; - if (!i) return 0; + if (!i) + return 0; uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]); - for (h1 |= 1; ; i++) { + for (h1 |= 1;; i++) + { uint32_t h2 = *hashval++; - if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0) - && !strcmp(s, dso->strings + dso->syms[i].st_name)) - return dso->syms+i; - if (h2 & 1) break; + if ((h1 == (h2 | 1)) && (!dso->versym || dso->versym[i] >= 0) && !strcmp(s, dso->strings + dso->syms[i].st_name)) + return dso->syms + i; + if (h2 & 1) + break; } return 0; @@ -287,18 +310,20 @@ static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const ch static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask) { - const size_t *bloomwords = (const void *)(hashtab+4); - size_t f = bloomwords[fofs & (hashtab[2]-1)]; - if (!(f & fmask)) return 0; + const size_t *bloomwords = (const void *)(hashtab + 4); + size_t f = bloomwords[fofs & (hashtab[2] - 1)]; + if (!(f & fmask)) + return 0; f >>= (h1 >> hashtab[3]) % (8 * sizeof f); - if (!(f & 1)) return 0; + if (!(f & 1)) + return 0; return gnu_lookup(h1, hashtab, dso, s); } -#define OK_TYPES (1<deps : 0; - for (; dso; dso=use_deps ? *deps++ : dso->syms_next) { + for (; dso; dso = use_deps ? *deps++ : dso->syms_next) + { Sym *sym; - if ((ght = dso->ghashtab)) { + if ((ght = dso->ghashtab)) + { sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm); - } else { - if (!h) h = sysv_hash(s); + } + else + { + if (!h) + h = sysv_hash(s); sym = sysv_lookup(s, h, dso); } - if (!sym) continue; + if (!sym) + continue; if (!sym->st_shndx) - if (need_def || (sym->st_info&0xf) == STT_TLS - || ARCH_SYM_REJECT_UND(sym)) + if (need_def || (sym->st_info & 0xf) == STT_TLS || ARCH_SYM_REJECT_UND(sym)) continue; if (!sym->st_value) - if ((sym->st_info&0xf) != STT_TLS) + if ((sym->st_info & 0xf) != STT_TLS) continue; - if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue; - if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue; + if (!(1 << (sym->st_info & 0xf) & OK_TYPES)) + continue; + if (!(1 << (sym->st_info >> 4) & OK_BINDS)) + continue; def.sym = sym; def.dso = dso; break; @@ -360,21 +393,26 @@ static struct symdef get_lfs64(const char *name) "__fxstat\0__fxstatat\0__lxstat\0__xstat\0"; size_t l; char buf[16]; - for (l=0; name[l]; l++) { - if (l >= sizeof buf) goto nomatch; + for (l = 0; name[l]; l++) + { + if (l >= sizeof buf) + goto nomatch; buf[l] = name[l]; } if (!strcmp(name, "readdir64_r")) return find_sym(&ldso, "readdir_r", 1); - if (l<2 || name[l-2]!='6' || name[l-1]!='4') + if (l < 2 || name[l - 2] != '6' || name[l - 1] != '4') goto nomatch; - buf[l-=2] = 0; - for (p=lfs64_list; *p; p++) { - if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1); - while (*p) p++; + buf[l -= 2] = 0; + for (p = lfs64_list; *p; p++) + { + if (!strcmp(buf, p)) + return find_sym(&ldso, buf, 1); + while (*p) + p++; } nomatch: - return (struct symdef){ 0 }; + return (struct symdef){0}; } static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride) @@ -394,58 +432,75 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri size_t addend; int skip_relative = 0, reuse_addends = 0, save_slot = 0; - if (dso == &ldso) { + if (dso == &ldso) + { /* Only ldso's REL table needs addend saving/reuse. */ if (rel == apply_addends_to) reuse_addends = 1; skip_relative = 1; } - for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) { - if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue; + for (; rel_size; rel += stride, rel_size -= stride * sizeof(size_t)) + { + if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) + continue; type = R_TYPE(rel[1]); - if (type == REL_NONE) continue; + if (type == REL_NONE) + continue; reloc_addr = laddr(dso, rel[0]); - if (stride > 2) { + if (stride > 2) + { addend = rel[2]; - } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) { + } + else if (type == REL_GOT || type == REL_PLT || type == REL_COPY) + { addend = 0; - } else if (reuse_addends) { + } + else if (reuse_addends) + { /* Save original addend in stage 2 where the dso * chain consists of just ldso; otherwise read back * saved addend since the inline one was clobbered. */ - if (head==&ldso) + if (head == &ldso) saved_addends[save_slot] = *reloc_addr; addend = saved_addends[save_slot++]; - } else { + } + else + { addend = *reloc_addr; } sym_index = R_SYM(rel[1]); - if (sym_index) { + if (sym_index) + { sym = syms + sym_index; name = strings + sym->st_name; - ctx = type==REL_COPY ? head->syms_next : head; - def = (sym->st_info>>4) == STB_LOCAL - ? (struct symdef){ .dso = dso, .sym = sym } - : find_sym(ctx, name, type==REL_PLT); - if (!def.sym) def = get_lfs64(name); - if (!def.sym && (sym->st_shndx != SHN_UNDEF - || sym->st_info>>4 != STB_WEAK)) { - if (dso->lazy && (type==REL_PLT || type==REL_GOT)) { - dso->lazy[3*dso->lazy_cnt+0] = rel[0]; - dso->lazy[3*dso->lazy_cnt+1] = rel[1]; - dso->lazy[3*dso->lazy_cnt+2] = addend; + ctx = type == REL_COPY ? head->syms_next : head; + def = (sym->st_info >> 4) == STB_LOCAL + ? (struct symdef){.dso = dso, .sym = sym} + : find_sym(ctx, name, type == REL_PLT); + if (!def.sym) + def = get_lfs64(name); + if (!def.sym && (sym->st_shndx != SHN_UNDEF || sym->st_info >> 4 != STB_WEAK)) + { + if (dso->lazy && (type == REL_PLT || type == REL_GOT)) + { + dso->lazy[3 * dso->lazy_cnt + 0] = rel[0]; + dso->lazy[3 * dso->lazy_cnt + 1] = rel[1]; + dso->lazy[3 * dso->lazy_cnt + 2] = addend; dso->lazy_cnt++; continue; } error("Error relocating %s: %s: symbol not found", - dso->name, name); - if (runtime) longjmp(*rtld_fail, 1); + dso->name, name); + if (runtime) + longjmp(*rtld_fail, 1); continue; } - } else { + } + else + { sym = 0; def.sym = 0; def.dso = dso; @@ -454,15 +509,16 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0; tls_val = def.sym ? def.sym->st_value : 0; - if ((type == REL_TPOFF || type == REL_TPOFF_NEG) - && def.dso->tls_id > static_tls_cnt) { + if ((type == REL_TPOFF || type == REL_TPOFF_NEG) && def.dso->tls_id > static_tls_cnt) + { error("Error relocating %s: %s: initial-exec TLS " - "resolves to dynamic definition in %s", - dso->name, name, def.dso->name); + "resolves to dynamic definition in %s", + dso->name, name, def.dso->name); longjmp(*rtld_fail, 1); } - switch(type) { + switch (type) + { case REL_OFFSET: addend -= (size_t)reloc_addr; case REL_SYMBOLIC: @@ -477,23 +533,25 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri *reloc_addr = (size_t)base + addend; break; case REL_SYM_OR_REL: - if (sym) *reloc_addr = sym_val + addend; - else *reloc_addr = (size_t)base + addend; + if (sym) + *reloc_addr = sym_val + addend; + else + *reloc_addr = (size_t)base + addend; break; case REL_COPY: memcpy(reloc_addr, (void *)sym_val, sym->st_size); break; case REL_OFFSET32: - *(uint32_t *)reloc_addr = sym_val + addend - - (size_t)reloc_addr; + *(uint32_t *)reloc_addr = sym_val + addend - (size_t)reloc_addr; break; case REL_FUNCDESC: - *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs - + (def.sym - def.dso->syms)) : 0; + *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs + (def.sym - def.dso->syms)) : 0; break; case REL_FUNCDESC_VAL: - if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val; - else *reloc_addr = sym_val; + if ((sym->st_info & 0xf) == STT_SECTION) + *reloc_addr += sym_val; + else + *reloc_addr = sym_val; reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0; break; case REL_DTPMOD: @@ -515,13 +573,16 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri break; #endif case REL_TLSDESC: - if (stride<3) addend = reloc_addr[1]; - if (def.dso->tls_id > static_tls_cnt) { + if (stride < 3) + addend = reloc_addr[1]; + if (def.dso->tls_id > static_tls_cnt) + { struct td_index *new = malloc(sizeof *new); - if (!new) { + if (!new) + { error( - "Error relocating %s: cannot allocate TLSDESC for %s", - dso->name, sym ? name : "(local)" ); + "Error relocating %s: cannot allocate TLSDESC for %s", + dso->name, sym ? name : "(local)"); longjmp(*rtld_fail, 1); } new->next = dso->td_index; @@ -529,15 +590,15 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri new->args[0] = def.dso->tls_id; new->args[1] = tls_val + addend - DTP_OFFSET; reloc_addr[0] = (size_t)__tlsdesc_dynamic; - reloc_addr[1] = (size_t)new; - } else { + reloc_addr[1] = (size_t) new; + } + else + { reloc_addr[0] = (size_t)__tlsdesc_static; #ifdef TLS_ABOVE_TP - reloc_addr[1] = tls_val + def.dso->tls.offset - + TPOFF_K + addend; + reloc_addr[1] = tls_val + def.dso->tls.offset + TPOFF_K + addend; #else - reloc_addr[1] = tls_val - def.dso->tls.offset - + addend; + reloc_addr[1] = tls_val - def.dso->tls.offset + addend; #endif } #ifdef TLSDESC_BACKWARDS @@ -550,8 +611,9 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri break; default: error("Error relocating %s: unsupported relocation type %d", - dso->name, type); - if (runtime) longjmp(*rtld_fail, 1); + dso->name, type); + if (runtime) + longjmp(*rtld_fail, 1); continue; } } @@ -559,19 +621,23 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size) { - if (dso == &ldso) return; /* self-relocation was done in _dlstart */ + if (dso == &ldso) + return; /* self-relocation was done in _dlstart */ unsigned char *base = dso->base; size_t *reloc_addr; - for (; relr_size; relr++, relr_size-=sizeof(size_t)) - if ((relr[0]&1) == 0) { + for (; relr_size; relr++, relr_size -= sizeof(size_t)) + if ((relr[0] & 1) == 0) + { reloc_addr = laddr(dso, relr[0]); *reloc_addr++ += (size_t)base; - } else { + } + else + { int i = 0; - for (size_t bitmap=relr[0]; (bitmap>>=1); i++) - if (bitmap&1) + for (size_t bitmap = relr[0]; (bitmap >>= 1); i++) + if (bitmap & 1) reloc_addr[i] += (size_t)base; - reloc_addr += 8*sizeof(size_t)-1; + reloc_addr += 8 * sizeof(size_t) - 1; } } @@ -579,15 +645,19 @@ static void redo_lazy_relocs() { struct dso *p = lazy_head, *next; lazy_head = 0; - for (; p; p=next) { + for (; p; p = next) + { next = p->lazy_next; - size_t size = p->lazy_cnt*3*sizeof(size_t); + size_t size = p->lazy_cnt * 3 * sizeof(size_t); p->lazy_cnt = 0; do_relocs(p, p->lazy, size, 3); - if (p->lazy_cnt) { + if (p->lazy_cnt) + { p->lazy_next = lazy_head; lazy_head = p; - } else { + } + else + { free(p->lazy); p->lazy = 0; p->lazy_next = 0; @@ -602,11 +672,14 @@ static void redo_lazy_relocs() static void reclaim(struct dso *dso, size_t start, size_t end) { - if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end; - if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start; - if (start >= end) return; + if (start >= dso->relro_start && start < dso->relro_end) + start = dso->relro_end; + if (end >= dso->relro_start && end < dso->relro_end) + end = dso->relro_start; + if (start >= end) + return; char *base = laddr_pg(dso, start); - __malloc_donate(base, base+(end-start)); + __malloc_donate(base, base + (end - start)); } static void reclaim_gaps(struct dso *dso) @@ -614,24 +687,32 @@ static void reclaim_gaps(struct dso *dso) Phdr *ph = dso->phdr; size_t phcnt = dso->phnum; - for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) { - if (ph->p_type!=PT_LOAD) continue; - if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; + for (; phcnt--; ph = (void *)((char *)ph + dso->phentsize)) + { + if (ph->p_type != PT_LOAD) + continue; + if ((ph->p_flags & (PF_R | PF_W)) != (PF_R | PF_W)) + continue; reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); - reclaim(dso, ph->p_vaddr+ph->p_memsz, - ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); + reclaim(dso, ph->p_vaddr + ph->p_memsz, + ph->p_vaddr + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE); } } static ssize_t read_loop(int fd, void *p, size_t n) { - for (size_t i=0; iloadmap) { + if (dso->loadmap) + { size_t i; - for (i=0; iloadmap->nsegs; i++) { + for (i = 0; i < dso->loadmap->nsegs; i++) + { if (!dso->loadmap->segs[i].p_memsz) continue; munmap((void *)dso->loadmap->segs[i].addr, - dso->loadmap->segs[i].p_memsz); + dso->loadmap->segs[i].p_memsz); } free(dso->loadmap); - } else if (dso->map && dso->map_len) { + } + else if (dso->map && dso->map_len) + { munmap(dso->map, dso->map_len); } } static void *map_library(int fd, struct dso *dso) { - Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)]; - void *allocated_buf=0; + Ehdr buf[(896 + sizeof(Ehdr)) / sizeof(Ehdr)]; + void *allocated_buf = 0; size_t phsize; - size_t addr_min=SIZE_MAX, addr_max=0, map_len; + size_t addr_min = SIZE_MAX, addr_max = 0, map_len; size_t this_min, this_max; size_t nsegs = 0; off_t off_start; Ehdr *eh; Phdr *ph, *ph0; unsigned prot; - unsigned char *map=MAP_FAILED, *base; - size_t dyn=0; - size_t tls_image=0; + unsigned char *map = MAP_FAILED, *base; + size_t dyn = 0; + size_t tls_image = 0; size_t i; ssize_t l = read(fd, buf, sizeof buf); eh = buf; - if (l<0) return 0; - if (le_type != ET_DYN && eh->e_type != ET_EXEC)) + if (l < 0) + return 0; + if (l < sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC)) goto noexec; phsize = eh->e_phentsize * eh->e_phnum; - if (phsize > sizeof buf - sizeof *eh) { + if (phsize > sizeof buf - sizeof *eh) + { allocated_buf = malloc(phsize); - if (!allocated_buf) return 0; + if (!allocated_buf) + return 0; l = pread(fd, allocated_buf, phsize, eh->e_phoff); - if (l < 0) goto error; - if (l != phsize) goto noexec; + if (l < 0) + goto error; + if (l != phsize) + goto noexec; ph = ph0 = allocated_buf; - } else if (eh->e_phoff + phsize > l) { - l = pread(fd, buf+1, phsize, eh->e_phoff); - if (l < 0) goto error; - if (l != phsize) goto noexec; + } + else if (eh->e_phoff + phsize > l) + { + l = pread(fd, buf + 1, phsize, eh->e_phoff); + if (l < 0) + goto error; + if (l != phsize) + goto noexec; ph = ph0 = (void *)(buf + 1); - } else { + } + else + { ph = ph0 = (void *)((char *)buf + eh->e_phoff); } - for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { - if (ph->p_type == PT_DYNAMIC) { + for (i = eh->e_phnum; i; i--, ph = (void *)((char *)ph + eh->e_phentsize)) + { + if (ph->p_type == PT_DYNAMIC) + { dyn = ph->p_vaddr; - } else if (ph->p_type == PT_TLS) { + } + else if (ph->p_type == PT_TLS) + { tls_image = ph->p_vaddr; dso->tls.align = ph->p_align; dso->tls.len = ph->p_filesz; dso->tls.size = ph->p_memsz; - } else if (ph->p_type == PT_GNU_RELRO) { + } + else if (ph->p_type == PT_GNU_RELRO) + { dso->relro_start = ph->p_vaddr & -PAGE_SIZE; dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; - } else if (ph->p_type == PT_GNU_STACK) { - if (!runtime && ph->p_memsz > __default_stacksize) { + } + else if (ph->p_type == PT_GNU_STACK) + { + if (!runtime && ph->p_memsz > __default_stacksize) + { __default_stacksize = - ph->p_memsz < DEFAULT_STACK_MAX ? - ph->p_memsz : DEFAULT_STACK_MAX; + ph->p_memsz < DEFAULT_STACK_MAX ? ph->p_memsz : DEFAULT_STACK_MAX; } } - if (ph->p_type != PT_LOAD) continue; + if (ph->p_type != PT_LOAD) + continue; nsegs++; - if (ph->p_vaddr < addr_min) { + if (ph->p_vaddr < addr_min) + { addr_min = ph->p_vaddr; off_start = ph->p_offset; - prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | - ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | - ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); + prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) | + ((ph->p_flags & PF_W) ? PROT_WRITE : 0) | + ((ph->p_flags & PF_X) ? PROT_EXEC : 0)); } - if (ph->p_vaddr+ph->p_memsz > addr_max) { - addr_max = ph->p_vaddr+ph->p_memsz; + if (ph->p_vaddr + ph->p_memsz > addr_max) + { + addr_max = ph->p_vaddr + ph->p_memsz; } } - if (!dyn) goto noexec; - if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) { - dso->loadmap = calloc(1, sizeof *dso->loadmap - + nsegs * sizeof *dso->loadmap->segs); - if (!dso->loadmap) goto error; + if (!dyn) + goto noexec; + if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) + { + dso->loadmap = calloc(1, sizeof *dso->loadmap + nsegs * sizeof *dso->loadmap->segs); + if (!dso->loadmap) + goto error; dso->loadmap->nsegs = nsegs; - for (ph=ph0, i=0; ie_phentsize)) { - if (ph->p_type != PT_LOAD) continue; - prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | - ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | - ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); - map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1), - prot, MAP_PRIVATE, - fd, ph->p_offset & -PAGE_SIZE); - if (map == MAP_FAILED) { + for (ph = ph0, i = 0; i < nsegs; ph = (void *)((char *)ph + eh->e_phentsize)) + { + if (ph->p_type != PT_LOAD) + continue; + prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) | + ((ph->p_flags & PF_W) ? PROT_WRITE : 0) | + ((ph->p_flags & PF_X) ? PROT_EXEC : 0)); + map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE - 1), + prot, MAP_PRIVATE, + fd, ph->p_offset & -PAGE_SIZE); + if (map == MAP_FAILED) + { unmap_library(dso); goto error; } dso->loadmap->segs[i].addr = (size_t)map + - (ph->p_vaddr & PAGE_SIZE-1); + (ph->p_vaddr & PAGE_SIZE - 1); dso->loadmap->segs[i].p_vaddr = ph->p_vaddr; dso->loadmap->segs[i].p_memsz = ph->p_memsz; i++; - if (prot & PROT_WRITE) { - size_t brk = (ph->p_vaddr & PAGE_SIZE-1) - + ph->p_filesz; - size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE; - size_t pgend = brk + ph->p_memsz - ph->p_filesz - + PAGE_SIZE-1 & -PAGE_SIZE; - if (pgend > pgbrk && mmap_fixed(map+pgbrk, - pgend-pgbrk, prot, - MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, - -1, off_start) == MAP_FAILED) + if (prot & PROT_WRITE) + { + size_t brk = (ph->p_vaddr & PAGE_SIZE - 1) + ph->p_filesz; + size_t pgbrk = brk + PAGE_SIZE - 1 & -PAGE_SIZE; + size_t pgend = brk + ph->p_memsz - ph->p_filesz + PAGE_SIZE - 1 & -PAGE_SIZE; + if (pgend > pgbrk && mmap_fixed(map + pgbrk, + pgend - pgbrk, prot, + MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, + -1, off_start) == MAP_FAILED) goto error; - memset(map + brk, 0, pgbrk-brk); + memset(map + brk, 0, pgbrk - brk); } } map = (void *)dso->loadmap->segs[0].addr; map_len = 0; goto done_mapping; } - addr_max += PAGE_SIZE-1; + addr_max += PAGE_SIZE - 1; addr_max &= -PAGE_SIZE; addr_min &= -PAGE_SIZE; off_start &= -PAGE_SIZE; @@ -802,68 +920,74 @@ static void *map_library(int fd, struct dso *dso) * use the invalid part; we just need to reserve the right * amount of virtual address space to map over later. */ map = DL_NOMMU_SUPPORT - ? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) - : mmap((void *)addr_min, map_len, prot, - MAP_PRIVATE, fd, off_start); - if (map==MAP_FAILED) goto error; + ? mmap((void *)addr_min, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) + : mmap((void *)addr_min, map_len, prot, + MAP_PRIVATE, fd, off_start); + if (map == MAP_FAILED) + goto error; dso->map = map; dso->map_len = map_len; /* If the loaded file is not relocatable and the requested address is * not available, then the load operation must fail. */ - if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) { + if (eh->e_type != ET_DYN && addr_min && map != (void *)addr_min) + { errno = EBUSY; goto error; } base = map - addr_min; dso->phdr = 0; dso->phnum = 0; - for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { - if (ph->p_type != PT_LOAD) continue; + for (ph = ph0, i = eh->e_phnum; i; i--, ph = (void *)((char *)ph + eh->e_phentsize)) + { + if (ph->p_type != PT_LOAD) + continue; /* Check if the programs headers are in this load segment, and * if so, record the address for use by dl_iterate_phdr. */ - if (!dso->phdr && eh->e_phoff >= ph->p_offset - && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) { - dso->phdr = (void *)(base + ph->p_vaddr - + (eh->e_phoff-ph->p_offset)); + if (!dso->phdr && eh->e_phoff >= ph->p_offset && eh->e_phoff + phsize <= ph->p_offset + ph->p_filesz) + { + dso->phdr = (void *)(base + ph->p_vaddr + (eh->e_phoff - ph->p_offset)); dso->phnum = eh->e_phnum; dso->phentsize = eh->e_phentsize; } this_min = ph->p_vaddr & -PAGE_SIZE; - this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE; + this_max = ph->p_vaddr + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE; off_start = ph->p_offset & -PAGE_SIZE; - prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | - ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | - ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); + prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) | + ((ph->p_flags & PF_W) ? PROT_WRITE : 0) | + ((ph->p_flags & PF_X) ? PROT_EXEC : 0)); /* Reuse the existing mapping for the lowest-address LOAD */ if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT) - if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) + if (mmap_fixed(base + this_min, this_max - this_min, prot, MAP_PRIVATE | MAP_FIXED, fd, off_start) == MAP_FAILED) goto error; - if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) { - size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz; - size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE; - memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1); - if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) + if (ph->p_memsz > ph->p_filesz && (ph->p_flags & PF_W)) + { + size_t brk = (size_t)base + ph->p_vaddr + ph->p_filesz; + size_t pgbrk = brk + PAGE_SIZE - 1 & -PAGE_SIZE; + memset((void *)brk, 0, pgbrk - brk & PAGE_SIZE - 1); + if (pgbrk - (size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base + this_max - pgbrk, prot, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0) == MAP_FAILED) goto error; } } - for (i=0; ((size_t *)(base+dyn))[i]; i+=2) - if (((size_t *)(base+dyn))[i]==DT_TEXTREL) { - if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) - && errno != ENOSYS) + for (i = 0; ((size_t *)(base + dyn))[i]; i += 2) + if (((size_t *)(base + dyn))[i] == DT_TEXTREL) + { + if (mprotect(map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC) && errno != ENOSYS) goto error; break; } done_mapping: dso->base = base; dso->dynv = laddr(dso, dyn); - if (dso->tls.size) dso->tls.image = laddr(dso, tls_image); + if (dso->tls.size) + dso->tls.image = laddr(dso, tls_image); free(allocated_buf); return map; noexec: errno = ENOEXEC; error: - if (map!=MAP_FAILED) unmap_library(dso); + if (map != MAP_FAILED) + unmap_library(dso); free(allocated_buf); return 0; } @@ -872,13 +996,18 @@ static int path_open(const char *name, const char *s, char *buf, size_t buf_size { size_t l; int fd; - for (;;) { + for (;;) + { s += strspn(s, ":\n"); l = strcspn(s, ":\n"); - if (l-1 >= INT_MAX) return -1; - if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) { - if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd; - switch (errno) { + if (l - 1 >= INT_MAX) + return -1; + if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) + { + if ((fd = open(buf, O_RDONLY | O_CLOEXEC)) >= 0) + return fd; + switch (errno) + { case ENOENT: case ENOTDIR: case EACCES: @@ -899,22 +1028,27 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size) size_t n, l; const char *s, *t, *origin; char *d; - if (p->rpath || !p->rpath_orig) return 0; - if (!strchr(p->rpath_orig, '$')) { + if (p->rpath || !p->rpath_orig) + return 0; + if (!strchr(p->rpath_orig, '$')) + { p->rpath = p->rpath_orig; return 0; } n = 0; s = p->rpath_orig; - while ((t=strchr(s, '$'))) { + while ((t = strchr(s, '$'))) + { if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9)) return 0; - s = t+1; + s = t + 1; n++; } - if (n > SSIZE_MAX/PATH_MAX) return 0; + if (n > SSIZE_MAX / PATH_MAX) + return 0; - if (p->kernel_mapped) { + if (p->kernel_mapped) + { /* $ORIGIN searches cannot be performed for the main program * when it is suid/sgid/AT_SECURE. This is because the * pathname is under the control of the caller of execve. @@ -924,25 +1058,32 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size) if (libc.secure) return 0; l = readlink("/proc/self/exe", buf, buf_size); - if (l == -1) switch (errno) { - case ENOENT: - case ENOTDIR: - case EACCES: - return 0; - default: - return -1; - } + if (l == -1) + switch (errno) + { + case ENOENT: + case ENOTDIR: + case EACCES: + return 0; + default: + return -1; + } if (l >= buf_size) return 0; buf[l] = 0; origin = buf; - } else { + } + else + { origin = p->name; } t = strrchr(origin, '/'); - if (t) { - l = t-origin; - } else { + if (t) + { + l = t - origin; + } + else + { /* Normally p->name will always be an absolute or relative * pathname containing at least one '/' character, but in the * case where ldso was invoked as a command to execute a @@ -953,19 +1094,21 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size) /* Disallow non-absolute origins for suid/sgid/AT_SECURE. */ if (libc.secure && *origin != '/') return 0; - p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1); - if (!p->rpath) return -1; + p->rpath = malloc(strlen(p->rpath_orig) + n * l + 1); + if (!p->rpath) + return -1; d = p->rpath; s = p->rpath_orig; - while ((t=strchr(s, '$'))) { - memcpy(d, s, t-s); - d += t-s; + while ((t = strchr(s, '$'))) + { + memcpy(d, s, t - s); + d += t - s; memcpy(d, origin, l); d += l; /* It was determined previously that the '$' is followed * either by "ORIGIN" or "{ORIGIN}". */ - s = t + 7 + 2*(t[1]=='{'); + s = t + 7 + 2 * (t[1] == '{'); } strcpy(d, s); return 0; @@ -977,13 +1120,13 @@ static void decode_dyn(struct dso *p) decode_vec(p->dynv, dyn, DYN_CNT); p->syms = laddr(p, dyn[DT_SYMTAB]); p->strings = laddr(p, dyn[DT_STRTAB]); - if (dyn[0]&(1<hashtab = laddr(p, dyn[DT_HASH]); - if (dyn[0]&(1<rpath_orig = p->strings + dyn[DT_RPATH]; - if (dyn[0]&(1<rpath_orig = p->strings + dyn[DT_RUNPATH]; - if (dyn[0]&(1<got = laddr(p, dyn[DT_PLTGOT]); if (search_vec(p->dynv, dyn, DT_GNU_HASH)) p->ghashtab = laddr(p, *dyn); @@ -993,18 +1136,22 @@ static void decode_dyn(struct dso *p) static size_t count_syms(struct dso *p) { - if (p->hashtab) return p->hashtab[1]; + if (p->hashtab) + return p->hashtab[1]; size_t nsym, i; - uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4); + uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2] * sizeof(size_t) / 4); uint32_t *hashval; - for (i = nsym = 0; i < p->ghashtab[0]; i++) { + for (i = nsym = 0; i < p->ghashtab[0]; i++) + { if (buckets[i] > nsym) nsym = buckets[i]; } - if (nsym) { + if (nsym) + { hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]); - do nsym++; + do + nsym++; while (!(*hashval++ & 1)); } return nsym; @@ -1013,9 +1160,13 @@ static size_t count_syms(struct dso *p) static void *dl_mmap(size_t n) { void *p; - int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE; + int prot = PROT_READ | PROT_WRITE, flags = MAP_ANONYMOUS | MAP_PRIVATE; #ifdef SYS_mmap2 +#ifdef NO_LITTLE_MODE p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0); +#else + p = (void *)be_mmap2(0, n, prot, flags, -1, 0); +#endif #else p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0); #endif @@ -1028,22 +1179,31 @@ static void makefuncdescs(struct dso *p) size_t nsym = count_syms(p); size_t i, size = nsym * sizeof(*p->funcdescs); - if (!self_done) { + if (!self_done) + { p->funcdescs = dl_mmap(size); self_done = 1; - } else { + } + else + { p->funcdescs = malloc(size); } - if (!p->funcdescs) { - if (!runtime) a_crash(); + if (!p->funcdescs) + { + if (!runtime) + a_crash(); error("Error allocating function descriptors for %s", p->name); longjmp(*rtld_fail, 1); } - for (i=0; isyms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) { + for (i = 0; i < nsym; i++) + { + if ((p->syms[i].st_info & 0xf) == STT_FUNC && p->syms[i].st_shndx) + { p->funcdescs[i].addr = laddr(p, p->syms[i].st_value); p->funcdescs[i].got = p->got; - } else { + } + else + { p->funcdescs[i].addr = 0; p->funcdescs[i].got = 0; } @@ -1052,7 +1212,7 @@ static void makefuncdescs(struct dso *p) static struct dso *load_library(const char *name, struct dso *needed_by) { - char buf[2*NAME_MAX+2]; + char buf[2 * NAME_MAX + 2]; const char *pathname; unsigned char *map; struct dso *p, temp_dso = {0}; @@ -1062,125 +1222,157 @@ static struct dso *load_library(const char *name, struct dso *needed_by) int n_th = 0; int is_self = 0; - if (!*name) { + if (!*name) + { errno = EINVAL; return 0; } /* Catch and block attempts to reload the implementation itself */ - if (name[0]=='l' && name[1]=='i' && name[2]=='b') { + if (name[0] == 'l' && name[1] == 'i' && name[2] == 'b') + { static const char reserved[] = "c.pthread.rt.m.dl.util.xnet."; const char *rp, *next; - for (rp=reserved; *rp; rp=next) { + for (rp = reserved; *rp; rp = next) + { next = strchr(rp, '.') + 1; - if (strncmp(name+3, rp, next-rp) == 0) + if (strncmp(name + 3, rp, next - rp) == 0) break; } - if (*rp) { - if (ldd_mode) { + if (*rp) + { + if (ldd_mode) + { /* Track which names have been resolved * and only report each one once. */ static unsigned reported; - unsigned mask = 1U<<(rp-reserved); - if (!(reported & mask)) { + unsigned mask = 1U << (rp - reserved); + if (!(reported & mask)) + { reported |= mask; dprintf(1, "\t%s => %s (%p)\n", - name, ldso.name, - ldso.base); + name, ldso.name, + ldso.base); } } is_self = 1; } } - if (!strcmp(name, ldso.name)) is_self = 1; - if (is_self) { - if (!ldso.prev) { + if (!strcmp(name, ldso.name)) + is_self = 1; + if (is_self) + { + if (!ldso.prev) + { tail->next = &ldso; ldso.prev = tail; tail = &ldso; } return &ldso; } - if (strchr(name, '/')) { + if (strchr(name, '/')) + { pathname = name; - fd = open(name, O_RDONLY|O_CLOEXEC); - } else { + fd = open(name, O_RDONLY | O_CLOEXEC); + } + else + { /* Search for the name to see if it's already loaded */ - for (p=head->next; p; p=p->next) { - if (p->shortname && !strcmp(p->shortname, name)) { + for (p = head->next; p; p = p->next) + { + if (p->shortname && !strcmp(p->shortname, name)) + { return p; } } - if (strlen(name) > NAME_MAX) return 0; + if (strlen(name) > NAME_MAX) + return 0; fd = -1; - if (env_path) fd = path_open(name, env_path, buf, sizeof buf); - for (p=needed_by; fd == -1 && p; p=p->needed_by) { + if (env_path) + fd = path_open(name, env_path, buf, sizeof buf); + for (p = needed_by; fd == -1 && p; p = p->needed_by) + { if (fixup_rpath(p, buf, sizeof buf) < 0) fd = -2; /* Inhibit further search. */ if (p->rpath) fd = path_open(name, p->rpath, buf, sizeof buf); } - if (fd == -1) { - if (!sys_path) { + if (fd == -1) + { + if (!sys_path) + { char *prefix = 0; size_t prefix_len; - if (ldso.name[0]=='/') { + if (ldso.name[0] == '/') + { char *s, *t, *z; - for (s=t=z=ldso.name; *s; s++) - if (*s=='/') z=t, t=s; - prefix_len = z-ldso.name; + for (s = t = z = ldso.name; *s; s++) + if (*s == '/') + z = t, t = s; + prefix_len = z - ldso.name; if (prefix_len < PATH_MAX) prefix = ldso.name; } - if (!prefix) { + if (!prefix) + { prefix = ""; prefix_len = 0; } - char etc_ldso_path[prefix_len + 1 - + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"]; + char etc_ldso_path[prefix_len + 1 + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"]; snprintf(etc_ldso_path, sizeof etc_ldso_path, - "%.*s/etc/ld-musl-" LDSO_ARCH ".path", - (int)prefix_len, prefix); - fd = open(etc_ldso_path, O_RDONLY|O_CLOEXEC); - if (fd>=0) { + "%.*s/etc/ld-musl-" LDSO_ARCH ".path", + (int)prefix_len, prefix); + fd = open(etc_ldso_path, O_RDONLY | O_CLOEXEC); + if (fd >= 0) + { size_t n = 0; - if (!fstat(fd, &st)) n = st.st_size; - if ((sys_path = malloc(n+1))) + if (!fstat(fd, &st)) + n = st.st_size; + if ((sys_path = malloc(n + 1))) sys_path[n] = 0; - if (!sys_path || read_loop(fd, sys_path, n)<0) { + if (!sys_path || read_loop(fd, sys_path, n) < 0) + { free(sys_path); sys_path = ""; } close(fd); - } else if (errno != ENOENT) { + } + else if (errno != ENOENT) + { sys_path = ""; } } - if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib"; + if (!sys_path) + sys_path = "/lib:/usr/local/lib:/usr/lib"; fd = path_open(name, sys_path, buf, sizeof buf); } pathname = buf; } - if (fd < 0) return 0; - if (fstat(fd, &st) < 0) { + if (fd < 0) + return 0; + if (fstat(fd, &st) < 0) + { close(fd); return 0; } - for (p=head->next; p; p=p->next) { - if (p->dev == st.st_dev && p->ino == st.st_ino) { + for (p = head->next; p; p = p->next) + { + if (p->dev == st.st_dev && p->ino == st.st_ino) + { /* If this library was previously loaded with a * pathname but a search found the same inode, * setup its shortname so it can be found by name. */ if (!p->shortname && pathname != name) - p->shortname = strrchr(p->name, '/')+1; + p->shortname = strrchr(p->name, '/') + 1; close(fd); return p; } } map = noload ? 0 : map_library(fd, &temp_dso); close(fd); - if (!map) return 0; + if (!map) + return 0; /* Avoid the danger of getting two versions of libc mapped into the * same process when an absolute pathname was used. The symbols @@ -1188,14 +1380,16 @@ static struct dso *load_library(const char *name, struct dso *needed_by) * false positives from interposition-hack libraries. */ decode_dyn(&temp_dso); if (find_sym(&temp_dso, "__libc_start_main", 1).sym && - find_sym(&temp_dso, "stdin", 1).sym) { + find_sym(&temp_dso, "stdin", 1).sym) + { unmap_library(&temp_dso); return load_library("libc.so", needed_by); } /* Past this point, if we haven't reached runtime yet, ldso has * committed either to use the mapped library or to abort execution. * Unmapping is not possible, so we can safely reclaim gaps. */ - if (!runtime) reclaim_gaps(&temp_dso); + if (!runtime) + reclaim_gaps(&temp_dso); /* Allocate storage for the new DSO. When there is TLS, this * storage must include a reservation for all pre-existing @@ -1203,15 +1397,18 @@ static struct dso *load_library(const char *name, struct dso *needed_by) * extended DTV capable of storing an additional slot for * the newly-loaded DSO. */ alloc_size = sizeof *p + strlen(pathname) + 1; - if (runtime && temp_dso.tls.image) { - size_t per_th = temp_dso.tls.size + temp_dso.tls.align - + sizeof(void *) * (tls_cnt+3); + if (runtime && temp_dso.tls.image) + { + size_t per_th = temp_dso.tls.size + temp_dso.tls.align + sizeof(void *) * (tls_cnt + 3); n_th = libc.threads_minus_1 + 1; - if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX; - else alloc_size += n_th * per_th; + if (n_th > SSIZE_MAX / per_th) + alloc_size = SIZE_MAX; + else + alloc_size += n_th * per_th; } p = calloc(1, alloc_size); - if (!p) { + if (!p) + { unmap_library(&temp_dso); return 0; } @@ -1223,25 +1420,28 @@ static struct dso *load_library(const char *name, struct dso *needed_by) p->runtime_loaded = runtime; strcpy(p->name, pathname); /* Add a shortname only if name arg was not an explicit pathname. */ - if (pathname != name) p->shortname = strrchr(p->name, '/')+1; - if (p->tls.image) { + if (pathname != name) + p->shortname = strrchr(p->name, '/') + 1; + if (p->tls.image) + { p->tls_id = ++tls_cnt; tls_align = MAXP2(tls_align, p->tls.align); #ifdef TLS_ABOVE_TP - p->tls.offset = tls_offset + ( (p->tls.align-1) & - (-tls_offset + (uintptr_t)p->tls.image) ); + p->tls.offset = tls_offset + ((p->tls.align - 1) & + (-tls_offset + (uintptr_t)p->tls.image)); tls_offset = p->tls.offset + p->tls.size; #else tls_offset += p->tls.size + p->tls.align - 1; - tls_offset -= (tls_offset + (uintptr_t)p->tls.image) - & (p->tls.align-1); + tls_offset -= (tls_offset + (uintptr_t)p->tls.image) & (p->tls.align - 1); p->tls.offset = tls_offset; #endif p->new_dtv = (void *)(-sizeof(size_t) & - (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t))); - p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1)); - if (tls_tail) tls_tail->next = &p->tls; - else libc.tls_head = &p->tls; + (uintptr_t)(p->name + strlen(p->name) + sizeof(size_t))); + p->new_tls = (void *)(p->new_dtv + n_th * (tls_cnt + 1)); + if (tls_tail) + tls_tail->next = &p->tls; + else + libc.tls_head = &p->tls; tls_tail = &p->tls; } @@ -1249,42 +1449,53 @@ static struct dso *load_library(const char *name, struct dso *needed_by) p->prev = tail; tail = p; - if (DL_FDPIC) makefuncdescs(p); + if (DL_FDPIC) + makefuncdescs(p); - if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base); + if (ldd_mode) + dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base); return p; } static void load_direct_deps(struct dso *p) { - size_t i, cnt=0; + size_t i, cnt = 0; - if (p->deps) return; + if (p->deps) + return; /* For head, all preloads are direct pseudo-dependencies. * Count and include them now to avoid realloc later. */ - if (p==head) for (struct dso *q=p->next; q; q=q->next) - cnt++; - for (i=0; p->dynv[i]; i+=2) - if (p->dynv[i] == DT_NEEDED) cnt++; + if (p == head) + for (struct dso *q = p->next; q; q = q->next) + cnt++; + for (i = 0; p->dynv[i]; i += 2) + if (p->dynv[i] == DT_NEEDED) + cnt++; /* Use builtin buffer for apps with no external deps, to * preserve property of no runtime failure paths. */ - p->deps = (p==head && cnt<2) ? builtin_deps : - calloc(cnt+1, sizeof *p->deps); - if (!p->deps) { + p->deps = (p == head && cnt < 2) ? builtin_deps : calloc(cnt + 1, sizeof *p->deps); + if (!p->deps) + { error("Error loading dependencies for %s", p->name); - if (runtime) longjmp(*rtld_fail, 1); + if (runtime) + longjmp(*rtld_fail, 1); } - cnt=0; - if (p==head) for (struct dso *q=p->next; q; q=q->next) - p->deps[cnt++] = q; - for (i=0; p->dynv[i]; i+=2) { - if (p->dynv[i] != DT_NEEDED) continue; - struct dso *dep = load_library(p->strings + p->dynv[i+1], p); - if (!dep) { + cnt = 0; + if (p == head) + for (struct dso *q = p->next; q; q = q->next) + p->deps[cnt++] = q; + for (i = 0; p->dynv[i]; i += 2) + { + if (p->dynv[i] != DT_NEEDED) + continue; + struct dso *dep = load_library(p->strings + p->dynv[i + 1], p); + if (!dep) + { error("Error loading shared library %s: %m (needed by %s)", - p->strings + p->dynv[i+1], p->name); - if (runtime) longjmp(*rtld_fail, 1); + p->strings + p->dynv[i + 1], p->name); + if (runtime) + longjmp(*rtld_fail, 1); continue; } p->deps[cnt++] = dep; @@ -1295,8 +1506,9 @@ static void load_direct_deps(struct dso *p) static void load_deps(struct dso *p) { - if (p->deps) return; - for (; p; p=p->next) + if (p->deps) + return; + for (; p; p = p->next) load_direct_deps(p); } @@ -1308,46 +1520,51 @@ static void extend_bfs_deps(struct dso *p) /* Can't use realloc if the original p->deps was allocated at * program entry and malloc has been replaced, or if it's * the builtin non-allocated trivial main program deps array. */ - int no_realloc = (__malloc_replaced && !p->runtime_loaded) - || p->deps == builtin_deps; + int no_realloc = (__malloc_replaced && !p->runtime_loaded) || p->deps == builtin_deps; - if (p->bfs_built) return; + if (p->bfs_built) + return; ndeps_all = p->ndeps_direct; /* Mark existing (direct) deps so they won't be duplicated. */ - for (i=0; p->deps[i]; i++) + for (i = 0; p->deps[i]; i++) p->deps[i]->mark = 1; /* For each dependency already in the list, copy its list of direct * dependencies to the list, excluding any items already in the * list. Note that the list this loop iterates over will grow during * the loop, but since duplicates are excluded, growth is bounded. */ - for (i=0; p->deps[i]; i++) { + for (i = 0; p->deps[i]; i++) + { struct dso *dep = p->deps[i]; - for (j=cnt=0; jndeps_direct; j++) - if (!dep->deps[j]->mark) cnt++; - tmp = no_realloc ? - malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) : - realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1)); - if (!tmp) { + for (j = cnt = 0; j < dep->ndeps_direct; j++) + if (!dep->deps[j]->mark) + cnt++; + tmp = no_realloc ? malloc(sizeof(*tmp) * (ndeps_all + cnt + 1)) : realloc(p->deps, sizeof(*tmp) * (ndeps_all + cnt + 1)); + if (!tmp) + { error("Error recording dependencies for %s", p->name); - if (runtime) longjmp(*rtld_fail, 1); + if (runtime) + longjmp(*rtld_fail, 1); continue; } - if (no_realloc) { - memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1)); + if (no_realloc) + { + memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all + 1)); no_realloc = 0; } p->deps = tmp; - for (j=0; jndeps_direct; j++) { - if (dep->deps[j]->mark) continue; + for (j = 0; j < dep->ndeps_direct; j++) + { + if (dep->deps[j]->mark) + continue; dep->deps[j]->mark = 1; p->deps[ndeps_all++] = dep->deps[j]; } p->deps[ndeps_all] = 0; } p->bfs_built = 1; - for (p=head; p; p=p->next) + for (p = head; p; p = p->next) p->mark = 0; } @@ -1355,9 +1572,12 @@ static void load_preload(char *s) { int tmp; char *z; - for (z=s; *z; s=z) { - for ( ; *s && (isspace(*s) || *s==':'); s++); - for (z=s; *z && !isspace(*z) && *z!=':'; z++); + for (z = s; *z; s = z) + { + for (; *s && (isspace(*s) || *s == ':'); s++) + ; + for (z = s; *z && !isspace(*z) && *z != ':'; z++) + ; tmp = *z; *z = 0; load_library(s, 0); @@ -1367,7 +1587,8 @@ static void load_preload(char *s) static void add_syms(struct dso *p) { - if (!p->syms_next && syms_tail != p) { + if (!p->syms_next && syms_tail != p) + { syms_tail->syms_next = p; syms_tail = p; } @@ -1378,7 +1599,8 @@ static void revert_syms(struct dso *old_tail) struct dso *p, *next; /* Chop off the tail of the list of dsos that participate in * the global symbol table, reverting them to RTLD_LOCAL. */ - for (p=old_tail; p; p=next) { + for (p = old_tail; p; p = next) + { next = p->syms_next; p->syms_next = 0; } @@ -1389,18 +1611,26 @@ static void do_mips_relocs(struct dso *p, size_t *got) { size_t i, j, rel[2]; unsigned char *base = p->base; - i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO); - if (p==&ldso) { + i = 0; + search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO); + if (p == &ldso) + { got += i; - } else { - while (i--) *got++ += (size_t)base; } - j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM); - i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); + else + { + while (i--) + *got++ += (size_t)base; + } + j = 0; + search_vec(p->dynv, &j, DT_MIPS_GOTSYM); + i = 0; + search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); Sym *sym = p->syms + j; rel[0] = (unsigned char *)got - base; - for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) { - rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT); + for (i -= j; i; i--, sym++, rel[0] += sizeof(size_t)) + { + rel[1] = R_INFO(sym - p->syms, R_MIPS_JUMP_SLOT); do_relocs(p, rel, sizeof rel, 2); } } @@ -1408,25 +1638,30 @@ static void do_mips_relocs(struct dso *p, size_t *got) static void reloc_all(struct dso *p) { size_t dyn[DYN_CNT]; - for (; p; p=p->next) { - if (p->relocated) continue; + for (; p; p = p->next) + { + if (p->relocated) + continue; decode_vec(p->dynv, dyn, DYN_CNT); if (NEED_MIPS_GOT_RELOCS) do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT])); do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ], - 2+(dyn[DT_PLTREL]==DT_RELA)); + 2 + (dyn[DT_PLTREL] == DT_RELA)); do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2); do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3); if (!DL_FDPIC) do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]); - if (head != &ldso && p->relro_start != p->relro_end) { + if (head != &ldso && p->relro_start != p->relro_end) + { long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start), - p->relro_end-p->relro_start, PROT_READ); - if (ret != 0 && ret != -ENOSYS) { + p->relro_end - p->relro_start, PROT_READ); + if (ret != 0 && ret != -ENOSYS) + { error("Error relocating %s: RELRO protection failed: %m", - p->name); - if (runtime) longjmp(*rtld_fail, 1); + p->name); + if (runtime) + longjmp(*rtld_fail, 1); } } @@ -1438,27 +1673,34 @@ static void kernel_mapped_dso(struct dso *p) { size_t min_addr = -1, max_addr = 0, cnt; Phdr *ph = p->phdr; - for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) { - if (ph->p_type == PT_DYNAMIC) { + for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) + { + if (ph->p_type == PT_DYNAMIC) + { p->dynv = laddr(p, ph->p_vaddr); - } else if (ph->p_type == PT_GNU_RELRO) { + } + else if (ph->p_type == PT_GNU_RELRO) + { p->relro_start = ph->p_vaddr & -PAGE_SIZE; p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; - } else if (ph->p_type == PT_GNU_STACK) { - if (!runtime && ph->p_memsz > __default_stacksize) { + } + else if (ph->p_type == PT_GNU_STACK) + { + if (!runtime && ph->p_memsz > __default_stacksize) + { __default_stacksize = - ph->p_memsz < DEFAULT_STACK_MAX ? - ph->p_memsz : DEFAULT_STACK_MAX; + ph->p_memsz < DEFAULT_STACK_MAX ? ph->p_memsz : DEFAULT_STACK_MAX; } } - if (ph->p_type != PT_LOAD) continue; + if (ph->p_type != PT_LOAD) + continue; if (ph->p_vaddr < min_addr) min_addr = ph->p_vaddr; - if (ph->p_vaddr+ph->p_memsz > max_addr) - max_addr = ph->p_vaddr+ph->p_memsz; + if (ph->p_vaddr + ph->p_memsz > max_addr) + max_addr = ph->p_vaddr + ph->p_memsz; } min_addr &= -PAGE_SIZE; - max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE; + max_addr = (max_addr + PAGE_SIZE - 1) & -PAGE_SIZE; p->map = p->base + min_addr; p->map_len = max_addr - min_addr; p->kernel_mapped = 1; @@ -1477,18 +1719,22 @@ void __libc_exit_fini() pthread_mutex_lock(&init_fini_lock); shutting_down = 1; pthread_rwlock_unlock(&lock); - for (p=fini_head; p; p=p->fini_next) { - while (p->ctor_visitor && p->ctor_visitor!=self) + for (p = fini_head; p; p = p->fini_next) + { + while (p->ctor_visitor && p->ctor_visitor != self) pthread_cond_wait(&ctor_cond, &init_fini_lock); - if (!p->constructed) continue; + if (!p->constructed) + continue; decode_vec(p->dynv, dyn, DYN_CNT); - if (dyn[0] & (1<bfs_built) { - for (cnt=0; dso->deps[cnt]; cnt++) + if (dso->bfs_built) + { + for (cnt = 0; dso->deps[cnt]; cnt++) dso->deps[cnt]->mark = 0; cnt++; /* self, not included in deps */ - } else { - for (cnt=0, p=head; p; cnt++, p=p->next) + } + else + { + for (cnt = 0, p = head; p; cnt++, p = p->next) p->mark = 0; } cnt++; /* termination slot */ - if (dso==head && cnt <= countof(builtin_ctor_queue)) + if (dso == head && cnt <= countof(builtin_ctor_queue)) queue = builtin_ctor_queue; else queue = calloc(cnt, sizeof *queue); - if (!queue) { + if (!queue) + { error("Error allocating constructor queue: %m\n"); - if (runtime) longjmp(*rtld_fail, 1); + if (runtime) + longjmp(*rtld_fail, 1); return 0; } @@ -1547,12 +1802,17 @@ static struct dso **queue_ctors(struct dso *dso) dso->mark = 1; /* Then perform pseudo-DFS sort, but ignoring circular deps. */ - while (sposnext_dep < p->ndeps_direct) { - if (p->deps[p->next_dep]->mark) { + while (p->next_dep < p->ndeps_direct) + { + if (p->deps[p->next_dep]->mark) + { p->next_dep++; - } else { + } + else + { stack[--spos] = p; p = p->deps[p->next_dep]; p->next_dep = 0; @@ -1562,13 +1822,16 @@ static struct dso **queue_ctors(struct dso *dso) queue[qpos++] = p; } queue[qpos] = 0; - for (i=0; imark = 0; - for (i=0; ictor_visitor && queue[i]->ctor_visitor->tid < 0) { + for (i = 0; i < qpos; i++) + queue[i]->mark = 0; + for (i = 0; i < qpos; i++) + if (queue[i]->ctor_visitor && queue[i]->ctor_visitor->tid < 0) + { error("State of %s is inconsistent due to multithreaded fork\n", - queue[i]->name); + queue[i]->name); free(queue); - if (runtime) longjmp(*rtld_fail, 1); + if (runtime) + longjmp(*rtld_fail, 1); } return queue; @@ -1581,15 +1844,17 @@ static void do_init_fini(struct dso **queue) pthread_t self = __pthread_self(); pthread_mutex_lock(&init_fini_lock); - for (i=0; (p=queue[i]); i++) { - while ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down) + for (i = 0; (p = queue[i]); i++) + { + while ((p->ctor_visitor && p->ctor_visitor != self) || shutting_down) pthread_cond_wait(&ctor_cond, &init_fini_lock); if (p->ctor_visitor || p->constructed) continue; p->ctor_visitor = self; - + decode_vec(p->dynv, dyn, DYN_CNT); - if (dyn[0] & ((1<fini_next = fini_head; fini_head = p; } @@ -1597,13 +1862,15 @@ static void do_init_fini(struct dso **queue) pthread_mutex_unlock(&init_fini_lock); #ifndef NO_LEGACY_INITFINI - if ((dyn[0] & (1<new_dtv; + uintptr_t(*newdtv)[tls_cnt + 1] = (void *)dtv_provider->new_dtv; struct dso *p; size_t i, j; size_t old_cnt = self->dtv[0]; @@ -1657,25 +1924,29 @@ static void install_new_tls(void) __block_app_sigs(&set); __tl_lock(); /* Copy existing dtv contents from all existing threads. */ - for (i=0, td=self; !i || td!=self; i++, td=td->next) { - memcpy(newdtv+i, td->dtv, - (old_cnt+1)*sizeof(uintptr_t)); + for (i = 0, td = self; !i || td != self; i++, td = td->next) + { + memcpy(newdtv + i, td->dtv, + (old_cnt + 1) * sizeof(uintptr_t)); newdtv[i][0] = tls_cnt; } /* Install new dtls into the enlarged, uninstalled dtv copies. */ - for (p=head; ; p=p->next) { - if (p->tls_id <= old_cnt) continue; + for (p = head;; p = p->next) + { + if (p->tls_id <= old_cnt) + continue; unsigned char *mem = p->new_tls; - for (j=0; jtls.image - (uintptr_t)mem) - & (p->tls.align-1); + new += ((uintptr_t)p->tls.image - (uintptr_t)mem) & (p->tls.align - 1); memcpy(new, p->tls.image, p->tls.len); newdtv[j][p->tls_id] = - (uintptr_t)new + DTP_OFFSET; + (uintptr_t) new + DTP_OFFSET; mem += p->tls.size + p->tls.align; } - if (p->tls_id == tls_cnt) break; + if (p->tls_id == tls_cnt) + break; } /* Broadcast barrier to ensure contents of new dtv is visible @@ -1686,7 +1957,8 @@ static void install_new_tls(void) __membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0); /* Install new dtv for each thread. */ - for (j=0, td=self; !j || td!=self; j++, td=td->next) { + for (j = 0, td = self; !j || td != self; j++, td = td->next) + { td->dtv = newdtv[j]; } @@ -1698,7 +1970,7 @@ static void install_new_tls(void) * following stage 2 and stage 3 functions via primitive symbolic lookup * since it does not have access to their addresses to begin with. */ -/* Stage 2 of the dynamic linker is called after relative relocations +/* Stage 2 of the dynamic linker is called after relative relocations * have been processed. It can make function calls to static functions * and access string literals and static data, but cannot use extern * symbols. Its job is to perform symbolic relocations on the dynamic @@ -1708,21 +1980,28 @@ static void install_new_tls(void) hidden void __dls2(unsigned char *base, size_t *sp) { size_t *auxv; - for (auxv=sp+1+*sp+1; *auxv; auxv++); + for (auxv = sp + 1 + *sp + 1; *auxv; auxv++) + ; auxv++; - if (DL_FDPIC) { + if (DL_FDPIC) + { void *p1 = (void *)sp[-2]; void *p2 = (void *)sp[-1]; - if (!p1) { + if (!p1) + { size_t aux[AUX_CNT]; decode_vec(auxv, aux, AUX_CNT); - if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE]; - else ldso.base = (void *)(aux[AT_PHDR] & -4096); + if (aux[AT_BASE]) + ldso.base = (void *)aux[AT_BASE]; + else + ldso.base = (void *)(aux[AT_PHDR] & -4096); } app_loadmap = p2 ? p1 : 0; ldso.loadmap = p2 ? p2 : p1; ldso.base = laddr(&ldso, 0); - } else { + } + else + { ldso.base = base; } Ehdr *ehdr = (void *)ldso.base; @@ -1734,7 +2013,8 @@ hidden void __dls2(unsigned char *base, size_t *sp) kernel_mapped_dso(&ldso); decode_dyn(&ldso); - if (DL_FDPIC) makefuncdescs(&ldso); + if (DL_FDPIC) + makefuncdescs(&ldso); /* Prepare storage for to save clobbered REL addends so they * can be reused in stage 3. There should be very few. If @@ -1746,10 +2026,12 @@ hidden void __dls2(unsigned char *base, size_t *sp) size_t rel_size = dyn[DT_RELSZ]; size_t symbolic_rel_cnt = 0; apply_addends_to = rel; - for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) - if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++; - if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash(); - size_t addends[symbolic_rel_cnt+1]; + for (; rel_size; rel += 2, rel_size -= 2 * sizeof(size_t)) + if (!IS_RELATIVE(rel[1], ldso.syms)) + symbolic_rel_cnt++; + if (symbolic_rel_cnt >= ADDEND_LIMIT) + a_crash(); + size_t addends[symbolic_rel_cnt + 1]; saved_addends = addends; head = &ldso; @@ -1761,8 +2043,10 @@ hidden void __dls2(unsigned char *base, size_t *sp) * symbolically as a barrier against moving the address * load across the above relocation processing. */ struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0); - if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv); - else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv); + if (DL_FDPIC) + ((stage3_func)&ldso.funcdescs[dls2b_def.sym - ldso.syms])(sp, auxv); + else + ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv); } /* Stage 2b sets up a valid thread pointer, which requires relocations @@ -1780,13 +2064,16 @@ void __dls2b(size_t *sp, size_t *auxv) libc.auxv = auxv; libc.tls_size = sizeof builtin_tls; libc.tls_align = tls_align; - if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) { + if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) + { a_crash(); } struct symdef dls3_def = find_sym(&ldso, "__dls3", 0); - if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv); - else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv); + if (DL_FDPIC) + ((stage3_func)&ldso.funcdescs[dls3_def.sym - ldso.syms])(sp, auxv); + else + ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv); } /* Stage 3 of the dynamic linker is called with the dynamic linker/libc @@ -1799,13 +2086,13 @@ void __dls3(size_t *sp, size_t *auxv) static struct dso app, vdso; size_t aux[AUX_CNT]; size_t i; - char *env_preload=0; - char *replace_argv0=0; + char *env_preload = 0; + char *replace_argv0 = 0; size_t vdso_base; int argc = *sp; - char **argv = (void *)(sp+1); + char **argv = (void *)(sp + 1); char **argv_orig = argv; - char **envp = argv+argc+1; + char **envp = argv + argc + 1; /* Find aux vector just past environ[] and use it to initialize * global data that may be needed before we can make syscalls. */ @@ -1814,11 +2101,11 @@ void __dls3(size_t *sp, size_t *auxv) search_vec(auxv, &__sysinfo, AT_SYSINFO); __pthread_self()->sysinfo = __sysinfo; libc.page_size = aux[AT_PAGESZ]; - libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] - || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]); + libc.secure = ((aux[0] & 0x7800) != 0x7800 || aux[AT_UID] != aux[AT_EUID] || aux[AT_GID] != aux[AT_EGID] || aux[AT_SECURE]); /* Only trust user/env if kernel says we're not suid/sgid */ - if (!libc.secure) { + if (!libc.secure) + { env_path = getenv("LD_LIBRARY_PATH"); env_preload = getenv("LD_PRELOAD"); } @@ -1829,80 +2116,112 @@ void __dls3(size_t *sp, size_t *auxv) /* If the main program was already loaded by the kernel, * AT_PHDR will point to some location other than the dynamic * linker's program headers. */ - if (aux[AT_PHDR] != (size_t)ldso.phdr) { + if (aux[AT_PHDR] != (size_t)ldso.phdr) + { size_t interp_off = 0; size_t tls_image = 0; /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */ Phdr *phdr = app.phdr = (void *)aux[AT_PHDR]; app.phnum = aux[AT_PHNUM]; app.phentsize = aux[AT_PHENT]; - for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) { + for (i = aux[AT_PHNUM]; i; i--, phdr = (void *)((char *)phdr + aux[AT_PHENT])) + { if (phdr->p_type == PT_PHDR) app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr); else if (phdr->p_type == PT_INTERP) interp_off = (size_t)phdr->p_vaddr; - else if (phdr->p_type == PT_TLS) { + else if (phdr->p_type == PT_TLS) + { tls_image = phdr->p_vaddr; app.tls.len = phdr->p_filesz; app.tls.size = phdr->p_memsz; app.tls.align = phdr->p_align; } } - if (DL_FDPIC) app.loadmap = app_loadmap; - if (app.tls.size) app.tls.image = laddr(&app, tls_image); - if (interp_off) ldso.name = laddr(&app, interp_off); - if ((aux[0] & (1UL<= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1; + if (l >= 3 && !strcmp(ldname + l - 3, "ldd")) + ldd_mode = 1; argv++; - while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') { - char *opt = argv[0]+2; + while (argv[0] && argv[0][0] == '-' && argv[0][1] == '-') + { + char *opt = argv[0] + 2; *argv++ = (void *)-1; - if (!*opt) { + if (!*opt) + { break; - } else if (!memcmp(opt, "list", 5)) { + } + else if (!memcmp(opt, "list", 5)) + { ldd_mode = 1; - } else if (!memcmp(opt, "library-path", 12)) { - if (opt[12]=='=') env_path = opt+13; - else if (opt[12]) *argv = 0; - else if (*argv) env_path = *argv++; - } else if (!memcmp(opt, "preload", 7)) { - if (opt[7]=='=') env_preload = opt+8; - else if (opt[7]) *argv = 0; - else if (*argv) env_preload = *argv++; - } else if (!memcmp(opt, "argv0", 5)) { - if (opt[5]=='=') replace_argv0 = opt+6; - else if (opt[5]) *argv = 0; - else if (*argv) replace_argv0 = *argv++; - } else { + } + else if (!memcmp(opt, "library-path", 12)) + { + if (opt[12] == '=') + env_path = opt + 13; + else if (opt[12]) + *argv = 0; + else if (*argv) + env_path = *argv++; + } + else if (!memcmp(opt, "preload", 7)) + { + if (opt[7] == '=') + env_preload = opt + 8; + else if (opt[7]) + *argv = 0; + else if (*argv) + env_preload = *argv++; + } + else if (!memcmp(opt, "argv0", 5)) + { + if (opt[5] == '=') + replace_argv0 = opt + 6; + else if (opt[5]) + *argv = 0; + else if (*argv) + replace_argv0 = *argv++; + } + else + { argv[0] = 0; } } - argv[-1] = (void *)(argc - (argv-argv_orig)); - if (!argv[0]) { + argv[-1] = (void *)(argc - (argv - argv_orig)); + if (!argv[0]) + { dprintf(2, "musl libc (" LDSO_ARCH ")\n" - "Version %s\n" - "Dynamic Program Loader\n" - "Usage: %s [options] [--] pathname%s\n", - __libc_version, ldname, - ldd_mode ? "" : " [args]"); + "Version %s\n" + "Dynamic Program Loader\n" + "Usage: %s [options] [--] pathname%s\n", + __libc_version, ldname, + ldd_mode ? "" : " [args]"); _exit(1); } fd = open(argv[0], O_RDONLY); - if (fd < 0) { + if (fd < 0) + { dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno)); _exit(1); } Ehdr *ehdr = map_library(fd, &app); - if (!ehdr) { + if (!ehdr) + { dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]); _exit(1); } @@ -1912,38 +2231,39 @@ void __dls3(size_t *sp, size_t *auxv) aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry); /* Find the name that would have been used for the dynamic * linker had ldd not taken its place. */ - if (ldd_mode) { - for (i=0; insegs = 1; app.loadmap->segs[0].addr = (size_t)app.map; - app.loadmap->segs[0].p_vaddr = (size_t)app.map - - (size_t)app.base; + app.loadmap->segs[0].p_vaddr = (size_t)app.map - (size_t)app.base; app.loadmap->segs[0].p_memsz = app.map_len; } argv[-3] = (void *)app.loadmap; @@ -1958,19 +2278,22 @@ void __dls3(size_t *sp, size_t *auxv) /* Load preload/needed libraries, add symbols to global namespace. */ ldso.deps = (struct dso **)no_deps; - if (env_preload) load_preload(env_preload); - load_deps(&app); - for (struct dso *p=head; p; p=p->next) + if (env_preload) + load_preload(env_preload); + load_deps(&app); + for (struct dso *p = head; p; p = p->next) add_syms(p); /* Attach to vdso, if provided by the kernel, last so that it does * not become part of the global namespace. */ - if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) { + if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) + { Ehdr *ehdr = (void *)vdso_base; Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff); vdso.phnum = ehdr->e_phnum; vdso.phentsize = ehdr->e_phentsize; - for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) { + for (i = ehdr->e_phnum; i; i--, phdr = (void *)((char *)phdr + ehdr->e_phentsize)) + { if (phdr->p_type == PT_DYNAMIC) vdso.dynv = (void *)(vdso_base + phdr->p_offset); if (phdr->p_type == PT_LOAD) @@ -1986,15 +2309,18 @@ void __dls3(size_t *sp, size_t *auxv) tail = &vdso; } - for (i=0; app.dynv[i]; i+=2) { - if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG) - app.dynv[i+1] = (size_t)&debug; - if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) { - size_t *ptr = (size_t *) app.dynv[i+1]; + for (i = 0; app.dynv[i]; i += 2) + { + if (!DT_DEBUG_INDIRECT && app.dynv[i] == DT_DEBUG) + app.dynv[i + 1] = (size_t)&debug; + if (DT_DEBUG_INDIRECT && app.dynv[i] == DT_DEBUG_INDIRECT) + { + size_t *ptr = (size_t *)app.dynv[i + 1]; *ptr = (size_t)&debug; } - if (app.dynv[i]==DT_DEBUG_INDIRECT_REL) { - size_t *ptr = (size_t *)((size_t)&app.dynv[i] + app.dynv[i+1]); + if (app.dynv[i] == DT_DEBUG_INDIRECT_REL) + { + size_t *ptr = (size_t *)((size_t)&app.dynv[i] + app.dynv[i + 1]); *ptr = (size_t)&debug; } } @@ -2011,11 +2337,13 @@ void __dls3(size_t *sp, size_t *auxv) * might result in calloc being a call to application code. */ update_tls_size(); void *initial_tls = builtin_tls; - if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) { + if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) + { initial_tls = calloc(libc.tls_size, 1); - if (!initial_tls) { + if (!initial_tls) + { dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n", - argv[0], libc.tls_size); + argv[0], libc.tls_size); _exit(127); } } @@ -2028,23 +2356,30 @@ void __dls3(size_t *sp, size_t *auxv) /* Actual copying to new TLS needs to happen after relocations, * since the TLS images might have contained relocated addresses. */ - if (initial_tls != builtin_tls) { - if (__init_tp(__copy_tls(initial_tls)) < 0) { + if (initial_tls != builtin_tls) + { + if (__init_tp(__copy_tls(initial_tls)) < 0) + { a_crash(); } - } else { + } + else + { size_t tmp_tls_size = libc.tls_size; pthread_t self = __pthread_self(); /* Temporarily set the tls size to the full size of * builtin_tls so that __copy_tls will use the same layout * as it did for before. Then check, just to be safe. */ libc.tls_size = sizeof builtin_tls; - if (__copy_tls((void*)builtin_tls) != self) a_crash(); + if (__copy_tls((void *)builtin_tls) != self) + a_crash(); libc.tls_size = tmp_tls_size; } - if (ldso_fail) _exit(127); - if (ldd_mode) _exit(0); + if (ldso_fail) + _exit(127); + if (ldd_mode) + _exit(0); /* Determine if malloc was interposed by a replacement implementation * so that calloc and the memalign family can harden against the @@ -2066,29 +2401,35 @@ void __dls3(size_t *sp, size_t *auxv) debug.state = RT_CONSISTENT; _dl_debug_state(); - if (replace_argv0) argv[0] = replace_argv0; + if (replace_argv0) + argv[0] = replace_argv0; errno = 0; - CRTJMP((void *)aux[AT_ENTRY], argv-1); - for(;;); + CRTJMP((void *)aux[AT_ENTRY], argv - 1); + for (;;) + ; } static void prepare_lazy(struct dso *p) { - size_t dyn[DYN_CNT], n, flags1=0; + size_t dyn[DYN_CNT], n, flags1 = 0; decode_vec(p->dynv, dyn, DYN_CNT); search_vec(p->dynv, &flags1, DT_FLAGS_1); if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW)) return; - n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1; - if (NEED_MIPS_GOT_RELOCS) { - size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM); - size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); - n += i-j; + n = dyn[DT_RELSZ] / 2 + dyn[DT_RELASZ] / 3 + dyn[DT_PLTRELSZ] / 2 + 1; + if (NEED_MIPS_GOT_RELOCS) + { + size_t j = 0; + search_vec(p->dynv, &j, DT_MIPS_GOTSYM); + size_t i = 0; + search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); + n += i - j; } - p->lazy = calloc(n, 3*sizeof(size_t)); - if (!p->lazy) { + p->lazy = calloc(n, 3 * sizeof(size_t)); + if (!p->lazy) + { error("Error preparing lazy relocation for %s: %m", p->name); longjmp(*rtld_fail, 1); } @@ -2106,7 +2447,8 @@ void *dlopen(const char *file, int mode) jmp_buf jb; struct dso **volatile ctor_queue = 0; - if (!file) return head; + if (!file) + return head; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); pthread_rwlock_wrlock(&lock); @@ -2116,7 +2458,8 @@ void *dlopen(const char *file, int mode) _dl_debug_state(); p = 0; - if (shutting_down) { + if (shutting_down) + { error("Cannot dlopen while program is exiting."); goto end; } @@ -2130,12 +2473,15 @@ void *dlopen(const char *file, int mode) noload = mode & RTLD_NOLOAD; rtld_fail = &jb; - if (setjmp(*rtld_fail)) { + if (setjmp(*rtld_fail)) + { /* Clean up anything new that was (partially) loaded */ revert_syms(orig_syms_tail); - for (p=orig_tail->next; p; p=next) { + for (p = orig_tail->next; p; p = next) + { next = p->next; - while (p->td_index) { + while (p->td_index) + { void *tmp = p->td_index->next; free(p->td_index); p->td_index = tmp; @@ -2149,9 +2495,11 @@ void *dlopen(const char *file, int mode) } free(ctor_queue); ctor_queue = 0; - if (!orig_tls_tail) libc.tls_head = 0; + if (!orig_tls_tail) + libc.tls_head = 0; tls_tail = orig_tls_tail; - if (tls_tail) tls_tail->next = 0; + if (tls_tail) + tls_tail->next = 0; tls_cnt = orig_tls_cnt; tls_offset = orig_tls_offset; tls_align = orig_tls_align; @@ -2160,13 +2508,14 @@ void *dlopen(const char *file, int mode) tail->next = 0; p = 0; goto end; - } else p = load_library(file, head); + } + else + p = load_library(file, head); - if (!p) { - error(noload ? - "Library %s is not already loaded" : - "Error loading shared library %s: %m", - file); + if (!p) + { + error(noload ? "Library %s is not already loaded" : "Error loading shared library %s: %m", + file); goto end; } @@ -2176,21 +2525,25 @@ void *dlopen(const char *file, int mode) pthread_mutex_lock(&init_fini_lock); int constructed = p->constructed; pthread_mutex_unlock(&init_fini_lock); - if (!constructed) ctor_queue = queue_ctors(p); - if (!p->relocated && (mode & RTLD_LAZY)) { + if (!constructed) + ctor_queue = queue_ctors(p); + if (!p->relocated && (mode & RTLD_LAZY)) + { prepare_lazy(p); - for (i=0; p->deps[i]; i++) + for (i = 0; p->deps[i]; i++) if (!p->deps[i]->relocated) prepare_lazy(p->deps[i]); } - if (!p->relocated || (mode & RTLD_GLOBAL)) { + if (!p->relocated || (mode & RTLD_GLOBAL)) + { /* Make new symbols global, at least temporarily, so we can do * relocations. If not RTLD_GLOBAL, this is reverted below. */ add_syms(p); - for (i=0; p->deps[i]; i++) + for (i = 0; p->deps[i]; i++) add_syms(p->deps[i]); } - if (!p->relocated) { + if (!p->relocated) + { reloc_all(p); } @@ -2213,9 +2566,11 @@ end: debug.state = RT_CONSISTENT; _dl_debug_state(); __release_ptc(); - if (p) gencnt++; + if (p) + gencnt++; pthread_rwlock_unlock(&lock); - if (ctor_queue) { + if (ctor_queue) + { do_init_fini(ctor_queue); free(ctor_queue); } @@ -2226,7 +2581,9 @@ end: hidden int __dl_invalid_handle(void *h) { struct dso *p; - for (p=head; p; p=p->next) if (h==p) return 0; + for (p = head; p; p = p->next) + if (h == p) + return 0; error("Invalid library handle %p", (void *)h); return 1; } @@ -2235,29 +2592,37 @@ static void *addr2dso(size_t a) { struct dso *p; size_t i; - if (DL_FDPIC) for (p=head; p; p=p->next) { - i = count_syms(p); - if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs)) - return p; - } - for (p=head; p; p=p->next) { - if (DL_FDPIC && p->loadmap) { - for (i=0; iloadmap->nsegs; i++) { - if (a-p->loadmap->segs[i].p_vaddr - < p->loadmap->segs[i].p_memsz) + if (DL_FDPIC) + for (p = head; p; p = p->next) + { + i = count_syms(p); + if (a - (size_t)p->funcdescs < i * sizeof(*p->funcdescs)) + return p; + } + for (p = head; p; p = p->next) + { + if (DL_FDPIC && p->loadmap) + { + for (i = 0; i < p->loadmap->nsegs; i++) + { + if (a - p->loadmap->segs[i].p_vaddr < p->loadmap->segs[i].p_memsz) return p; } - } else { + } + else + { Phdr *ph = p->phdr; size_t phcnt = p->phnum; size_t entsz = p->phentsize; size_t base = (size_t)p->base; - for (; phcnt--; ph=(void *)((char *)ph+entsz)) { - if (ph->p_type != PT_LOAD) continue; - if (a-base-ph->p_vaddr < ph->p_memsz) + for (; phcnt--; ph = (void *)((char *)ph + entsz)) + { + if (ph->p_type != PT_LOAD) + continue; + if (a - base - ph->p_vaddr < ph->p_memsz) return p; } - if (a-(size_t)p->map < p->map_len) + if (a - (size_t)p->map < p->map_len) return 0; } } @@ -2267,24 +2632,32 @@ static void *addr2dso(size_t a) static void *do_dlsym(struct dso *p, const char *s, void *ra) { int use_deps = 0; - if (p == head || p == RTLD_DEFAULT) { + if (p == head || p == RTLD_DEFAULT) + { p = head; - } else if (p == RTLD_NEXT) { + } + else if (p == RTLD_NEXT) + { p = addr2dso((size_t)ra); - if (!p) p=head; + if (!p) + p = head; p = p->next; - } else if (__dl_invalid_handle(p)) { + } + else if (__dl_invalid_handle(p)) + { return 0; - } else + } + else use_deps = 1; struct symdef def = find_sym2(p, s, 0, use_deps); - if (!def.sym) { + if (!def.sym) + { error("Symbol not found: %s", s); return 0; } - if ((def.sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET}); - if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC) + if ((def.sym->st_info & 0xf) == STT_TLS) + return __tls_get_addr((tls_mod_off_t[]){def.dso->tls_id, def.sym->st_value - DTP_OFFSET}); + if (DL_FDPIC && (def.sym->st_info & 0xf) == STT_FUNC) return def.dso->funcdescs + (def.sym - def.dso->syms); return laddr(def.dso, def.sym->st_value); } @@ -2303,38 +2676,42 @@ int dladdr(const void *addr_arg, Dl_info *info) p = addr2dso(addr); pthread_rwlock_unlock(&lock); - if (!p) return 0; + if (!p) + return 0; sym = p->syms; strings = p->strings; nsym = count_syms(p); - if (DL_FDPIC) { - size_t idx = (addr-(size_t)p->funcdescs) - / sizeof(*p->funcdescs); - if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) { + if (DL_FDPIC) + { + size_t idx = (addr - (size_t)p->funcdescs) / sizeof(*p->funcdescs); + if (idx < nsym && (sym[idx].st_info & 0xf) == STT_FUNC) + { best = (size_t)(p->funcdescs + idx); bestsym = sym + idx; besterr = 0; } } - if (!best) for (; nsym; nsym--, sym++) { - if (sym->st_value - && (1<<(sym->st_info&0xf) & OK_TYPES) - && (1<<(sym->st_info>>4) & OK_BINDS)) { - size_t symaddr = (size_t)laddr(p, sym->st_value); - if (symaddr > addr || symaddr <= best) - continue; - best = symaddr; - bestsym = sym; - besterr = addr - symaddr; - if (addr == symaddr) - break; + if (!best) + for (; nsym; nsym--, sym++) + { + if (sym->st_value && (1 << (sym->st_info & 0xf) & OK_TYPES) && (1 << (sym->st_info >> 4) & OK_BINDS)) + { + size_t symaddr = (size_t)laddr(p, sym->st_value); + if (symaddr > addr || symaddr <= best) + continue; + best = symaddr; + bestsym = sym; + besterr = addr - symaddr; + if (addr == symaddr) + break; + } } - } - if (best && besterr > bestsym->st_size-1) { + if (best && besterr > bestsym->st_size - 1) + { best = 0; bestsym = 0; } @@ -2342,13 +2719,14 @@ int dladdr(const void *addr_arg, Dl_info *info) info->dli_fname = p->name; info->dli_fbase = p->map; - if (!best) { + if (!best) + { info->dli_sname = 0; info->dli_saddr = 0; return 1; } - if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC) + if (DL_FDPIC && (bestsym->st_info & 0xf) == STT_FUNC) best = (size_t)(p->funcdescs + (bestsym - p->syms)); info->dli_sname = strings + bestsym->st_name; info->dli_saddr = (void *)best; @@ -2374,43 +2752,50 @@ hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void /* Map the symbol name to a time64 version of itself according to the * pattern used for naming the redirected time64 symbols. */ size_t l = strnlen(s, sizeof redir); - if (l<4 || l==sizeof redir) goto no_redir; - if (s[l-2]=='_' && s[l-1]=='r') { + if (l < 4 || l == sizeof redir) + goto no_redir; + if (s[l - 2] == '_' && s[l - 1] == 'r') + { l -= 2; - suffix2 = s+l; + suffix2 = s + l; } - if (l<4) goto no_redir; - if (!strcmp(s+l-4, "time")) suffix = "64"; - else suffix = "_time64"; + if (l < 4) + goto no_redir; + if (!strcmp(s + l - 4, "time")) + suffix = "64"; + else + suffix = "_time64"; /* Use the presence of the remapped symbol name in libc to determine * whether it's one that requires time64 redirection; replace if so. */ snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2); - if (find_sym(&ldso, redir, 1).sym) s = redir; + if (find_sym(&ldso, redir, 1).sym) + s = redir; no_redir: #endif return __dlsym(p, s, ra); } -int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data) +int dl_iterate_phdr(int (*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data) { struct dso *current; struct dl_phdr_info info; int ret = 0; - for(current = head; current;) { - info.dlpi_addr = (uintptr_t)current->base; - info.dlpi_name = current->name; - info.dlpi_phdr = current->phdr; - info.dlpi_phnum = current->phnum; - info.dlpi_adds = gencnt; - info.dlpi_subs = 0; + for (current = head; current;) + { + info.dlpi_addr = (uintptr_t)current->base; + info.dlpi_name = current->name; + info.dlpi_phdr = current->phdr; + info.dlpi_phnum = current->phnum; + info.dlpi_adds = gencnt; + info.dlpi_subs = 0; info.dlpi_tls_modid = current->tls_id; - info.dlpi_tls_data = !current->tls_id ? 0 : - __tls_get_addr((tls_mod_off_t[]){current->tls_id,0}); + info.dlpi_tls_data = !current->tls_id ? 0 : __tls_get_addr((tls_mod_off_t[]){current->tls_id, 0}); - ret = (callback)(&info, sizeof (info), data); + ret = (callback)(&info, sizeof(info), data); - if (ret != 0) break; + if (ret != 0) + break; pthread_rwlock_rdlock(&lock); current = current->next; @@ -2423,7 +2808,8 @@ static void error_impl(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - if (!runtime) { + if (!runtime) + { vdprintf(2, fmt, ap); dprintf(2, "\n"); ldso_fail = 1; diff --git a/mkrtos_user/lib/mlibc/src/env/__init_tls.c b/mkrtos_user/lib/mlibc/src/env/__init_tls.c index d553059e4..cdab7f4c9 100644 --- a/mkrtos_user/lib/mlibc/src/env/__init_tls.c +++ b/mkrtos_user/lib/mlibc/src/env/__init_tls.c @@ -8,7 +8,9 @@ #include "libc.h" #include "atomic.h" #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif volatile int __thread_list_lock; int __init_tp(void *p) @@ -16,11 +18,21 @@ int __init_tp(void *p) pthread_t td = p; td->self = td; +#ifdef NO_LITTLE_MODE int r = __set_thread_area(TP_ADJ(p)); - if (r < 0) return -1; - if (!r) libc.can_do_threads = 1; +#else + int r = be_set_thread_area(TP_ADJ(p)); +#endif + if (r < 0) + return -1; + if (!r) + libc.can_do_threads = 1; td->detach_state = DT_JOINABLE; +#ifdef NO_LITTLE_MODE td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock); +#else + td->tid = be_set_tid_address(&__thread_list_lock); +#endif td->locale = &libc.global_locale; td->robust_list.head = &td->robust_list.head; td->sysinfo = __sysinfo; @@ -28,7 +40,8 @@ int __init_tp(void *p) return 0; } -static struct builtin_tls { +static struct builtin_tls +{ char c; struct pthread pt; void *space[16]; @@ -45,13 +58,14 @@ void *__copy_tls(unsigned char *mem) uintptr_t *dtv; #ifdef TLS_ABOVE_TP - dtv = (uintptr_t*)(mem + libc.tls_size) - (libc.tls_cnt + 1); + dtv = (uintptr_t *)(mem + libc.tls_size) - (libc.tls_cnt + 1); - mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1); + mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align - 1); td = (pthread_t)mem; mem += sizeof(struct pthread); - for (i=1, p=libc.tls_head; p; i++, p=p->next) { + for (i = 1, p = libc.tls_head; p; i++, p = p->next) + { dtv[i] = (uintptr_t)(mem + p->offset) + DTP_OFFSET; memcpy(mem + p->offset, p->image, p->len); } @@ -59,10 +73,11 @@ void *__copy_tls(unsigned char *mem) dtv = (uintptr_t *)mem; mem += libc.tls_size - sizeof(struct pthread); - mem -= (uintptr_t)mem & (libc.tls_align-1); + mem -= (uintptr_t)mem & (libc.tls_align - 1); td = (pthread_t)mem; - for (i=1, p=libc.tls_head; p; i++, p=p->next) { + for (i = 1, p = libc.tls_head; p; i++, p = p->next) + { dtv[i] = (uintptr_t)(mem - p->offset) + DTP_OFFSET; memcpy(mem - p->offset, p->image, p->len); } @@ -84,11 +99,12 @@ static void static_init_tls(size_t *aux) { unsigned char *p; size_t n; - Phdr *phdr, *tls_phdr=0; + Phdr *phdr, *tls_phdr = 0; size_t base = 0; void *mem; - for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) { + for (p = (void *)aux[AT_PHDR], n = aux[AT_PHNUM]; n; n--, p += aux[AT_PHENT]) + { phdr = (void *)p; if (phdr->p_type == PT_PHDR) base = aux[AT_PHDR] - phdr->p_vaddr; @@ -97,13 +113,13 @@ static void static_init_tls(size_t *aux) if (phdr->p_type == PT_TLS) tls_phdr = phdr; if (phdr->p_type == PT_GNU_STACK && - phdr->p_memsz > __default_stacksize) + phdr->p_memsz > __default_stacksize) __default_stacksize = - phdr->p_memsz < DEFAULT_STACK_MAX ? - phdr->p_memsz : DEFAULT_STACK_MAX; + phdr->p_memsz < DEFAULT_STACK_MAX ? phdr->p_memsz : DEFAULT_STACK_MAX; } - if (tls_phdr) { + if (tls_phdr) + { main_tls.image = (void *)(base + tls_phdr->p_vaddr); main_tls.len = tls_phdr->p_filesz; main_tls.size = tls_phdr->p_memsz; @@ -112,37 +128,46 @@ static void static_init_tls(size_t *aux) libc.tls_head = &main_tls; } - main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image) - & (main_tls.align-1); + main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image) & (main_tls.align - 1); #ifdef TLS_ABOVE_TP main_tls.offset = GAP_ABOVE_TP; - main_tls.offset += (-GAP_ABOVE_TP + (uintptr_t)main_tls.image) - & (main_tls.align-1); + main_tls.offset += (-GAP_ABOVE_TP + (uintptr_t)main_tls.image) & (main_tls.align - 1); #else main_tls.offset = main_tls.size; #endif - if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN; + if (main_tls.align < MIN_TLS_ALIGN) + main_tls.align = MIN_TLS_ALIGN; libc.tls_align = main_tls.align; - libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread) + libc.tls_size = 2 * sizeof(void *) + sizeof(struct pthread) #ifdef TLS_ABOVE_TP - + main_tls.offset + + main_tls.offset #endif - + main_tls.size + main_tls.align - + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN; + + main_tls.size + main_tls.align + MIN_TLS_ALIGN - 1 & + -MIN_TLS_ALIGN; - if (libc.tls_size > sizeof builtin_tls) { + if (libc.tls_size > sizeof builtin_tls) + { #ifndef SYS_mmap2 #define SYS_mmap2 SYS_mmap #endif +#ifdef NO_LITTLE_MODE mem = (void *)__syscall( SYS_mmap2, - 0, libc.tls_size, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - /* -4095...-1 cast to void * will crash on dereference anyway, - * so don't bloat the init code checking for error codes and - * explicitly calling a_crash(). */ - } else { + 0, libc.tls_size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +/* -4095...-1 cast to void * will crash on dereference anyway, + * so don't bloat the init code checking for error codes and + * explicitly calling a_crash(). */ +#else + // mem = (void *)be_mmap2( + // 0, libc.tls_size, PROT_READ | PROT_WRITE, + // MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + a_crash(); +#endif + } + else + { mem = builtin_tls; } diff --git a/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c b/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c index 300faf4af..a8f103a79 100644 --- a/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c +++ b/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c @@ -36,7 +36,7 @@ __init_libc(char **envp, char *pn) } else if (auxv[i] == 0xfe) { - extern void u_env_init(void * * in_env); + extern void u_env_init(void **in_env); u_env_init((void *)auxv[i + 1]); } @@ -54,13 +54,11 @@ __init_libc(char **envp, char *pn) for (i = 0; pn[i]; i++) if (pn[i] == '/') __progname = pn + i + 1; - __init_tls(aux); __init_ssp((void *)aux[AT_RANDOM]); - if (aux[AT_UID] == aux[AT_EUID] && aux[AT_GID] == aux[AT_EGID] && !aux[AT_SECURE]) return; - +#ifdef NO_LITTLE_MODE struct pollfd pfd[3] = {{.fd = 0}, {.fd = 1}, {.fd = 2}}; int r = #ifdef SYS_poll @@ -74,6 +72,7 @@ __init_libc(char **envp, char *pn) if (pfd[i].revents & POLLNVAL) if (__sys_open("/dev/null", O_RDWR) < 0) a_crash(); +#endif libc.secure = 1; } @@ -103,7 +102,10 @@ int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, /* Barrier against hoisting application code or anything using ssp * or thread pointer prior to its initialization above. */ lsm2_fn *stage2 = libc_start_main_stage2; - __asm__("" : "+r"(stage2) : : "memory"); + __asm__("" + : "+r"(stage2) + : + : "memory"); return stage2(main, argc, argv); } int __libc_start_main_init(int (*main)(int, char **, char **), int argc, char **argv, @@ -121,7 +123,10 @@ int __libc_start_main_init(int (*main)(int, char **, char **), int argc, char ** /* Barrier against hoisting application code or anything using ssp * or thread pointer prior to its initialization above. */ lsm2_fn *stage2 = libc_start_main_stage2; - __asm__("" : "+r"(stage2) : : "memory"); + __asm__("" + : "+r"(stage2) + : + : "memory"); return stage2(main, argc, argv); } diff --git a/mkrtos_user/lib/mlibc/src/exit/_Exit.c b/mkrtos_user/lib/mlibc/src/exit/_Exit.c index 7a6115c7b..556e0d9e0 100644 --- a/mkrtos_user/lib/mlibc/src/exit/_Exit.c +++ b/mkrtos_user/lib/mlibc/src/exit/_Exit.c @@ -1,8 +1,16 @@ #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif _Noreturn void _Exit(int ec) { __syscall(SYS_exit_group, ec); - for (;;) __syscall(SYS_exit, ec); +#ifdef NO_LITTLE_MODE + for (;;) + __syscall(SYS_exit, ec); +#else + for (;;) + be_exit(ec); +#endif } diff --git a/mkrtos_user/lib/mlibc/src/exit/exit.c b/mkrtos_user/lib/mlibc/src/exit/exit.c index a6869b375..41b6b8d0f 100644 --- a/mkrtos_user/lib/mlibc/src/exit/exit.c +++ b/mkrtos_user/lib/mlibc/src/exit/exit.c @@ -17,8 +17,8 @@ extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_ static void libc_exit_fini(void) { uintptr_t a = (uintptr_t)&__fini_array_end; - for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)())) - (*(void (**)())(a-sizeof(void(*)())))(); + for (; a > (uintptr_t)&__fini_array_start; a -= sizeof(void (*)())) + (*(void (**)())(a - sizeof(void (*)())))(); _fini(); } diff --git a/mkrtos_user/lib/mlibc/src/misc/ioctl.c b/mkrtos_user/lib/mlibc/src/misc/ioctl.c index 35804f026..fb51d8baa 100644 --- a/mkrtos_user/lib/mlibc/src/misc/ioctl.c +++ b/mkrtos_user/lib/mlibc/src/misc/ioctl.c @@ -9,75 +9,85 @@ #include #include "syscall.h" -#define alignof(t) offsetof(struct { char c; t x; }, x) +#define alignof(t) offsetof( \ + struct { char c; t x; }, x) #define W 1 #define R 2 #define WR 3 -struct ioctl_compat_map { +struct ioctl_compat_map +{ int new_req, old_req; unsigned char old_size, dir, force_align, noffs; unsigned char offsets[8]; }; -#define NINTH(a,b,c,d,e,f,g,h,i,...) i -#define COUNT(...) NINTH(__VA_ARGS__,8,7,6,5,4,3,2,1,0) -#define OFFS(...) COUNT(__VA_ARGS__), { __VA_ARGS__ } +#define NINTH(a, b, c, d, e, f, g, h, i, ...) i +#define COUNT(...) NINTH(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define OFFS(...) \ + COUNT(__VA_ARGS__), { __VA_ARGS__ } /* yields a type for a struct with original size n, with a misaligned * timeval/timespec expanded from 32- to 64-bit. for use with ioctl * number producing macros; only size of result is meaningful. */ -#define new_misaligned(n) struct { int i; time_t t; char c[(n)-4]; } +#define new_misaligned(n) \ + struct \ + { \ + int i; \ + time_t t; \ + char c[(n)-4]; \ + } -struct v4l2_event { +struct v4l2_event +{ uint32_t a; uint64_t b[8]; uint32_t c[2], ts[2], d[9]; }; static const struct ioctl_compat_map compat_map[] = { - { SIOCGSTAMP, SIOCGSTAMP_OLD, 8, R, 0, OFFS(0, 4) }, - { SIOCGSTAMPNS, SIOCGSTAMPNS_OLD, 8, R, 0, OFFS(0, 4) }, + {SIOCGSTAMP, SIOCGSTAMP_OLD, 8, R, 0, OFFS(0, 4)}, + {SIOCGSTAMPNS, SIOCGSTAMPNS_OLD, 8, R, 0, OFFS(0, 4)}, /* SNDRV_TIMER_IOCTL_STATUS */ - { _IOR('T', 0x14, char[96]), _IOR('T', 0x14, 88), 88, R, 0, OFFS(0,4) }, + {_IOR('T', 0x14, char[96]), _IOR('T', 0x14, 88), 88, R, 0, OFFS(0, 4)}, /* SNDRV_PCM_IOCTL_STATUS[_EXT] */ - { _IOR('A', 0x20, char[128]), _IOR('A', 0x20, char[108]), 108, R, 1, OFFS(4,8,12,16,52,56,60,64) }, - { _IOWR('A', 0x24, char[128]), _IOWR('A', 0x24, char[108]), 108, WR, 1, OFFS(4,8,12,16,52,56,60,64) }, + {_IOR('A', 0x20, char[128]), _IOR('A', 0x20, char[108]), 108, R, 1, OFFS(4, 8, 12, 16, 52, 56, 60, 64)}, + {_IOWR('A', 0x24, char[128]), _IOWR('A', 0x24, char[108]), 108, WR, 1, OFFS(4, 8, 12, 16, 52, 56, 60, 64)}, /* SNDRV_RAWMIDI_IOCTL_STATUS */ - { _IOWR('W', 0x20, char[48]), _IOWR('W', 0x20, char[36]), 36, WR, 1, OFFS(4,8) }, + {_IOWR('W', 0x20, char[48]), _IOWR('W', 0x20, char[36]), 36, WR, 1, OFFS(4, 8)}, /* SNDRV_PCM_IOCTL_SYNC_PTR - with 3 subtables */ - { _IOWR('A', 0x23, char[136]), _IOWR('A', 0x23, char[132]), 0, WR, 1, 0 }, - { 0, 0, 4, WR, 1, 0 }, /* snd_pcm_sync_ptr (flags only) */ - { 0, 0, 32, WR, 1, OFFS(8,12,16,24,28) }, /* snd_pcm_mmap_status */ - { 0, 0, 4, WR, 1, 0 }, /* snd_pcm_mmap_control (each member) */ + {_IOWR('A', 0x23, char[136]), _IOWR('A', 0x23, char[132]), 0, WR, 1, 0}, + {0, 0, 4, WR, 1, 0}, /* snd_pcm_sync_ptr (flags only) */ + {0, 0, 32, WR, 1, OFFS(8, 12, 16, 24, 28)}, /* snd_pcm_mmap_status */ + {0, 0, 4, WR, 1, 0}, /* snd_pcm_mmap_control (each member) */ /* VIDIOC_QUERYBUF, VIDIOC_QBUF, VIDIOC_DQBUF, VIDIOC_PREPARE_BUF */ - { _IOWR('V', 9, new_misaligned(68)), _IOWR('V', 9, char[68]), 68, WR, 1, OFFS(20, 24) }, - { _IOWR('V', 15, new_misaligned(68)), _IOWR('V', 15, char[68]), 68, WR, 1, OFFS(20, 24) }, - { _IOWR('V', 17, new_misaligned(68)), _IOWR('V', 17, char[68]), 68, WR, 1, OFFS(20, 24) }, - { _IOWR('V', 93, new_misaligned(68)), _IOWR('V', 93, char[68]), 68, WR, 1, OFFS(20, 24) }, + {_IOWR('V', 9, new_misaligned(68)), _IOWR('V', 9, char[68]), 68, WR, 1, OFFS(20, 24)}, + {_IOWR('V', 15, new_misaligned(68)), _IOWR('V', 15, char[68]), 68, WR, 1, OFFS(20, 24)}, + {_IOWR('V', 17, new_misaligned(68)), _IOWR('V', 17, char[68]), 68, WR, 1, OFFS(20, 24)}, + {_IOWR('V', 93, new_misaligned(68)), _IOWR('V', 93, char[68]), 68, WR, 1, OFFS(20, 24)}, /* VIDIOC_DQEVENT */ - { _IOR('V', 89, new_misaligned(120)), _IOR('V', 89, struct v4l2_event), sizeof(struct v4l2_event), - R, 0, OFFS(offsetof(struct v4l2_event, ts[0]), offsetof(struct v4l2_event, ts[1])) }, + {_IOR('V', 89, new_misaligned(120)), _IOR('V', 89, struct v4l2_event), sizeof(struct v4l2_event), + R, 0, OFFS(offsetof(struct v4l2_event, ts[0]), offsetof(struct v4l2_event, ts[1]))}, /* VIDIOC_OMAP3ISP_STAT_REQ */ - { _IOWR('V', 192+6, char[32]), _IOWR('V', 192+6, char[24]), 22, WR, 0, OFFS(0,4) }, + {_IOWR('V', 192 + 6, char[32]), _IOWR('V', 192 + 6, char[24]), 22, WR, 0, OFFS(0, 4)}, /* PPPIOCGIDLE */ - { _IOR('t', 63, char[16]), _IOR('t', 63, char[8]), 8, R, 0, OFFS(0,4) }, + {_IOR('t', 63, char[16]), _IOR('t', 63, char[8]), 8, R, 0, OFFS(0, 4)}, /* PPGETTIME, PPSETTIME */ - { _IOR('p', 0x95, char[16]), _IOR('p', 0x95, char[8]), 8, R, 0, OFFS(0,4) }, - { _IOW('p', 0x96, char[16]), _IOW('p', 0x96, char[8]), 8, W, 0, OFFS(0,4) }, + {_IOR('p', 0x95, char[16]), _IOR('p', 0x95, char[8]), 8, R, 0, OFFS(0, 4)}, + {_IOW('p', 0x96, char[16]), _IOW('p', 0x96, char[8]), 8, W, 0, OFFS(0, 4)}, /* LPSETTIMEOUT */ - { _IOW(0x6, 0xf, char[16]), 0x060f, 8, W, 0, OFFS(0,4) }, + {_IOW(0x6, 0xf, char[16]), 0x060f, 8, W, 0, OFFS(0, 4)}, }; static void convert_ioctl_struct(const struct ioctl_compat_map *map, char *old, char *new, int dir) @@ -85,46 +95,58 @@ static void convert_ioctl_struct(const struct ioctl_compat_map *map, char *old, int new_offset = 0; int old_offset = 0; int old_size = map->old_size; - if (!(dir & map->dir)) return; - if (!map->old_size) { + if (!(dir & map->dir)) + return; + if (!map->old_size) + { /* offsets hard-coded for SNDRV_PCM_IOCTL_SYNC_PTR; * if another exception appears this needs changing. */ - convert_ioctl_struct(map+1, old, new, dir); - convert_ioctl_struct(map+2, old+4, new+8, dir); + convert_ioctl_struct(map + 1, old, new, dir); + convert_ioctl_struct(map + 2, old + 4, new + 8, dir); /* snd_pcm_mmap_control, special-cased due to kernel * type definition having been botched. */ - int adj = BYTE_ORDER==BIG_ENDIAN ? 4 : 0; - convert_ioctl_struct(map+3, old+68, new+72+adj, dir); - convert_ioctl_struct(map+3, old+72, new+76+3*adj, dir); + int adj = BYTE_ORDER == BIG_ENDIAN ? 4 : 0; + convert_ioctl_struct(map + 3, old + 68, new + 72 + adj, dir); + convert_ioctl_struct(map + 3, old + 72, new + 76 + 3 * adj, dir); return; } - for (int i=0; i < map->noffs; i++) { + for (int i = 0; i < map->noffs; i++) + { int ts_offset = map->offsets[i]; - int len = ts_offset-old_offset; - if (dir==W) memcpy(old+old_offset, new+new_offset, len); - else memcpy(new+new_offset, old+old_offset, len); + int len = ts_offset - old_offset; + if (dir == W) + memcpy(old + old_offset, new + new_offset, len); + else + memcpy(new + new_offset, old + old_offset, len); new_offset += len; old_offset += len; long long new_ts; long old_ts; int align = map->force_align ? sizeof(time_t) : alignof(time_t); - new_offset += (align-1) & -new_offset; - if (dir==W) { - memcpy(&new_ts, new+new_offset, sizeof new_ts); + new_offset += (align - 1) & -new_offset; + if (dir == W) + { + memcpy(&new_ts, new + new_offset, sizeof new_ts); old_ts = new_ts; - memcpy(old+old_offset, &old_ts, sizeof old_ts); - } else { - memcpy(&old_ts, old+old_offset, sizeof old_ts); + memcpy(old + old_offset, &old_ts, sizeof old_ts); + } + else + { + memcpy(&old_ts, old + old_offset, sizeof old_ts); new_ts = old_ts; - memcpy(new+new_offset, &new_ts, sizeof new_ts); + memcpy(new + new_offset, &new_ts, sizeof new_ts); } new_offset += sizeof new_ts; old_offset += sizeof old_ts; } - if (dir==W) memcpy(old+old_offset, new+new_offset, old_size-old_offset); - else memcpy(new+new_offset, old+old_offset, old_size-old_offset); + if (dir == W) + memcpy(old + old_offset, new + new_offset, old_size - old_offset); + else + memcpy(new + new_offset, old + old_offset, old_size - old_offset); } - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif int ioctl(int fd, int req, ...) { void *arg; @@ -132,17 +154,30 @@ int ioctl(int fd, int req, ...) va_start(ap, req); arg = va_arg(ap, void *); va_end(ap); +#ifdef NO_LITTLE_MODE int r = __syscall(SYS_ioctl, fd, req, arg); - if (SIOCGSTAMP != SIOCGSTAMP_OLD && req && r==-ENOTTY) { - for (int i=0; i= len) return ERANGE; + if (!buf) + len = 0; +#ifdef NO_LITTLE_MODE + if ((err = __syscall(SYS_ioctl, fd, TIOCGPTN, &pty))) + return -err; +#else + if ((err = be_ioctl(fd, TIOCGPTN, &pty))) + return -err; +#endif + if (snprintf(buf, len, "/dev/pts/%d", pty) >= len) + return ERANGE; return 0; } diff --git a/mkrtos_user/lib/mlibc/src/mman/mmap.c b/mkrtos_user/lib/mlibc/src/mman/mmap.c index 43e5e0294..895f9a9cf 100644 --- a/mkrtos_user/lib/mlibc/src/mman/mmap.c +++ b/mkrtos_user/lib/mlibc/src/mman/mmap.c @@ -4,34 +4,43 @@ #include #include #include "syscall.h" - -static void dummy(void) { } +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif +static void dummy(void) {} weak_alias(dummy, __vm_wait); #define UNIT SYSCALL_MMAP2_UNIT -#define OFF_MASK ((-0x2000ULL << (8*sizeof(syscall_arg_t)-1)) | (UNIT-1)) +#define OFF_MASK ((-0x2000ULL << (8 * sizeof(syscall_arg_t) - 1)) | (UNIT - 1)) void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off) { long ret; - if (off & OFF_MASK) { + if (off & OFF_MASK) + { errno = EINVAL; return MAP_FAILED; } - if (len >= PTRDIFF_MAX) { + if (len >= PTRDIFF_MAX) + { errno = ENOMEM; return MAP_FAILED; } - if (flags & MAP_FIXED) { + if (flags & MAP_FIXED) + { __vm_wait(); } #ifdef SYS_mmap2 - ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT); +#ifdef NO_LITTLE_MODE + ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off / UNIT); +#else + ret = be_mmap2(start, len, prot, flags, fd, off / UNIT); +#endif #else ret = __syscall(SYS_mmap, start, len, prot, flags, fd, off); #endif /* Fixup incorrect EPERM from kernel. */ - if (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED)) + if (ret == -EPERM && !start && (flags & MAP_ANON) && !(flags & MAP_FIXED)) ret = -ENOMEM; return (void *)__syscall_ret(ret); } diff --git a/mkrtos_user/lib/mlibc/src/mman/munmap.c b/mkrtos_user/lib/mlibc/src/mman/munmap.c index 2bf83bbe9..53b8c2300 100644 --- a/mkrtos_user/lib/mlibc/src/mman/munmap.c +++ b/mkrtos_user/lib/mlibc/src/mman/munmap.c @@ -1,13 +1,19 @@ #include #include "syscall.h" - -static void dummy(void) { } +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif +static void dummy(void) {} weak_alias(dummy, __vm_wait); int __munmap(void *start, size_t len) { __vm_wait(); +#ifdef NO_LITTLE_MODE return syscall(SYS_munmap, start, len); +#else + return be_munmap(start, len); +#endif } weak_alias(__munmap, munmap); diff --git a/mkrtos_user/lib/mlibc/src/process/posix_spawn.c b/mkrtos_user/lib/mlibc/src/process/posix_spawn.c index 728551b36..8b1fab5b2 100644 --- a/mkrtos_user/lib/mlibc/src/process/posix_spawn.c +++ b/mkrtos_user/lib/mlibc/src/process/posix_spawn.c @@ -9,8 +9,11 @@ #include "lock.h" #include "pthread_impl.h" #include "fdop.h" - -struct args { +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif +struct args +{ int p[2]; sigset_t oldmask; const char *path; @@ -47,92 +50,115 @@ static int child(void *args_vp) * reduce overhead, sigaction has tracked for us which signals * potentially have a signal handler. */ __get_handler_set(&hset); - for (i=1; i<_NSIG; i++) { - if ((attr->__flags & POSIX_SPAWN_SETSIGDEF) - && sigismember(&attr->__def, i)) { + for (i = 1; i < _NSIG; i++) + { + if ((attr->__flags & POSIX_SPAWN_SETSIGDEF) && sigismember(&attr->__def, i)) + { sa.sa_handler = SIG_DFL; - } else if (sigismember(&hset, i)) { - if (i-32<3U) { + } + else if (sigismember(&hset, i)) + { + if (i - 32 < 3U) + { sa.sa_handler = SIG_IGN; - } else { + } + else + { __libc_sigaction(i, 0, &sa); - if (sa.sa_handler==SIG_IGN) continue; + if (sa.sa_handler == SIG_IGN) + continue; sa.sa_handler = SIG_DFL; } - } else { + } + else + { continue; } __libc_sigaction(i, &sa, 0); } if (attr->__flags & POSIX_SPAWN_SETSID) - if ((ret=__syscall(SYS_setsid)) < 0) + if ((ret = __syscall(SYS_setsid)) < 0) goto fail; if (attr->__flags & POSIX_SPAWN_SETPGROUP) - if ((ret=__syscall(SYS_setpgid, 0, attr->__pgrp))) + if ((ret = __syscall(SYS_setpgid, 0, attr->__pgrp))) goto fail; /* Use syscalls directly because the library functions attempt * to do a multi-threaded synchronized id-change, which would * trash the parent's state. */ if (attr->__flags & POSIX_SPAWN_RESETIDS) - if ((ret=__syscall(SYS_setgid, __syscall(SYS_getgid))) || - (ret=__syscall(SYS_setuid, __syscall(SYS_getuid))) ) + if ((ret = __syscall(SYS_setgid, __syscall(SYS_getgid))) || + (ret = __syscall(SYS_setuid, __syscall(SYS_getuid)))) goto fail; - if (fa && fa->__actions) { + if (fa && fa->__actions) + { struct fdop *op; int fd; - for (op = fa->__actions; op->next; op = op->next); - for (; op; op = op->prev) { + for (op = fa->__actions; op->next; op = op->next) + ; + for (; op; op = op->prev) + { /* It's possible that a file operation would clobber * the pipe fd used for synchronizing with the * parent. To avoid that, we dup the pipe onto * an unoccupied fd. */ - if (op->fd == p) { + if (op->fd == p) + { ret = __syscall(SYS_dup, p); - if (ret < 0) goto fail; + if (ret < 0) + goto fail; __syscall(SYS_close, p); p = ret; } - switch(op->cmd) { + switch (op->cmd) + { case FDOP_CLOSE: __syscall(SYS_close, op->fd); break; case FDOP_DUP2: fd = op->srcfd; - if (fd == p) { + if (fd == p) + { ret = -EBADF; goto fail; } - if (fd != op->fd) { - if ((ret=__sys_dup2(fd, op->fd))<0) + if (fd != op->fd) + { + if ((ret = __sys_dup2(fd, op->fd)) < 0) goto fail; - } else { + } + else + { ret = __syscall(SYS_fcntl, fd, F_GETFD); ret = __syscall(SYS_fcntl, fd, F_SETFD, - ret & ~FD_CLOEXEC); - if (ret<0) + ret & ~FD_CLOEXEC); + if (ret < 0) goto fail; } break; case FDOP_OPEN: fd = __sys_open(op->path, op->oflag, op->mode); - if ((ret=fd) < 0) goto fail; - if (fd != op->fd) { - if ((ret=__sys_dup2(fd, op->fd))<0) + if ((ret = fd) < 0) + goto fail; + if (fd != op->fd) + { + if ((ret = __sys_dup2(fd, op->fd)) < 0) goto fail; __syscall(SYS_close, fd); } break; case FDOP_CHDIR: ret = __syscall(SYS_chdir, op->path); - if (ret<0) goto fail; + if (ret < 0) + goto fail; break; case FDOP_FCHDIR: ret = __syscall(SYS_fchdir, op->fd); - if (ret<0) goto fail; + if (ret < 0) + goto fail; break; } } @@ -144,8 +170,7 @@ static int child(void *args_vp) * in this process there are no threads or signal handlers. */ __syscall(SYS_fcntl, p, F_SETFD, FD_CLOEXEC); - pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK) - ? &attr->__mask : &args->oldmask, 0); + pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK) ? &attr->__mask : &args->oldmask, 0); int (*exec)(const char *, char *const *, char *const *) = attr->__fn ? (int (*)())attr->__fn : execve; @@ -156,19 +181,25 @@ static int child(void *args_vp) fail: /* Since sizeof errno < PIPE_BUF, the write is atomic. */ ret = -ret; - if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0); + if (ret) +#ifdef NO_LITTLE_MODE + while (__syscall(SYS_write, p, &ret, sizeof ret) < 0) + ; +#else + while (be_write(p, &ret, sizeof ret) < 0) + ; +#endif _exit(127); } - int posix_spawn(pid_t *restrict res, const char *restrict path, - const posix_spawn_file_actions_t *fa, - const posix_spawnattr_t *restrict attr, - char *const argv[restrict], char *const envp[restrict]) + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *restrict attr, + char *const argv[restrict], char *const envp[restrict]) { pid_t pid; - char stack[1024+PATH_MAX]; - int ec=0, cs; + char stack[1024 + PATH_MAX]; + int ec = 0, cs; struct args args; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); @@ -184,27 +215,34 @@ int posix_spawn(pid_t *restrict res, const char *restrict path, * by abort and against leaking the pipe fd to fork-without-exec. */ LOCK(__abort_lock); - if (pipe2(args.p, O_CLOEXEC)) { + if (pipe2(args.p, O_CLOEXEC)) + { UNLOCK(__abort_lock); ec = errno; goto fail; } - pid = __clone(child, stack+sizeof stack, - CLONE_VM|CLONE_VFORK|SIGCHLD, &args); + pid = __clone(child, stack + sizeof stack, + CLONE_VM | CLONE_VFORK | SIGCHLD, &args); close(args.p[1]); UNLOCK(__abort_lock); - if (pid > 0) { - if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0; - else waitpid(pid, &(int){0}, 0); - } else { + if (pid > 0) + { + if (read(args.p[0], &ec, sizeof ec) != sizeof ec) + ec = 0; + else + waitpid(pid, &(int){0}, 0); + } + else + { ec = -pid; } close(args.p[0]); - if (!ec && res) *res = pid; + if (!ec && res) + *res = pid; fail: pthread_sigmask(SIG_SETMASK, &args.oldmask, 0); diff --git a/mkrtos_user/lib/mlibc/src/stdio/__fdopen.c b/mkrtos_user/lib/mlibc/src/stdio/__fdopen.c index 116e78e56..9ad901015 100644 --- a/mkrtos_user/lib/mlibc/src/stdio/__fdopen.c +++ b/mkrtos_user/lib/mlibc/src/stdio/__fdopen.c @@ -5,6 +5,9 @@ #include #include #include "libc.h" +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif FILE *__fdopen(int fd, const char *mode) { @@ -12,25 +15,30 @@ FILE *__fdopen(int fd, const char *mode) struct winsize wsz; /* Check for valid initial mode character */ - if (!strchr("rwa", *mode)) { + if (!strchr("rwa", *mode)) + { errno = EINVAL; return 0; } /* Allocate FILE+buffer or fail */ - if (!(f=malloc(sizeof *f + UNGET + BUFSIZ))) return 0; + if (!(f = malloc(sizeof *f + UNGET + BUFSIZ))) + return 0; /* Zero-fill only the struct, not the buffer */ memset(f, 0, sizeof *f); /* Impose mode restrictions */ - if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; + if (!strchr(mode, '+')) + f->flags = (*mode == 'r') ? F_NOWR : F_NORD; /* Apply close-on-exec flag */ - if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); + if (strchr(mode, 'e')) + __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); /* Set append mode on fd if opened for append */ - if (*mode == 'a') { + if (*mode == 'a') + { int flags = __syscall(SYS_fcntl, fd, F_GETFL); if (!(flags & O_APPEND)) __syscall(SYS_fcntl, fd, F_SETFL, flags | O_APPEND); @@ -43,16 +51,21 @@ FILE *__fdopen(int fd, const char *mode) /* Activate line buffered mode for terminals */ f->lbf = EOF; +#ifdef NO_LITTLE_MODE if (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz)) f->lbf = '\n'; - +#else + if (!(f->flags & F_NOWR) && !be_ioctl(fd, TIOCGWINSZ, &wsz)) + f->lbf = '\n'; +#endif /* Initialize op ptrs. No problem if some are unneeded. */ f->read = __stdio_read; f->write = __stdio_write; f->seek = __stdio_seek; f->close = __stdio_close; - if (!libc.threaded) f->lock = -1; + if (!libc.threaded) + f->lock = -1; /* Add new FILE to open file list */ return __ofl_add(f); diff --git a/mkrtos_user/lib/mlibc/src/stdio/__stdio_write.c b/mkrtos_user/lib/mlibc/src/stdio/__stdio_write.c index d2d89475b..cdfbe18d9 100644 --- a/mkrtos_user/lib/mlibc/src/stdio/__stdio_write.c +++ b/mkrtos_user/lib/mlibc/src/stdio/__stdio_write.c @@ -1,32 +1,42 @@ #include "stdio_impl.h" #include - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) { struct iovec iovs[2] = { - { .iov_base = f->wbase, .iov_len = f->wpos-f->wbase }, - { .iov_base = (void *)buf, .iov_len = len } - }; + {.iov_base = f->wbase, .iov_len = f->wpos - f->wbase}, + {.iov_base = (void *)buf, .iov_len = len}}; struct iovec *iov = iovs; size_t rem = iov[0].iov_len + iov[1].iov_len; int iovcnt = 2; ssize_t cnt; - for (;;) { + for (;;) + { +#ifdef NO_LITTLE_MODE cnt = syscall(SYS_writev, f->fd, iov, iovcnt); - if (cnt == rem) { +#else + cnt = be_writev(f->fd, iov, iovcnt); +#endif + if (cnt == rem) + { f->wend = f->buf + f->buf_size; f->wpos = f->wbase = f->buf; return len; } - if (cnt < 0) { + if (cnt < 0) + { f->wpos = f->wbase = f->wend = 0; f->flags |= F_ERR; - return iovcnt == 2 ? 0 : len-iov[0].iov_len; + return iovcnt == 2 ? 0 : len - iov[0].iov_len; } rem -= cnt; - if (cnt > iov[0].iov_len) { + if (cnt > iov[0].iov_len) + { cnt -= iov[0].iov_len; - iov++; iovcnt--; + iov++; + iovcnt--; } iov[0].iov_base = (char *)iov[0].iov_base + cnt; iov[0].iov_len -= cnt; diff --git a/mkrtos_user/lib/mlibc/src/stdio/__stdout_write.c b/mkrtos_user/lib/mlibc/src/stdio/__stdout_write.c index dd1ec60ff..97fddb06d 100644 --- a/mkrtos_user/lib/mlibc/src/stdio/__stdout_write.c +++ b/mkrtos_user/lib/mlibc/src/stdio/__stdout_write.c @@ -1,11 +1,18 @@ #include "stdio_impl.h" #include - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif size_t __stdout_write(FILE *f, const unsigned char *buf, size_t len) { struct winsize wsz; f->write = __stdio_write; +#ifdef NO_LITTLE_MODE if (!(f->flags & F_SVB) && __syscall(SYS_ioctl, f->fd, TIOCGWINSZ, &wsz)) f->lbf = -1; +#else + if (!(f->flags & F_SVB) && be_ioctl(f->fd, TIOCGWINSZ, &wsz)) + f->lbf = -1; +#endif return __stdio_write(f, buf, len); } diff --git a/mkrtos_user/lib/mlibc/src/termios/tcdrain.c b/mkrtos_user/lib/mlibc/src/termios/tcdrain.c index c0e542b3e..5bfcef4a6 100644 --- a/mkrtos_user/lib/mlibc/src/termios/tcdrain.c +++ b/mkrtos_user/lib/mlibc/src/termios/tcdrain.c @@ -1,8 +1,14 @@ #include #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif int tcdrain(int fd) { +#ifdef NO_LITTLE_MODE return syscall_cp(SYS_ioctl, fd, TCSBRK, 1); +#else + return be_ioctl(fd, TCSBRK, 1); +#endif } diff --git a/mkrtos_user/lib/mlibc/src/termios/tcgetwinsize.c b/mkrtos_user/lib/mlibc/src/termios/tcgetwinsize.c index 9b3a65a40..71db71812 100644 --- a/mkrtos_user/lib/mlibc/src/termios/tcgetwinsize.c +++ b/mkrtos_user/lib/mlibc/src/termios/tcgetwinsize.c @@ -1,8 +1,14 @@ #include #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif int tcgetwinsize(int fd, struct winsize *wsz) { +#ifdef NO_LITTLE_MODE return syscall(SYS_ioctl, fd, TIOCGWINSZ, wsz); +#else + return be_ioctl(fd, TIOCGWINSZ, wsz); +#endif } diff --git a/mkrtos_user/lib/mlibc/src/termios/tcsetwinsize.c b/mkrtos_user/lib/mlibc/src/termios/tcsetwinsize.c index e01d0e254..38aa47d2a 100644 --- a/mkrtos_user/lib/mlibc/src/termios/tcsetwinsize.c +++ b/mkrtos_user/lib/mlibc/src/termios/tcsetwinsize.c @@ -1,8 +1,15 @@ #include #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif int tcsetwinsize(int fd, const struct winsize *wsz) { +#ifdef NO_LITTLE_MODE return syscall(SYS_ioctl, fd, TIOCSWINSZ, wsz); +#else + return be_ioctl(fd, TIOCSWINSZ, wsz); + +#endif } diff --git a/mkrtos_user/lib/mlibc/src/thread/__unmapself.c b/mkrtos_user/lib/mlibc/src/thread/__unmapself.c index 31d94e67e..5468e8864 100644 --- a/mkrtos_user/lib/mlibc/src/thread/__unmapself.c +++ b/mkrtos_user/lib/mlibc/src/thread/__unmapself.c @@ -3,15 +3,21 @@ #include "syscall.h" /* cheat and reuse CRTJMP macro from dynlink code */ #include "dynlink.h" - static void *unmap_base; static size_t unmap_size; static char shared_stack[256]; - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif static void do_unmap() { +#ifdef NO_LITTLE_MODE __syscall(SYS_munmap, unmap_base, unmap_size); __syscall(SYS_exit); +#else + be_munmap(unmap_base, unmap_size); + be_exit(0); +#endif } void __unmapself(void *base, size_t size) diff --git a/mkrtos_user/lib/mlibc/src/thread/arm/__set_thread_area.c b/mkrtos_user/lib/mlibc/src/thread/arm/__set_thread_area.c index 3b1666976..e4d8725d2 100644 --- a/mkrtos_user/lib/mlibc/src/thread/arm/__set_thread_area.c +++ b/mkrtos_user/lib/mlibc/src/thread/arm/__set_thread_area.c @@ -3,50 +3,67 @@ #include "pthread_impl.h" #include "libc.h" +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif + #define HWCAP_TLS (1 << 15) extern hidden const unsigned char - __a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[], + __a_barrier_oldkuser[], + __a_barrier_v6[], __a_barrier_v7[], __a_cas_v6[], __a_cas_v7[], __a_gettp_cp15[]; #define __a_barrier_kuser 0xffff0fa0 -#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser -#define __a_barrier_v6 (uintptr_t)__a_barrier_v6 -#define __a_barrier_v7 (uintptr_t)__a_barrier_v7 +#define __a_barrier_oldkuser (uintptr_t) __a_barrier_oldkuser +#define __a_barrier_v6 (uintptr_t) __a_barrier_v6 +#define __a_barrier_v7 (uintptr_t) __a_barrier_v7 #define __a_cas_kuser 0xffff0fc0 -#define __a_cas_v6 (uintptr_t)__a_cas_v6 -#define __a_cas_v7 (uintptr_t)__a_cas_v7 +#define __a_cas_v6 (uintptr_t) __a_cas_v6 +#define __a_cas_v7 (uintptr_t) __a_cas_v7 #define __a_gettp_kuser 0xffff0fe0 -#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15 +#define __a_gettp_cp15 (uintptr_t) __a_gettp_cp15 extern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr; int __set_thread_area(void *p) { #if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7 - if (__hwcap & HWCAP_TLS) { + if (__hwcap & HWCAP_TLS) + { size_t *aux; __a_cas_ptr = __a_cas_v7; __a_barrier_ptr = __a_barrier_v7; - for (aux=libc.auxv; *aux; aux+=2) { - if (*aux != AT_PLATFORM) continue; + for (aux = libc.auxv; *aux; aux += 2) + { + if (*aux != AT_PLATFORM) + continue; const char *s = (void *)aux[1]; - if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break; + if (s[0] != 'v' || s[1] != '6' || s[2] - '0' < 10u) + break; __a_cas_ptr = __a_cas_v6; __a_barrier_ptr = __a_barrier_v6; break; } - } else { + } + else + { int ver = *(int *)0xffff0ffc; __a_gettp_ptr = __a_gettp_kuser; __a_cas_ptr = __a_cas_kuser; __a_barrier_ptr = __a_barrier_kuser; - if (ver < 2) a_crash(); - if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser; + if (ver < 2) + a_crash(); + if (ver < 3) + __a_barrier_ptr = __a_barrier_oldkuser; } #endif +#ifdef NO_LITTLE_MODE return __syscall(__ARM_NR_set_tls, p); +#else + return be_set_thread_area(p); +#endif } diff --git a/mkrtos_user/lib/mlibc/src/thread/pthread_create.c b/mkrtos_user/lib/mlibc/src/thread/pthread_create.c index 087f6206d..34d359340 100644 --- a/mkrtos_user/lib/mlibc/src/thread/pthread_create.c +++ b/mkrtos_user/lib/mlibc/src/thread/pthread_create.c @@ -6,7 +6,9 @@ #include #include #include - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif static void dummy_0() { } @@ -24,7 +26,8 @@ void __tl_lock(void) { int tid = __pthread_self()->tid; int val = __thread_list_lock; - if (val == tid) { + if (val == tid) + { tl_lock_count++; return; } @@ -34,21 +37,25 @@ void __tl_lock(void) void __tl_unlock(void) { - if (tl_lock_count) { + if (tl_lock_count) + { tl_lock_count--; return; } a_store(&__thread_list_lock, 0); - if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); + if (tl_lock_waiters) + __wake(&__thread_list_lock, 1, 0); } void __tl_sync(pthread_t td) { a_barrier(); int val = __thread_list_lock; - if (!val) return; + if (!val) + return; __wait(&__thread_list_lock, &tl_lock_waiters, val, 0); - if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); + if (tl_lock_waiters) + __wake(&__thread_list_lock, 1, 0); } _Noreturn void __pthread_exit(void *result) @@ -60,7 +67,8 @@ _Noreturn void __pthread_exit(void *result) self->cancelasync = 0; self->result = result; - while (self->cancelbuf) { + while (self->cancelbuf) + { void (*f)(void *) = self->cancelbuf->__f; void *x = self->cancelbuf->__x; self->cancelbuf = self->cancelbuf->__next; @@ -75,7 +83,8 @@ _Noreturn void __pthread_exit(void *result) * call; the loser is responsible for freeing thread resources. */ int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING); - if (state==DT_DETACHED && self->map_base) { + if (state == DT_DETACHED && self->map_base) + { /* Since __unmapself bypasses the normal munmap code path, * explicitly wait for vmlock holders first. This must be * done before any locks are taken, to avoid lock ordering @@ -97,7 +106,8 @@ _Noreturn void __pthread_exit(void *result) /* If this is the only thread in the list, don't proceed with * termination of the thread, but restore the previous lock and * signal state to prepare for exit to call atexit handlers. */ - if (self->next == self) { + if (self->next == self) + { __tl_unlock(); UNLOCK(self->killlock); self->detach_state = state; @@ -122,9 +132,9 @@ _Noreturn void __pthread_exit(void *result) * be invalid when the kernel would process it. */ __vm_lock(); volatile void *volatile *rp; - while ((rp=self->robust_list.head) && rp != &self->robust_list.head) { - pthread_mutex_t *m = (void *)((char *)rp - - offsetof(pthread_mutex_t, _m_next)); + while ((rp = self->robust_list.head) && rp != &self->robust_list.head) + { + pthread_mutex_t *m = (void *)((char *)rp - offsetof(pthread_mutex_t, _m_next)); int waiters = m->_m_waiters; int priv = (m->_m_type & 128) ^ 128; self->robust_list.pending = rp; @@ -144,12 +154,14 @@ _Noreturn void __pthread_exit(void *result) * has been called, via the exit futex address pointing at the lock. * This needs to happen after any possible calls to LOCK() that might * skip locking if process appears single-threaded. */ - if (!--libc.threads_minus_1) libc.need_locks = -1; + if (!--libc.threads_minus_1) + libc.need_locks = -1; self->next->prev = self->prev; self->prev->next = self->next; self->prev = self->next = self; - if (state==DT_DETACHED && self->map_base) { + if (state == DT_DETACHED && self->map_base) + { /* Detached threads must block even implementation-internal * signals, since they will not have a stack in their last * moments of existence. */ @@ -158,7 +170,7 @@ _Noreturn void __pthread_exit(void *result) /* Robust list will no longer be valid, and was already * processed above, so unregister it with the kernel. */ if (self->robust_list.off) - __syscall(SYS_set_robust_list, 0, 3*sizeof(long)); + __syscall(SYS_set_robust_list, 0, 3 * sizeof(long)); /* The following call unmaps the thread's stack mapping * and then exits without touching the stack. */ @@ -169,7 +181,13 @@ _Noreturn void __pthread_exit(void *result) a_store(&self->detach_state, DT_EXITED); __wake(&self->detach_state, 1, 1); - for (;;) __syscall(SYS_exit, 0); +#ifdef NO_LITTLE_MODE + for (;;) + __syscall(SYS_exit, 0); +#else + for (;;) + be_exit(0); +#endif } void __do_cleanup_push(struct __ptcb *cb) @@ -184,26 +202,38 @@ void __do_cleanup_pop(struct __ptcb *cb) __pthread_self()->cancelbuf = cb->__next; } -struct start_args { +struct start_args +{ void *(*start_func)(void *); void *start_arg; volatile int control; - unsigned long sig_mask[_NSIG/8/sizeof(long)]; + unsigned long sig_mask[_NSIG / 8 / sizeof(long)]; }; - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif static int start(void *p) { struct start_args *args = p; int state = args->control; - if (state) { - if (a_cas(&args->control, 1, 2)==1) + if (state) + { + if (a_cas(&args->control, 1, 2) == 1) __wait(&args->control, 0, 2, 1); - if (args->control) { + if (args->control) + { +#ifdef NO_LITTLE_MODE __syscall(SYS_set_tid_address, &args->control); - for (;;) __syscall(SYS_exit, 0); + for (;;) + __syscall(SYS_exit, 0); +#else + be_set_tid_address(&args->control); + for (;;) + be_exit(0); +#endif } } - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->sig_mask, 0, _NSIG/8); + __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->sig_mask, 0, _NSIG / 8); __pthread_exit(args->start_func(args->start_arg)); return 0; } @@ -211,17 +241,17 @@ static int start(void *p) static int start_c11(void *p) { struct start_args *args = p; - int (*start)(void*) = (int(*)(void*)) args->start_func; + int (*start)(void *) = (int (*)(void *))args->start_func; __pthread_exit((void *)(uintptr_t)start(args->start_arg)); return 0; } -#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE) +#define ROUND(x) (((x) + PAGE_SIZE - 1) & -PAGE_SIZE) /* pthread_key_create.c overrides this */ static volatile size_t dummy = 0; weak_alias(dummy, __pthread_tsd_size); -static void *dummy_tsd[1] = { 0 }; +static void *dummy_tsd[1] = {0}; weak_alias(dummy_tsd, __pthread_tsd_main); static FILE *volatile dummy_file = 0; @@ -231,7 +261,8 @@ weak_alias(dummy_file, __stderr_used); static void init_file_lock(FILE *f) { - if (f && f->lock<0) f->lock = 0; + if (f && f->lock < 0) + f->lock = 0; } int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg) @@ -240,35 +271,38 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att size_t size, guard; struct pthread *self, *new; unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit; - unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND - | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS - | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED; - pthread_attr_t attr = { 0 }; + unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED; + pthread_attr_t attr = {0}; sigset_t set; - if (!libc.can_do_threads) return ENOSYS; + if (!libc.can_do_threads) + return ENOSYS; self = __pthread_self(); - if (!libc.threaded) { - for (FILE *f=*__ofl_lock(); f; f=f->next) + if (!libc.threaded) + { + for (FILE *f = *__ofl_lock(); f; f = f->next) init_file_lock(f); __ofl_unlock(); init_file_lock(__stdin_used); init_file_lock(__stdout_used); init_file_lock(__stderr_used); - __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8); + __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG / 8); self->tsd = (void **)__pthread_tsd_main; __membarrier_init(); libc.threaded = 1; } - if (attrp && !c11) attr = *attrp; + if (attrp && !c11) + attr = *attrp; __acquire_ptc(); - if (!attrp || c11) { + if (!attrp || c11) + { attr._a_stacksize = __default_stacksize; attr._a_guardsize = __default_guardsize; } - if (attr._a_stackaddr) { + if (attr._a_stackaddr) + { size_t need = libc.tls_size + __pthread_tsd_size; size = attr._a_stacksize; stack = (void *)(attr._a_stackaddr & -16); @@ -276,35 +310,46 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att /* Use application-provided stack for TLS only when * it does not take more than ~12% or 2k of the * application's stack space. */ - if (need < size/8 && need < 2048) { + if (need < size / 8 && need < 2048) + { tsd = stack - __pthread_tsd_size; stack = tsd - libc.tls_size; memset(stack, 0, need); - } else { + } + else + { size = ROUND(need); } guard = 0; - } else { + } + else + { guard = ROUND(attr._a_guardsize); - size = guard + ROUND(attr._a_stacksize - + libc.tls_size + __pthread_tsd_size); + size = guard + ROUND(attr._a_stacksize + libc.tls_size + __pthread_tsd_size); } - if (!tsd) { - if (guard) { - map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0); - if (map == MAP_FAILED) goto fail; - if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE) - && errno != ENOSYS) { + if (!tsd) + { + if (guard) + { + map = __mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (map == MAP_FAILED) + goto fail; + if (__mprotect(map + guard, size - guard, PROT_READ | PROT_WRITE) && errno != ENOSYS) + { __munmap(map, size); goto fail; } - } else { - map = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); - if (map == MAP_FAILED) goto fail; + } + else + { + map = __mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (map == MAP_FAILED) + goto fail; } tsd = map + size - __pthread_tsd_size; - if (!stack) { + if (!stack) + { stack = tsd - libc.tls_size; stack_limit = map + guard; } @@ -319,9 +364,12 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att new->self = new; new->tsd = (void *)tsd; new->locale = &libc.global_locale; - if (attr._a_detach) { + if (attr._a_detach) + { new->detach_state = DT_DETACHED; - } else { + } + else + { new->detach_state = DT_JOINABLE; } new->robust_list.head = &new->robust_list.head; @@ -347,42 +395,52 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att * working with a copy of the set so we can restore the * original mask in the calling thread. */ memcpy(&args->sig_mask, &set, sizeof args->sig_mask); - args->sig_mask[(SIGCANCEL-1)/8/sizeof(long)] &= - ~(1UL<<((SIGCANCEL-1)%(8*sizeof(long)))); + args->sig_mask[(SIGCANCEL - 1) / 8 / sizeof(long)] &= + ~(1UL << ((SIGCANCEL - 1) % (8 * sizeof(long)))); __tl_lock(); - if (!libc.threads_minus_1++) libc.need_locks = 1; + if (!libc.threads_minus_1++) + libc.need_locks = 1; ret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock); /* All clone failures translate to EAGAIN. If explicit scheduling * was requested, attempt it before unlocking the thread list so * that the failed thread is never exposed and so that we can * clean up all transient resource usage before returning. */ - if (ret < 0) { + if (ret < 0) + { ret = -EAGAIN; - } else if (attr._a_sched) { + } + else if (attr._a_sched) + { ret = __syscall(SYS_sched_setscheduler, - new->tid, attr._a_policy, &attr._a_prio); - if (a_swap(&args->control, ret ? 3 : 0)==2) + new->tid, attr._a_policy, &attr._a_prio); + if (a_swap(&args->control, ret ? 3 : 0) == 2) __wake(&args->control, 1, 1); if (ret) __wait(&args->control, 0, 3, 0); } - if (ret >= 0) { + if (ret >= 0) + { new->next = self->next; new->prev = self; new->next->prev = new; new->prev->next = new; - } else { - if (!--libc.threads_minus_1) libc.need_locks = 0; + } + else + { + if (!--libc.threads_minus_1) + libc.need_locks = 0; } __tl_unlock(); __restore_sigs(&set); __release_ptc(); - if (ret < 0) { - if (map) __munmap(map, size); + if (ret < 0) + { + if (map) + __munmap(map, size); return -ret; } diff --git a/mkrtos_user/lib/mlibc/src/unistd/faccessat.c b/mkrtos_user/lib/mlibc/src/unistd/faccessat.c index 557503eb6..e3e90cde1 100644 --- a/mkrtos_user/lib/mlibc/src/unistd/faccessat.c +++ b/mkrtos_user/lib/mlibc/src/unistd/faccessat.c @@ -3,8 +3,11 @@ #include #include "syscall.h" #include "pthread_impl.h" - -struct ctx { +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif +struct ctx +{ int fd; const char *filename; int amode; @@ -15,25 +18,35 @@ static int checker(void *p) { struct ctx *c = p; int ret; - if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1) - || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1)) + if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1) || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1)) +#ifdef NO_LITTLE_MODE __syscall(SYS_exit, 1); +#else + be_exit(1); +#endif + ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0); +#ifdef NO_LITTLE_MODE __syscall(SYS_write, c->p, &ret, sizeof ret); +#else + be_write(c->p, &ret, sizeof ret); +#endif return 0; } int faccessat(int fd, const char *filename, int amode, int flag) { - if (flag) { + if (flag) + { int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag); - if (ret != -ENOSYS) return __syscall_ret(ret); + if (ret != -ENOSYS) + return __syscall_ret(ret); } if (flag & ~AT_EACCESS) return __syscall_ret(-EINVAL); - if (!flag || (getuid()==geteuid() && getgid()==getegid())) + if (!flag || (getuid() == geteuid() && getgid() == getegid())) return syscall(SYS_faccessat, fd, filename, amode); char stack[1024]; @@ -42,15 +55,16 @@ int faccessat(int fd, const char *filename, int amode, int flag) int status; int ret, p[2]; - if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY); - struct ctx c = { .fd = fd, .filename = filename, .amode = amode, .p = p[1] }; + if (pipe2(p, O_CLOEXEC)) + return __syscall_ret(-EBUSY); + struct ctx c = {.fd = fd, .filename = filename, .amode = amode, .p = p[1]}; __block_all_sigs(&set); - - pid = __clone(checker, stack+sizeof stack, 0, &c); + + pid = __clone(checker, stack + sizeof stack, 0, &c); __syscall(SYS_close, p[1]); - if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret)) + if (pid < 0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret)) ret = -EBUSY; __syscall(SYS_close, p[0]); __syscall(SYS_wait4, pid, &status, __WCLONE, 0); diff --git a/mkrtos_user/lib/mlibc/src/unistd/isatty.c b/mkrtos_user/lib/mlibc/src/unistd/isatty.c index 75a9c186a..5aa46fe69 100644 --- a/mkrtos_user/lib/mlibc/src/unistd/isatty.c +++ b/mkrtos_user/lib/mlibc/src/unistd/isatty.c @@ -2,12 +2,20 @@ #include #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif int isatty(int fd) { struct winsize wsz; +#ifdef NO_LITTLE_MODE unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz); - if (r == 0) return 1; - if (errno != EBADF) errno = ENOTTY; +#else + unsigned long r = be_ioctl(fd, TIOCGWINSZ, &wsz); +#endif + if (r == 0) + return 1; + if (errno != EBADF) + errno = ENOTTY; return 0; } diff --git a/mkrtos_user/lib/mlibc/src/unistd/read.c b/mkrtos_user/lib/mlibc/src/unistd/read.c index f3589c05c..7b07247d3 100644 --- a/mkrtos_user/lib/mlibc/src/unistd/read.c +++ b/mkrtos_user/lib/mlibc/src/unistd/read.c @@ -1,7 +1,13 @@ #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif ssize_t read(int fd, void *buf, size_t count) { +#ifdef NO_LITTLE_MODE return syscall_cp(SYS_read, fd, buf, count); +#else + return be_read(fd, buf, count); +#endif } diff --git a/mkrtos_user/lib/mlibc/src/unistd/writev.c b/mkrtos_user/lib/mlibc/src/unistd/writev.c index 5a46c951a..aa74c0605 100644 --- a/mkrtos_user/lib/mlibc/src/unistd/writev.c +++ b/mkrtos_user/lib/mlibc/src/unistd/writev.c @@ -1,7 +1,13 @@ #include #include "syscall.h" - +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif ssize_t writev(int fd, const struct iovec *iov, int count) { +#ifdef NO_LITTLE_MODE return syscall_cp(SYS_writev, fd, iov, count); +#else + return be_writev(fd, iov, count); +#endif } diff --git a/mkrtos_user/lib/sys/inc/u_log.h b/mkrtos_user/lib/sys/inc/u_log.h index 438d21cdf..a8fc9b366 100644 --- a/mkrtos_user/lib/sys/inc/u_log.h +++ b/mkrtos_user/lib/sys/inc/u_log.h @@ -2,7 +2,7 @@ #include "u_arch.h" #include "u_types.h" - +#include "u_prot.h" #define ULOG_RW_MAX_BYTES (WORD_BYTES * 5) void ulog_write_bytes(obj_handler_t obj_inx, const uint8_t *data, umword_t len); diff --git a/mkrtos_user/server/hello/src/heap_stack.c b/mkrtos_user/server/hello/src/heap_stack.c index 791dd8e9d..ae178938f 100644 --- a/mkrtos_user/server/hello/src/heap_stack.c +++ b/mkrtos_user/server/hello/src/heap_stack.c @@ -1,6 +1,6 @@ #define HEAP_SIZE 0 * 1024 -#define STACK_SIZE 1024 * 1 +#define STACK_SIZE 1024 + 512 #if defined(__CC_ARM) #define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init)) diff --git a/mkrtos_user/server/hello/src/main.c b/mkrtos_user/server/hello/src/main.c index b4473a0ed..9310d92e6 100644 --- a/mkrtos_user/server/hello/src/main.c +++ b/mkrtos_user/server/hello/src/main.c @@ -1,9 +1,8 @@ -#include #include - +#include "u_log.h" int main(int argc, char *args[]) { - // printf("Hello world.\n"); + printf("Hello world.\n"); return 0; } diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c index 5ba89df5d..75145a3cb 100644 --- a/mkrtos_user/server/init/src/main.c +++ b/mkrtos_user/server/init/src/main.c @@ -5,8 +5,7 @@ #include "u_factory.h" #include "u_thread.h" #include "u_task.h" -#include -#include +#include "u_sleep.h" #include "u_ipc.h" #include "u_hd_man.h" #include "u_irq_sender.h" @@ -16,7 +15,8 @@ #include "u_rpc_svr.h" #include "namespace.h" #include "ns_svr.h" - +#include +#include extern void futex_init(void); int main(int argc, char *args[]) { @@ -43,8 +43,7 @@ int main(int argc, char *args[]) assert(ret >= 0); env.ns_hd = ipc_hd; namespace_init(ipc_hd); - - + u_sleep_init(); ret = app_load("app", &env); if (ret < 0) { @@ -56,7 +55,16 @@ int main(int argc, char *args[]) { printf("app load fail, 0x%x\n", ret); } + // u_sleep_ms(500); + // u_sleep_ms(500); + + ret = app_load("hello", &env); + if (ret < 0) + { + printf("app load fail, 0x%x\n", ret); + } + namespace_pre_alloc_map_fd(); namespace_loop(); // task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task,以及申请得所有对象 // printf("exit init.\n"); diff --git a/mkrtos_user/server/init/src/namespace.c b/mkrtos_user/server/init/src/namespace.c index 408298c51..07cecafb5 100644 --- a/mkrtos_user/server/init/src/namespace.c +++ b/mkrtos_user/server/init/src/namespace.c @@ -14,7 +14,6 @@ static ns_t ns; void namespace_init(obj_handler_t ipc) { ns_init(&ns); - namespace_pre_alloc_map_fd(); ns.ipc_hd = ipc; }