Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | #define _GNU_SOURCE |
2 | ||
3 | #include "platform.h" | |
4 | ||
5 | #include "diskBack.unix.c" | |
6 | #include "displayMem.proc.c" | |
7 | #include "mmap-protect.c" | |
8 | #include "nonwin.c" | |
9 | #include "use-mmap.c" | |
10 | ||
11 | static void catcher (__attribute__ ((unused)) int signo, | |
12 | __attribute__ ((unused)) siginfo_t* info, | |
13 | void* context) { | |
14 | #if (defined (__x86_64__)) | |
15 | #ifndef REG_RIP | |
16 | #define REG_INDEX(NAME) (offsetof(struct sigcontext, NAME) / sizeof(greg_t)) | |
17 | #define REG_RIP REG_INDEX(rip) /* seems to be 16 */ | |
18 | #endif | |
19 | ucontext_t* ucp = (ucontext_t*)context; | |
20 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.gregs[REG_RIP]); | |
21 | #elif (defined (__alpha__)) | |
22 | ucontext_t* ucp = (ucontext_t*)context; | |
23 | GC_handleSigProf ((code_pointer) (ucp->uc_mcontext.sc_pc)); | |
24 | #elif (defined (__hppa__)) | |
25 | ucontext_t* ucp = (ucontext_t*)context; | |
26 | GC_handleSigProf ((code_pointer) (ucp->uc_mcontext.sc_iaoq[0] & ~0x3UL)); | |
27 | #elif (defined(__ia64__)) | |
28 | ucontext_t* ucp = (ucontext_t*)context; | |
29 | GC_handleSigProf ((code_pointer) ucp->_u._mc.sc_ip); | |
30 | #elif (defined (__ppc__)) || (defined (__powerpc__)) | |
31 | ucontext_t* ucp = (ucontext_t*)context; | |
32 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.regs->nip); | |
33 | #elif (defined (__sparc__)) | |
34 | struct sigcontext* scp = (struct sigcontext*)context; | |
35 | #if __WORDSIZE == 64 | |
36 | GC_handleSigProf ((code_pointer) scp->sigc_regs.tpc); | |
37 | #else | |
38 | GC_handleSigProf ((code_pointer) scp->si_regs.pc); | |
39 | #endif | |
40 | #elif (defined (__mips__)) | |
41 | ucontext_t* ucp = (ucontext_t*)context; | |
42 | #ifdef __UCLIBC__ | |
43 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.gpregs[CTX_EPC]); | |
44 | #else | |
45 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.pc); | |
46 | #endif | |
47 | #elif (defined (__i386__)) | |
48 | #ifndef EIP | |
49 | #define EIP 14 | |
50 | #endif | |
51 | ucontext_t* ucp = (ucontext_t*)context; | |
52 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.gregs[EIP]); | |
53 | #elif (defined (__arm__)) | |
54 | ucontext_t* ucp = (ucontext_t*)context; | |
55 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.arm_pc); | |
56 | #elif (defined (__aarch64__)) | |
57 | ucontext_t* ucp = (ucontext_t*)context; | |
58 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.pc); | |
59 | #elif (defined (__s390__)) | |
60 | ucontext_t* ucp = (ucontext_t*)context; | |
61 | GC_handleSigProf ((code_pointer) ucp->uc_mcontext.psw.addr); | |
62 | #else | |
63 | #error Profiling handler is missing for this architecture | |
64 | #endif | |
65 | } | |
66 | ||
67 | void GC_setSigProfHandler (struct sigaction *sa) { | |
68 | sa->sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; | |
69 | sa->sa_sigaction = (void (*)(int, siginfo_t*, void*))catcher; | |
70 | } | |
71 | ||
72 | /* We need the value of MREMAP_MAYMOVE, which should come from sys/mman.h, but | |
73 | * isn't there. It is in linux/mman.h, but we can't #include that here, because | |
74 | * kernel headers don't mix with system headers. We could create a separate | |
75 | * file, include the kernel headers there, and define a global. But there | |
76 | * sometimes seem to be problems including kernel headers, so the easiest thing | |
77 | * to do is just define MREMAP_MAYMOVE. | |
78 | */ | |
79 | #define MREMAP_MAYMOVE 1 | |
80 | ||
81 | void *GC_mremap (void *start, size_t oldLength, size_t newLength) { | |
82 | return mremap (start, oldLength, newLength, MREMAP_MAYMOVE); | |
83 | } | |
84 | ||
85 | size_t GC_pageSize (void) { | |
86 | long int pageSize; | |
87 | ||
88 | pageSize = sysconf (_SC_PAGESIZE); | |
89 | if (pageSize < 0) | |
90 | diee ("GC_pageSize error: sysconf (_SC_PAGESIZE) failed"); | |
91 | ||
92 | return (size_t)pageSize; | |
93 | } | |
94 | ||
95 | /* sysconf(_SC_PHYS_PAGES) is not portable (mipsel uclibc) */ | |
96 | uintmax_t GC_physMem (void) { | |
97 | struct sysinfo si; | |
98 | if (sysinfo(&si) < 0) | |
99 | diee ("GC_physMem error: sysinfo failed"); | |
100 | ||
101 | return (uintmax_t)si.totalram * (uintmax_t)si.mem_unit; | |
102 | } |