00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 # include "gc_private.h"
00011 # include <stdio.h>
00012 # include <signal.h>
00013
00014
00015
00016
00017
00018
00019 # ifdef OS2
00020
00021 # define INCL_DOSEXCEPTIONS
00022 # define INCL_DOSPROCESS
00023 # define INCL_DOSERRORS
00024 # define INCL_DOSMODULEMGR
00025 # include <os2.h>
00026
00027
00028 # ifndef WORD
00029 # define WORD unsigned short
00030 # endif
00031 # ifndef DWORD
00032 # define DWORD unsigned long
00033 # endif
00034
00035 # define EXE386 1
00036 # include <newexe.h>
00037 # include <exe386.h>
00038
00039 void GC_disable_signals(void)
00040 {
00041 ULONG nest;
00042
00043 DosEnterMustComplete(&nest);
00044 if (nest != 1) ABORT("nested GC_disable_signals");
00045 }
00046
00047 void GC_enable_signals(void)
00048 {
00049 ULONG nest;
00050
00051 DosExitMustComplete(&nest);
00052 if (nest != 0) ABORT("GC_enable_signals");
00053 }
00054
00055
00056 # else
00057
00058 # ifndef PCR
00059
00060 # ifdef sigmask
00061
00062 # define SIGSET_T int
00063 # define SIG_DEL(set, signal) (set) &= ~(sigmask(signal))
00064 # define SIG_FILL(set) (set) = 0x7fffffff
00065
00066
00067
00068 # define SIGSETMASK(old, new) (old) = sigsetmask(new)
00069 # else
00070
00071 # define SIGSET_T sigset_t
00072 # define SIG_DEL(set, signal) sigdelset(&(set), (signal))
00073 # define SIG_FILL(set) sigfillset(&set)
00074 # define SIGSETMASK(old, new) sigprocmask(SIG_SETMASK, &(new), &(old))
00075 # endif
00076
00077 static bool mask_initialized = FALSE;
00078
00079 static SIGSET_T new_mask;
00080
00081 static SIGSET_T old_mask;
00082
00083 static SIGSET_T dummy;
00084
00085 void GC_disable_signals()
00086 {
00087 if (!mask_initialized) {
00088 SIG_FILL(new_mask);
00089
00090 SIG_DEL(new_mask, SIGSEGV);
00091 SIG_DEL(new_mask, SIGILL);
00092 SIG_DEL(new_mask, SIGQUIT);
00093 # ifdef SIGBUS
00094 SIG_DEL(new_mask, SIGBUS);
00095 # endif
00096 # ifdef SIGIOT
00097 SIG_DEL(new_mask, SIGIOT);
00098 # endif
00099 # ifdef SIGEMT
00100 SIG_DEL(new_mask, SIGEMT);
00101 # endif
00102 # ifdef SIGTRAP
00103 SIG_DEL(new_mask, SIGTRAP);
00104 # endif
00105 mask_initialized = TRUE;
00106 }
00107 SIGSETMASK(old_mask,new_mask);
00108 }
00109
00110 void GC_enable_signals()
00111 {
00112 SIGSETMASK(dummy,old_mask);
00113 }
00114
00115 # endif
00116
00117 # endif
00119
00120
00121
00122
00123
00124
00125
00126 # ifdef OS2
00127
00128 ptr_t GC_get_stack_base()
00129 {
00130 PTIB ptib;
00131 PPIB ppib;
00132
00133 if (DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) {
00134 GC_err_printf0("DosGetInfoBlocks failed\n");
00135 ABORT("DosGetInfoBlocks failed\n");
00136 }
00137 return((ptr_t)(ptib -> tib_pstacklimit));
00138 }
00139
00140 # else
00141
00142 # if !defined(THREADS) && !defined(STACKBOTTOM) && defined(HEURISTIC2)
00143
00144 # define MIN_PAGE_SIZE 256
00145 # include <setjmp.h>
00146 jmp_buf GC_jmp_buf;
00147
00148
00149 void GC_fault_handler(sig)
00150 int sig;
00151 {
00152 longjmp(GC_jmp_buf, 1);
00153 }
00154 # endif
00155
00156 ptr_t GC_get_stack_base()
00157 {
00158 word dummy;
00159 static ptr_t result;
00160
00161
00162
00163
00164 # ifdef __STDC__
00165 typedef void (*handler)(int);
00166 # else
00167 typedef void (*handler)();
00168 # endif
00169 # ifdef HEURISTIC2
00170 static handler old_segv_handler, old_bus_handler;
00171
00172 # endif
00173 # define STACKBOTTOM_ALIGNMENT_M1 0xffffff
00174
00175 # ifdef STACKBOTTOM
00176 return(STACKBOTTOM);
00177 # else
00178 # ifdef HEURISTIC1
00179 # ifdef STACK_GROWS_DOWN
00180 result = (ptr_t)((((word)(&dummy))
00181 + STACKBOTTOM_ALIGNMENT_M1)
00182 & ~STACKBOTTOM_ALIGNMENT_M1);
00183 # else
00184 result = (ptr_t)(((word)(&dummy))
00185 & ~STACKBOTTOM_ALIGNMENT_M1);
00186 # endif
00187 # endif
00188 # ifdef HEURISTIC2
00189 old_segv_handler = signal(SIGSEGV, GC_fault_handler);
00190 # ifdef SIGBUS
00191 old_bus_handler = signal(SIGBUS, GC_fault_handler);
00192 # endif
00193 if (setjmp(GC_jmp_buf) == 0) {
00194 result = (ptr_t)(((word)(&dummy))
00195 & ~(MIN_PAGE_SIZE-1));
00196 for (;;) {
00197 # ifdef STACK_GROWS_DOWN
00198 result += MIN_PAGE_SIZE;
00199 # else
00200 result -= MIN_PAGE_SIZE;
00201 # endif
00202 GC_noop(*result);
00203 }
00204 }
00205 (void) signal(SIGSEGV, old_segv_handler);
00206 # ifdef SIGBUS
00207 (void) signal(SIGBUS, old_bus_handler);
00208 # endif
00209 # ifdef STACK_GROWS_UP
00210 result += MIN_PAGE_SIZE;
00211 # endif
00212 # endif
00213 return(result);
00214 # endif
00215 }
00216
00217 # endif
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 # ifdef OS2
00228
00229 void GC_register_data_segments()
00230 {
00231 PTIB ptib;
00232 PPIB ppib;
00233 HMODULE module_handle;
00234 # define PBUFSIZ 512
00235 UCHAR path[PBUFSIZ];
00236 FILE * myexefile;
00237 struct exe_hdr hdrdos;
00238 struct e32_exe hdr386;
00239 struct o32_obj seg;
00240 int nsegs;
00241
00242
00243 if (DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) {
00244 GC_err_printf0("DosGetInfoBlocks failed\n");
00245 ABORT("DosGetInfoBlocks failed\n");
00246 }
00247 module_handle = ppib -> pib_hmte;
00248 if (DosQueryModuleName(module_handle, PBUFSIZ, path) != NO_ERROR) {
00249 GC_err_printf0("DosQueryModuleName failed\n");
00250 ABORT("DosGetInfoBlocks failed\n");
00251 }
00252 myexefile = fopen(path, "rb");
00253 if (myexefile == 0) {
00254 GC_err_puts("Couldn't open executable ");
00255 GC_err_puts(path); GC_err_puts("\n");
00256 ABORT("Failed to open executable\n");
00257 }
00258 if (fread((char *)(&hdrdos), 1, sizeof hdrdos, myexefile) < sizeof hdrdos) {
00259 GC_err_puts("Couldn't read MSDOS header from ");
00260 GC_err_puts(path); GC_err_puts("\n");
00261 ABORT("Couldn't read MSDOS header");
00262 }
00263 if (E_MAGIC(hdrdos) != EMAGIC) {
00264 GC_err_puts("Executable has wrong DOS magic number: ");
00265 GC_err_puts(path); GC_err_puts("\n");
00266 ABORT("Bad DOS magic number");
00267 }
00268 if (fseek(myexefile, E_LFANEW(hdrdos), SEEK_SET) != 0) {
00269 GC_err_puts("Seek to new header failed in ");
00270 GC_err_puts(path); GC_err_puts("\n");
00271 ABORT("Bad DOS magic number");
00272 }
00273 if (fread((char *)(&hdr386), 1, sizeof hdr386, myexefile) < sizeof hdr386) {
00274 GC_err_puts("Couldn't read MSDOS header from ");
00275 GC_err_puts(path); GC_err_puts("\n");
00276 ABORT("Couldn't read OS/2 header");
00277 }
00278 if (E32_MAGIC1(hdr386) != E32MAGIC1 || E32_MAGIC2(hdr386) != E32MAGIC2) {
00279 GC_err_puts("Executable has wrong OS/2 magic number:");
00280 GC_err_puts(path); GC_err_puts("\n");
00281 ABORT("Bad OS/2 magic number");
00282 }
00283 if ( E32_BORDER(hdr386) != E32LEBO || E32_WORDER(hdr386) != E32LEWO) {
00284 GC_err_puts("Executable %s has wrong byte order: ");
00285 GC_err_puts(path); GC_err_puts("\n");
00286 ABORT("Bad byte order");
00287 }
00288 if ( E32_CPU(hdr386) == E32CPU286) {
00289 GC_err_puts("GC can't handle 80286 executables: ");
00290 GC_err_puts(path); GC_err_puts("\n");
00291 EXIT();
00292 }
00293 if (fseek(myexefile, E_LFANEW(hdrdos) + E32_OBJTAB(hdr386),
00294 SEEK_SET) != 0) {
00295 GC_err_puts("Seek to object table failed: ");
00296 GC_err_puts(path); GC_err_puts("\n");
00297 ABORT("Seek to object table failed");
00298 }
00299 for (nsegs = E32_OBJCNT(hdr386); nsegs > 0; nsegs--) {
00300 int flags;
00301 if (fread((char *)(&seg), 1, sizeof seg, myexefile) < sizeof seg) {
00302 GC_err_puts("Couldn't read obj table entry from ");
00303 GC_err_puts(path); GC_err_puts("\n");
00304 ABORT("Couldn't read obj table entry");
00305 }
00306 flags = O32_FLAGS(seg);
00307 if (!(flags & OBJWRITE)) continue;
00308 if (!(flags & OBJREAD)) continue;
00309 if (flags & OBJINVALID) {
00310 GC_err_printf0("Object with invalid pages?\n");
00311 continue;
00312 }
00313 GC_add_roots_inner(O32_BASE(seg), O32_BASE(seg)+O32_SIZE(seg));
00314 }
00315 }
00316
00317 # else
00318
00319 void GC_register_data_segments()
00320 {
00321 extern int end;
00322
00323 # ifndef PCR
00324 GC_add_roots_inner(DATASTART, (char *)(&end));
00325 # endif
00326
00327
00328 }
00329
00330 # endif