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 #if !HAVE_MMAP
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 #endif
43
sigfillset(sigset_t * set)44 int sigfillset(sigset_t *set)
45 {
46 return 0;
47 }
48 #ifndef MINGW
49
pthread_key_create(pthread_key_t * key,void (* destroy)(void *))50 int pthread_key_create(pthread_key_t *key, void (*destroy)(void*))
51 {
52 // We are not implementing pthread_getspecific so this sholdn't matter much
53 return 0;
54 }
55
pthread_setspecific(pthread_key_t key,const void * value)56 int pthread_setspecific(pthread_key_t key, const void *value)
57 {
58 // We are not implementing pthread_getspecific so this sholdn't matter much
59 return 0;
60 }
61
pthread_mutex_init(pthread_mutex_t * mutex,const pthread_mutexattr_t * attr)62 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
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_lock(pthread_mutex_t * mutex)69 int pthread_mutex_lock(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_mutex_unlock(pthread_mutex_t * mutex)76 int pthread_mutex_unlock(pthread_mutex_t *mutex)
77 {
78 // For dump debugging we don't need locking
79 // We expect to run in a single thread
80 return 0;
81 }
82
pthread_once(pthread_once_t * control,void (* init)(void))83 int pthread_once(pthread_once_t *control, void (*init)(void))
84 {
85 if (control == 0)
86 return -1;
87
88 // We expect to run in a single thread
89 // We don't need atomics here
90 if (*control != PTHREAD_ONCE_INIT)
91 {
92 (*init)();
93 *control = ~PTHREAD_ONCE_INIT;
94 }
95 return 0;
96 }
97
98
read(int fd,void * buf,size_t count)99 ssize_t read(int fd, void *buf, size_t count)
100 {
101 // For dump debugging we shouldn't need to open files
102 // Especially since we didn't implement open()
103 return -1;
104 }
105
close(int fd)106 int close(int fd)
107 {
108 // For dump debugging we shouldn't need to open files
109 // Especially since we didn't implement open()
110 return -1;
111 }
112 // ALIAS(x) is nop. We need this alias to link properly
unw_get_accessors_int(unw_addr_space_t as)113 unw_accessors_t * unw_get_accessors_int (unw_addr_space_t as)
114 {
115 return unw_get_accessors(as);
116 }
117 #endif
118
119