1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 // This is minimal implementation of posix functions files required to cross compile
6 // libunwind on a Windows host for UNW_REMOTE_ONLY application.
7
8 // This a completely thread unsafe implementation
9 // It is likely sufficient for a single thread's usage of UNW_REMOTE_ONLY debugging of
10 // a read-only dump.
11
12 #include <pthread.h>
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <sys/mman.h>
16 #include <unistd.h>
17 #include "libunwind_i.h"
18 #include "compiler.h"
19
20
getpagesize(void)21 int getpagesize(void)
22 {
23 // 4096 is truth for most targets
24 // Unlikely to matter in dump debugging
25 return 4096;
26 }
27
mmap(void * addr,size_t length,int prot,int flags,int fd,size_t offset)28 void* mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset)
29 {
30 // We shouldn't be doing anything other than anonymous mappings
31 if ((flags & MAP_ANONYMOUS) == 0)
32 return MAP_FAILED;
33
34 return calloc(1, length);
35 }
36
munmap(void * addr,size_t length)37 int munmap(void *addr, size_t length)
38 {
39 free(addr);
40 return 0;
41 }
42
pthread_key_create(pthread_key_t * key,void (* destroy)(void *))43 int pthread_key_create(pthread_key_t *key, void (*destroy)(void*))
44 {
45 // We are not implementing pthread_getspecific so this sholdn't matter much
46 return 0;
47 }
48
pthread_setspecific(pthread_key_t key,const void * value)49 int pthread_setspecific(pthread_key_t key, const void *value)
50 {
51 // We are not implementing pthread_getspecific so this sholdn't matter much
52 return 0;
53 }
54
pthread_mutex_init(pthread_mutex_t * mutex,const pthread_mutexattr_t * attr)55 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
56 {
57 // For dump debugging we don't need locking
58 // We expect to run in a single thread
59 return 0;
60 }
61
pthread_mutex_lock(pthread_mutex_t * mutex)62 int pthread_mutex_lock(pthread_mutex_t *mutex)
63 {
64 // For dump debugging we don't need locking
65 // We expect to run in a single thread
66 return 0;
67 }
68
pthread_mutex_unlock(pthread_mutex_t * mutex)69 int pthread_mutex_unlock(pthread_mutex_t *mutex)
70 {
71 // For dump debugging we don't need locking
72 // We expect to run in a single thread
73 return 0;
74 }
75
pthread_once(pthread_once_t * control,void (* init)(void))76 int pthread_once(pthread_once_t *control, void (*init)(void))
77 {
78 if (control == 0)
79 return -1;
80
81 // We expect to run in a single thread
82 // We don't need atomics here
83 if (*control != PTHREAD_ONCE_INIT)
84 {
85 (*init)();
86 *control = ~PTHREAD_ONCE_INIT;
87 }
88 return 0;
89 }
90
sigfillset(sigset_t * set)91 int sigfillset(sigset_t *set)
92 {
93 return 0;
94 }
95
read(int fd,void * buf,size_t count)96 ssize_t read(int fd, void *buf, size_t count)
97 {
98 // For dump debugging we shouldn't need to open files
99 // Especially since we didn't implement open()
100 return -1;
101 }
102
close(int fd)103 int close(int fd)
104 {
105 // For dump debugging we shouldn't need to open files
106 // Especially since we didn't implement open()
107 return -1;
108 }
109
110 // ALIAS(x) is nop. We need this alias to link properly
unw_get_accessors_int(unw_addr_space_t as)111 unw_accessors_t * unw_get_accessors_int (unw_addr_space_t as)
112 {
113 return unw_get_accessors(as);
114 }
115