Changeset 6220


Ignore:
Timestamp:
Apr 8, 2007, 4:56:00 AM (12 years ago)
Author:
gb
Message:

Handle signals on the altstack if not Darwin.
In Darwin, evactuate off of the lisp stack while interrupts are
still disabled.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/x86-exceptions.c

    r6039 r6220  
    10391039
    10401040void
    1041 altstack_signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    1042 {
    1043   TCR* tcr = get_tcr(true);
    1044   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1045 #if 1
    1046   if (tcr->valence != TCR_STATE_LISP) {
    1047     Bug(context, "exception in foreign context");
    1048   }
    1049 #endif
     1041handle_signal_on_foreign_stack(TCR *tcr,
     1042                               void *handler,
     1043                               int signum,
     1044                               siginfo_t *info,
     1045                               ExceptionInformation *context,
     1046                               LispObj return_address
     1047#ifdef DARWIN_GS_HACK
     1048                               , Boolean gs_was_tcr
     1049#endif
     1050                               )
     1051{
    10501052#ifdef LINUX
    10511053  fpregset_t fpregs = NULL;
     
    10531055  void *fpregs = NULL;
    10541056#endif
     1057#ifdef DARWIN
     1058  MCONTEXT_T mcontextp = NULL;
     1059#endif
    10551060  siginfo_t *info_copy = NULL;
    10561061  ExceptionInformation *xp = NULL;
    1057 
    1058   if (foreign_rsp) {
     1062  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
     1063
    10591064#ifdef LINUX
    1060     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1061 #endif
    1062     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1063     info_copy = (siginfo_t *)foreign_rsp;
    1064     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1065     xp = (ExceptionInformation *)foreign_rsp;
    1066     *--foreign_rsp = (LispObj)__builtin_return_address(0);
    1067     switch_to_foreign_stack(foreign_rsp,signal_handler,signum,info_copy,xp);
    1068   }
     1065  foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
     1066#endif
     1067#ifdef DARWIN
     1068  foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
     1069#endif
     1070  foreign_rsp = copy_siginfo(info, foreign_rsp);
     1071  info_copy = (siginfo_t *)foreign_rsp;
     1072  foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
     1073  xp = (ExceptionInformation *)foreign_rsp;
     1074#ifdef DARWIN
     1075  UC_MCONTEXT(xp) = mcontextp;
     1076#endif
     1077  *--foreign_rsp = return_address;
     1078#ifdef DARWIN_GS_HACK
     1079  if (gs_was_tcr) {
     1080    set_gs_address(tcr);
     1081  }
     1082#endif
     1083  switch_to_foreign_stack(foreign_rsp,handler,signum,info_copy,xp);
     1084}
     1085
     1086
     1087void
     1088altstack_signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1089{
     1090  TCR* tcr = get_tcr(true);
     1091#if 1
     1092  if (tcr->valence != TCR_STATE_LISP) {
     1093    Bug(context, "exception in foreign context");
     1094  }
     1095#endif
     1096  handle_signal_on_foreign_stack(tcr,signal_handler,signum,info,context,(LispObj)__builtin_return_address(0)
     1097#ifdef DARWIN_GS_HACK
     1098                                 , false
     1099#endif
     1100);
    10691101}
    10701102
     
    11341166}
    11351167
    1136 void
    1137 altstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     1168#ifndef USE_SIGALTSTACK
     1169void
     1170arbstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
    11381171{
    11391172#ifdef DARWIN_GS_HACK
     
    11411174#endif
    11421175  TCR *tcr = get_interrupt_tcr(false);
    1143   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1144 #ifdef LINUX
    1145   fpregset_t fpregs = NULL;
    1146 #else
    1147   void *fpregs = NULL;
    1148 #endif
    1149 #ifdef DARWIN
    1150   MCONTEXT_T mcontextp = NULL;
    1151 #endif
    1152   siginfo_t *info_copy = NULL;
    1153   ExceptionInformation *xp = NULL;
    1154 
    1155   if (foreign_rsp) {
    1156 #ifdef LINUX
    1157     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1158 #endif
    1159 #ifdef DARWIN
    1160     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1161 #endif
    1162     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1163     info_copy = (siginfo_t *)foreign_rsp;
    1164     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1165     xp = (ExceptionInformation *)foreign_rsp;
    1166 #ifdef DARWIN
    1167     UC_MCONTEXT(xp) = mcontextp;
    1168 #endif
    1169     *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1176  area *vs = tcr->vs_area;
     1177  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1178
     1179  if ((current_sp >= vs->low) &&
     1180      (current_sp < vs->high)) {
     1181    handle_signal_on_foreign_stack(tcr,
     1182                                   interrupt_handler,
     1183                                   signum,
     1184                                   info,
     1185                                   context,
     1186                                   (LispObj)__builtin_return_address(0)
     1187#ifdef DARWIN_GS_HACK
     1188                                   ,gs_was_tcr
     1189#endif
     1190                                   );
     1191  } else {
     1192    /* If we're not on the value stack, we pretty much have to be on
     1193       the C stack.  Just run the handler. */
    11701194#ifdef DARWIN_GS_HACK
    11711195    if (gs_was_tcr) {
     
    11731197    }
    11741198#endif
    1175     switch_to_foreign_stack(foreign_rsp,interrupt_handler,signum,info_copy,xp);
    1176   }
    1177 }
     1199    interrupt_handler(signum, info, context);
     1200  }
     1201}
     1202
     1203#else /* altstack works */
     1204 
     1205void
     1206altstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     1207{
     1208#ifdef DARWIN_GS_HACK
     1209  Boolean gs_was_tcr = ensure_gs_pthread();
     1210#endif
     1211  TCR *tcr = get_interrupt_tcr(false);
     1212  handle_signal_on_foreign_stack(tcr,interrupt_handler,signum,info,context,(LispObj)__builtin_return_address(0)
     1213#ifdef DARWIN_GS_HACK
     1214                                 ,gs_was_tcr
     1215#endif
     1216                                 );
     1217}
     1218
     1219#endif
    11781220
    11791221
     
    11951237  sa.sa_flags =
    11961238    SA_RESTART
     1239#ifdef USE_SIGALTSTACK
    11971240    | SA_ONSTACK
     1241#endif
    11981242    | SA_SIGINFO;
    11991243
     
    12211265 
    12221266  install_signal_handler(SIGNAL_FOR_PROCESS_INTERRUPT,
    1223                          altstack_interrupt_handler);
     1267#ifdef USE_SIGALTSTACK
     1268                         altstack_interrupt_handler
     1269#else
     1270                         arbstack_interrupt_handler
     1271#endif
     1272);
    12241273  signal(SIGPIPE, SIG_IGN);
    12251274}
    12261275
    1227 
    1228 void
    1229 altstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1276#ifndef USE_SIGALTSTACK
     1277void
     1278arbstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    12301279{
    12311280#ifdef DARWIN_GS_HACK
    12321281  Boolean gs_was_tcr = ensure_gs_pthread();
    12331282#endif
    1234   TCR* tcr = get_tcr(true);
    1235   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1236 #ifdef LINUX
    1237   fpregset_t fpregs = NULL;
    1238 #else
    1239   void *fpregs = NULL;
    1240 #endif
    1241 #ifdef DARWIN
    1242   MCONTEXT_T mcontextp = NULL;
    1243 #endif
    1244 
    1245   siginfo_t *info_copy = NULL;
    1246   ExceptionInformation *xp = NULL;
    1247 
    1248   if (foreign_rsp) {
    1249 #ifdef LINUX
    1250     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1251 #endif
    1252 #ifdef DARWIN
    1253     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1254 #endif
    1255     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1256     info_copy = (siginfo_t *)foreign_rsp;
    1257     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1258     xp = (ExceptionInformation *)foreign_rsp;
    1259 #ifdef DARWIN
    1260     UC_MCONTEXT(xp) = mcontextp;
    1261 #endif
    1262     *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1283  TCR *tcr = get_interrupt_tcr(false);
     1284  area *vs = tcr->vs_area;
     1285  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1286
     1287  if ((current_sp >= vs->low) &&
     1288      (current_sp < vs->high)) {
     1289    handle_signal_on_foreign_stack(tcr,
     1290                                   suspend_resume_handler,
     1291                                   signum,
     1292                                   info,
     1293                                   context,
     1294                                   (LispObj)__builtin_return_address(0)
     1295#ifdef DARWIN_GS_HACK
     1296                                   ,gs_was_tcr
     1297#endif
     1298                                   );
     1299  } else {
     1300    /* If we're not on the value stack, we pretty much have to be on
     1301       the C stack.  Just run the handler. */
    12631302#ifdef DARWIN_GS_HACK
    12641303    if (gs_was_tcr) {
     
    12661305    }
    12671306#endif
    1268     switch_to_foreign_stack(foreign_rsp,suspend_resume_handler,signum,info_copy,xp);
    1269   }
    1270 }
    1271 
    1272 void
    1273 quit_handler(int signum, siginfo_t info, ExceptionInformation *xp)
     1307    suspend_resume_handler(signum, info, context);
     1308  }
     1309}
     1310
     1311
     1312#else /* altstack works */
     1313void
     1314altstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1315{
     1316#ifdef DARWIN_GS_HACK
     1317  Boolean gs_was_tcr = ensure_gs_pthread();
     1318#endif
     1319  TCR* tcr = get_tcr(true);
     1320  handle_signal_on_foreign_stack(tcr,
     1321                                 suspend_resume_handler,
     1322                                 signum,
     1323                                 info,
     1324                                 context,
     1325                                 (LispObj)__builtin_return_address(0)
     1326#ifdef DARWIN_GS_HACK
     1327                                 ,gs_was_tcr
     1328#endif
     1329                                 );
     1330}
     1331
     1332#endif
     1333
     1334void
     1335quit_handler(int signum, siginfo_t *info, ExceptionInformation *xp)
    12741336{
    12751337  TCR *tcr = get_tcr(false);
     
    13001362}
    13011363
    1302 void
    1303 altstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
     1364#ifndef USE_SIGALTSTACK
     1365arbstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
    13041366{
    13051367#ifdef DARWIN_GS_HACK
    13061368  Boolean gs_was_tcr = ensure_gs_pthread();
    13071369#endif
     1370  TCR *tcr = get_interrupt_tcr(false);
     1371  area *vs = tcr->vs_area;
     1372  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1373
     1374  if ((current_sp >= vs->low) &&
     1375      (current_sp < vs->high)) {
     1376    handle_signal_on_foreign_stack(tcr,
     1377                                   quit_handler,
     1378                                   signum,
     1379                                   info,
     1380                                   context,
     1381                                   (LispObj)__builtin_return_address(0)
     1382#ifdef DARWIN_GS_HACK
     1383                                   ,gs_was_tcr
     1384#endif
     1385                                   );
     1386  } else {
     1387    /* If we're not on the value stack, we pretty much have to be on
     1388       the C stack.  Just run the handler. */
     1389#ifdef DARWIN_GS_HACK
     1390    if (gs_was_tcr) {
     1391      set_gs_address(tcr);
     1392    }
     1393#endif
     1394    quit_handler(signum, info, context);
     1395  }
     1396}
     1397
     1398
     1399#else
     1400void
     1401altstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
     1402{
     1403#ifdef DARWIN_GS_HACK
     1404  Boolean gs_was_tcr = ensure_gs_pthread();
     1405#endif
    13081406  TCR* tcr = get_tcr(true);
    1309   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1310 #ifdef LINUX
    1311   fpregset_t fpregs = NULL;
     1407  handle_signal_on_foreign_stack(tcr,
     1408                                 quit_handler,
     1409                                 signum,
     1410                                 info,
     1411                                 context,
     1412                                 (LispObj)__builtin_return_address(0)
     1413#ifdef DARWIN_GS_HACK
     1414                                 ,gs_was_tcr
     1415#endif
     1416                                 );
     1417}
     1418#endif
     1419
     1420#ifdef USE_SIGALTSTACK
     1421#define SUSPEND_RESUME_HANDLER altstack_suspend_resume_handler
     1422#define QUIT_HANDLER altstack_quit_handler
    13121423#else
    1313   void *fpregs = NULL;
    1314 #endif
    1315 #ifdef DARWIN
    1316   MCONTEXT_T mcontextp = NULL;
    1317 #endif
    1318 
    1319   siginfo_t *info_copy = NULL;
    1320   ExceptionInformation *xp = NULL;
    1321 
    1322   if (foreign_rsp) {
    1323 #ifdef LINUX
    1324     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1325 #endif
    1326 #ifdef DARWIN
    1327     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1328 #endif
    1329     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1330     info_copy = (siginfo_t *)foreign_rsp;
    1331     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1332     xp = (ExceptionInformation *)foreign_rsp;
    1333 #ifdef DARWIN
    1334     UC_MCONTEXT(xp) = mcontextp;
    1335 #endif
    1336     *--foreign_rsp = (LispObj)__builtin_return_address(0);
    1337     switch_to_foreign_stack(foreign_rsp,quit_handler,signum,info_copy,xp);
    1338   }
    1339 }
     1424#define SUSPEND_RESUME_HANDLER arbstack_suspend_resume_handler
     1425#define QUIT_HANDLER arbstack_quit_handler
     1426#endif
    13401427
    13411428void
     
    13451432  thread_resume_signal = SIG_RESUME_THREAD;
    13461433
    1347   install_signal_handler(thread_suspend_signal, (void *)altstack_suspend_resume_handler);
    1348   install_signal_handler(thread_resume_signal, (void *)altstack_suspend_resume_handler);
    1349   install_signal_handler(SIGQUIT, (void *)altstack_quit_handler);
     1434  install_signal_handler(thread_suspend_signal, (void *)SUSPEND_RESUME_HANDLER);
     1435  install_signal_handler(thread_resume_signal, (void *)SUSPEND_RESUME_HANDLER);
     1436  install_signal_handler(SIGQUIT, (void *)QUIT_HANDLER);
    13501437}
    13511438
     
    14031490
    14041491
     1492#ifdef USE_SIGALTSTACK
    14051493void
    14061494setup_sigaltstack(area *a)
     
    14121500  stack.ss_flags = 0;
    14131501  mmap(stack.ss_sp,stack.ss_size, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_ANON|MAP_PRIVATE,-1,0);
    1414   sigaltstack(&stack, NULL);
    1415 }
     1502  if (sigaltstack(&stack, NULL) != 0) {
     1503    perror("sigaltstack");
     1504    exit(-1);
     1505  }
     1506}
     1507#endif
    14161508
    14171509extern opcode egc_write_barrier_start, egc_write_barrier_end,
Note: See TracChangeset for help on using the changeset viewer.