The Pedigree Project  0.1
signal-syscalls.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "signal-syscalls.h"
21 #include "file-syscalls.h"
22 #include "pedigree/kernel/Log.h"
23 #include "pedigree/kernel/syscallError.h"
24 #include "pthread-syscalls.h"
25 #include "system-syscalls.h"
26 
27 #include "pedigree/kernel/process/PerProcessorScheduler.h"
28 #include "pedigree/kernel/process/Scheduler.h"
29 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"
30 
31 #define MACHINE_FORWARD_DECL_ONLY
32 #include "pedigree/kernel/machine/Machine.h"
33 #include "pedigree/kernel/machine/Timer.h"
34 
35 #include "pedigree/kernel/Subsystem.h"
36 #include <PosixProcess.h>
37 #include <PosixSubsystem.h>
38 
39 #include <signal.h>
40 
41 extern "C" {
42 extern void sigret_stub();
43 extern char sigret_stub_end;
44 }
45 
46 static int doProcessKill(Process *p, int sig);
47 static int doThreadKill(Thread *p, int sig);
48 
50 
51 #define SIGNAL_HANDLER_EXIT(name, errcode) \
52  static void name(int) NORETURN; \
53  static void name(int) \
54  { \
55  posix_exit(errcode); \
56  }
57 #define SIGNAL_HANDLER_EMPTY(name) \
58  static void name(int s) \
59  { \
60  NOTICE("EMPTY handler."); \
61  }
62 #define SIGNAL_HANDLER_EXITMSG(name, errcode, msg) \
63  static void name(int) NORETURN; \
64  static void name(int) \
65  { \
66  Processor::setInterrupts(true); \
67  posix_write(1, msg, StringLength(msg), true); \
68  Scheduler::instance().yield(); \
69  posix_exit(errcode); \
70  }
71 #define SIGNAL_HANDLER_SUSPEND(name) \
72  static void name(int s) \
73  { \
74  Process *pParent = \
75  Processor::information().getCurrentThread()->getParent(); \
76  NOTICE( \
77  "SUSPEND [pid=" << pParent->getId() << ", signal " << s << "]"); \
78  pParent->suspend(); \
79  }
80 #define SIGNAL_HANDLER_RESUME(name) \
81  static void name(int s) \
82  { \
83  NOTICE("RESUME [signal " << s << "]"); \
84  Processor::information().getCurrentThread()->getParent()->resume(); \
85  }
86 
87 static char SSIGILL[] = "Illegal instruction.\n";
88 static char SSIGSEGV[] = "Segmentation fault.\n";
89 static char SSIGBUS[] = "Bus error.\n";
90 static char SSIGABRT[] = "Abort.\n";
91 
92 SIGNAL_HANDLER_EXITMSG(sigabrt, SIGABRT, SSIGABRT)
93 SIGNAL_HANDLER_EXIT(sigalrm, SIGALRM)
94 SIGNAL_HANDLER_EXITMSG(sigbus, SIGBUS, SSIGBUS)
95 SIGNAL_HANDLER_EMPTY(sigchld)
96 SIGNAL_HANDLER_RESUME(sigcont)
97 SIGNAL_HANDLER_EXIT(sigfpe, SIGFPE) // floating point exception signal
98 SIGNAL_HANDLER_EXIT(sighup, SIGHUP)
99 SIGNAL_HANDLER_EXITMSG(sigill, SIGILL, SSIGILL)
100 SIGNAL_HANDLER_EXIT(sigint, SIGINT)
101 SIGNAL_HANDLER_EXIT(sigkill, SIGKILL)
102 SIGNAL_HANDLER_EXIT(sigpipe, SIGPIPE)
103 SIGNAL_HANDLER_EXIT(sigquit, SIGQUIT)
104 SIGNAL_HANDLER_EXITMSG(sigsegv, SIGSEGV, SSIGSEGV)
105 SIGNAL_HANDLER_SUSPEND(sigstop)
106 SIGNAL_HANDLER_EXIT(sigterm, SIGTERM)
107 SIGNAL_HANDLER_SUSPEND(sigtstp) // terminal stop
108 SIGNAL_HANDLER_SUSPEND(sigttin) // background process attempts read
109 SIGNAL_HANDLER_SUSPEND(sigttou) // background process attempts write
110 SIGNAL_HANDLER_EMPTY(sigusr1)
111 SIGNAL_HANDLER_EMPTY(sigusr2)
112 SIGNAL_HANDLER_EMPTY(sigurg) // high bandwdith data available at a sockeet
113 
114 SIGNAL_HANDLER_EMPTY(sigign);
115 
116 static _sig_func_ptr default_sig_handlers[32] = {
117  sigign, // 0
118  sighup, // SIGHUP
119  sigint, // SIGINT
120  sigquit, // SIGQUIT
121  sigill, // SIGILL
122  sigign, // SIGTRAP
123  sigabrt, // SIGABRT
124  sigbus, // SIGBUS
125  sigfpe, // SIGFPE
126  sigkill, // SIGKILL
127  sigusr1, // SIGUSR1
128  sigsegv, // SIGSEGV
129  sigusr2, // SIGUSR2
130  sigpipe, // SIGPIPE
131  sigalrm, // SIGALRM
132  sigterm, // SIGTERM
133  sigign, // SIGSTKFLT
134  sigchld, // SIGCHLD
135  sigcont, // SIGCONT
136  sigstop, // SIGSTOP
137  sigtstp, // SIGTSTP
138  sigttin, // SIGTTIN
139  sigttou, // SIGTTOU
140  sigurg, // SIGURG
141  sigign, // SIGXCPU
142  sigign, // SIGXFSZ
143  sigign, // SIGVTALRM
144  sigign, // SIGWINCH
145  sigign, // SIGIO
146  sigign, // SIGPOLL
147  sigign, // SIGPWR
148  sigign, // SIGSYS
149 };
150 
151 int posix_sigaction(
152  int sig, const struct sigaction *act, struct sigaction *oact)
153 {
154  SG_NOTICE(
155  "sigaction(" << Dec << sig << Hex << ", "
156  << reinterpret_cast<uintptr_t>(act) << ", "
157  << reinterpret_cast<uintptr_t>(oact) << ")");
158  if ((act && !PosixSubsystem::checkAddress(
159  reinterpret_cast<uintptr_t>(act), sizeof(struct sigaction),
160  PosixSubsystem::SafeRead)) ||
162  reinterpret_cast<uintptr_t>(oact),
163  sizeof(struct sigaction), PosixSubsystem::SafeWrite)))
164  {
165  SYSCALL_ERROR(InvalidArgument);
166  return -1;
167  }
168 
169  Thread *pThread = Processor::information().getCurrentThread();
170  Process *pProcess = pThread->getParent();
171  PosixSubsystem *pSubsystem =
172  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
173  if (!pSubsystem)
174  {
175  ERROR("posix_sigaction: no subsystem");
176  return -1;
177  }
178 
179  // sanity and safety checks
180  if ((sig > 32) || (sig == SIGKILL || sig == SIGSTOP))
181  {
182  SYSCALL_ERROR(InvalidArgument);
183  return -1;
184  }
185  sig %= 32;
186 
187  // store the old signal handler information if we can
188  if (oact)
189  {
190  PosixSubsystem::SignalHandler *oldSignalHandler =
191  pSubsystem->getSignalHandler(sig);
192  if (oldSignalHandler)
193  {
194  oact->sa_flags = oldSignalHandler->flags;
195  // oact->sa_mask = oldSignalHandler->sigMask;
196  if (oldSignalHandler->type == 0)
197  oact->sa_handler = reinterpret_cast<void (*)(int)>(
198  oldSignalHandler->pEvent->getHandlerAddress());
199  else if (oldSignalHandler->type == 1)
200  oact->sa_handler = reinterpret_cast<void (*)(int)>(0);
201  else if (oldSignalHandler->type == 2)
202  oact->sa_handler = reinterpret_cast<void (*)(int)>(1);
203  }
204  else
205  ByteSet(oact, 0, sizeof(struct sigaction));
206  }
207 
208  // and if needed, fill in the new signal handler
209  if (act)
210  {
211  PosixSubsystem::SignalHandler *sigHandler =
213  // sigHandler->sigMask = act->sa_mask;
214  sigHandler->flags = act->sa_flags;
215 
216  uintptr_t newHandler = reinterpret_cast<uintptr_t>(act->sa_handler);
217  if (newHandler == 0)
218  {
219  SG_NOTICE(" + SIG_DFL");
220  newHandler = reinterpret_cast<uintptr_t>(default_sig_handlers[sig]);
221  sigHandler->type = 1;
222  }
223  else if (newHandler == 1)
224  {
225  SG_NOTICE(" + SIG_IGN");
226  newHandler = reinterpret_cast<uintptr_t>(sigign);
227  sigHandler->type = 2;
228  }
229  else if (static_cast<int>(newHandler) == -1)
230  {
231  SG_NOTICE(" + Invalid");
232  delete sigHandler;
233  SYSCALL_ERROR(InvalidArgument);
234  return -1;
235  }
236  else
237  {
238  // SG_NOTICE(" + <handler has been provided>");
239  sigHandler->type = 0;
240  }
241 
242  sigHandler->pEvent =
243  new SignalEvent(newHandler, static_cast<size_t>(sig));
244  SG_NOTICE(
245  "Creating the event ("
246  << reinterpret_cast<uintptr_t>(sigHandler->pEvent) << ").");
247  pSubsystem->setSignalHandler(sig, sigHandler);
248  }
249  else if (!oact)
250  {
251  // no valid arguments!
252  SYSCALL_ERROR(InvalidArgument);
253  return -1;
254  }
255  return 0;
256 }
257 
258 uintptr_t posix_signal(int sig, void *func)
259 {
260  ERROR("signal called but glue signal should redirect to sigaction");
261  return 0;
262 }
263 
264 int posix_raise(int sig, SyscallState &State)
265 {
266  SG_NOTICE("raise");
267 
268  // Create the pending signal and pass it in
269  Thread *pThread = Processor::information().getCurrentThread();
270  Process *pProcess = pThread->getParent();
271  PosixSubsystem *pSubsystem =
272  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
273  if (!pSubsystem)
274  {
275  ERROR("posix_raise: no subsystem");
276  return -1;
277  }
278 
279  PosixSubsystem::SignalHandler *signalHandler =
280  pSubsystem->getSignalHandler(sig);
281 
282  // Firing and checking the event state needs to be done without any
283  // interrupts getting in the way.
284  bool bWasInterrupts = Processor::getInterrupts();
286 
287  // Fire the event, and wait for it to complete
288  if (signalHandler->pEvent)
289  pThread->sendEvent(reinterpret_cast<Event *>(signalHandler->pEvent));
290 
291  // If the alternate stack is available, and not in use, use that
292  uintptr_t stackPointer = State.getStackPointer();
294  pSubsystem->getAlternateSignalStack();
295  if (currStack.enabled && !currStack.inUse)
296  stackPointer = (currStack.base + currStack.size) - 1;
297 
298  // Jump to the signal handler
299  Processor::information().getScheduler().checkEventState(stackPointer);
300  Processor::setInterrupts(bWasInterrupts);
301 
302  // All done
303  return 0;
304 }
305 
306 int pedigree_sigret() NORETURN;
307 int pedigree_sigret()
308 {
309  SG_NOTICE("pedigree_sigret");
310 
311  // Grab the subsystem for this thread
312  Thread *pThread = Processor::information().getCurrentThread();
313  Process *pProcess = pThread->getParent();
314  PosixSubsystem *pSubsystem =
315  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
316 
317  // If the alternate stack is in use, we're done with it for now
319  pSubsystem->getAlternateSignalStack();
320  if (currStack.inUse)
321  currStack.inUse = false;
322 
323  // Return to the old code
324  Processor::information().getScheduler().eventHandlerReturned();
325 
326  FATAL("eventHandlerReturned() returned!");
327 }
328 
329 void pedigree_unwind_signal()
330 {
331  SG_NOTICE("pedigree_unwind_signal");
332 
333  // Pop a state from the thread, but don't jump to it.
334  Thread *pThread = Processor::information().getCurrentThread();
335  pThread->popState();
336 }
337 
338 static int doThreadKill(Thread *p, int sig)
339 {
340  // Are we allowed to do this?
341  if (p->getStatus() == Thread::Suspended)
342  {
343  if (!(sig == SIGKILL || sig == SIGCONT))
344  {
345  WARNING("kill: can't send anything other than SIGKILL or SIGCONT "
346  "to a suspended process.");
347  return -1;
348  }
349  }
350 
351  Process *pThisProcess =
352  Processor::information().getCurrentThread()->getParent();
353 
354  // Build the pending signal and pass it in
355  PosixSubsystem *pSubsystem =
356  reinterpret_cast<PosixSubsystem *>(p->getParent()->getSubsystem());
357  if (!pSubsystem)
358  {
359  ERROR(
360  "posix_kill: no subsystem on process " << p->getParent()->getId());
361  return -1;
362  }
363  PosixSubsystem::SignalHandler *signalHandler =
364  pSubsystem->getSignalHandler(sig);
365  if (signalHandler && signalHandler->pEvent)
366  {
367  // Fire the event
368  p->sendEvent(reinterpret_cast<Event *>(signalHandler->pEvent));
369 
370  // Don't schedule to the process if that process is us.
371  if (p->getParent() != pThisProcess)
372  {
373  // Switch to that context in order to handle the event
374  bool bWasInterrupts = Processor::getInterrupts();
376  Processor::information().getScheduler().schedule(Thread::Ready, p);
377  Processor::setInterrupts(bWasInterrupts);
378  }
379  }
380 
381  return 0;
382 }
383 
384 static int doProcessKill(Process *p, int sig)
385 {
386  return doThreadKill(p->getThread(0), sig);
387 }
388 
389 int posix_kill(int pid, int sig)
390 {
391  SG_NOTICE("kill(" << pid << ", " << sig << ")");
392 
393  List<Process *> processList;
394 
395  // Metadata about the calling process.
396  PosixProcess *pThisProcess = static_cast<PosixProcess *>(
397  Processor::information().getCurrentThread()->getParent());
398  ProcessGroup *pThisGroup = pThisProcess->getProcessGroup();
399 
400  bool bKillingSelf = false;
401 
402  // Check for the process(es) we are about to kill.
403  size_t i = 0;
404  for (; i < Scheduler::instance().getNumProcesses(); ++i)
405  {
406  Process *pProcess = Scheduler::instance().getProcess(i);
407 
408  if (pProcess->getThread(0)->getStatus() == Thread::Zombie)
409  {
410  // Oops, process already been terminated.
411  if (static_cast<int>(pProcess->getId()) == pid)
412  break;
413  else
414  continue;
415  }
416  else if ((pid <= 0) && (pProcess->getType() == Process::Posix))
417  {
418  PosixProcess *pPosixProcess = static_cast<PosixProcess *>(pProcess);
419  ProcessGroup *pGroup = pPosixProcess->getProcessGroup();
420  if (pid == 0)
421  {
422  // Any process in the same process group as the caller.
423  if (!(pGroup && pThisGroup))
424  continue;
425  if (pGroup->processGroupId != pThisGroup->processGroupId)
426  continue;
427 
428  if (pGroup != pThisGroup)
429  {
430  SC_NOTICE(" -> same group IDs but different groups??");
431  }
432 
433  SC_NOTICE(
434  " -> killing process " << pProcess->getId() << " in group ["
435  << pGroup->processGroupId << "]");
436  }
437  else if (pid == -1)
438  {
439  // Kill all processes we have permission to kill (limit to only
440  // direct children for now)
441  if (pProcess->getParent() != pThisProcess)
442  continue;
443  }
444  else if (pGroup && (pGroup->processGroupId != (pid * -1)))
445  {
446  // Absolute group ID reference
447  continue;
448  }
449  }
450  else if ((pid > 0) && (static_cast<int>(pProcess->getId()) != pid))
451  continue;
452  else if (pProcess->getType() != Process::Posix)
453  continue;
454  else if (pid <= 0)
455  {
456  // process group option failed to fully succeed, don't kill
457  continue;
458  }
459 
460  // Okay, the process is good.
461  processList.pushBack(pProcess);
462  }
463 
464  // No process(es) found?
465  if (processList.count() == 0)
466  {
467  SYSCALL_ERROR(NoSuchProcess);
468  SG_NOTICE(" -> no such process");
469  return -1;
470  }
471 
472  // Go ahead and kill each process.
473  for (List<Process *>::Iterator it = processList.begin();
474  it != processList.end(); ++it)
475  {
476  PosixProcess *member = static_cast<PosixProcess *>(*it);
477  if (member != pThisProcess)
478  {
479  SG_NOTICE(
480  " -> not killing current process, killing " << member->getId());
481  NOTICE(
482  "sending #" << Dec << member->getId() << " signal #" << sig
483  << " from #" << pThisProcess->getId());
484  doProcessKill(member, sig);
485  }
486  else
487  {
488  SG_NOTICE(
489  " -> killing current process (" << pThisProcess->getId()
490  << ")");
491  bKillingSelf = true;
492  }
493  }
494 
495  // Yield to allow the events to be propagated across the process(es)
497 
498  if (bKillingSelf)
499  {
500  SG_NOTICE("performing kill of " << pThisProcess->getId() << "...");
501  NOTICE(
502  "sending self #" << Dec << pThisProcess->getId() << " signal #"
503  << sig);
504  doProcessKill(pThisProcess, sig);
505 
506  // If it was us, try to handle the signal *now*, or else we're going to
507  // end up who-knows-where on return.
508  Processor::information().getScheduler().checkEventState(0);
509  }
510 
511  return 0;
512 }
513 
515 int posix_sigprocmask(int how, const uint32_t *set, uint32_t *oset)
516 {
517  return 0;
518 }
519 
520 size_t posix_alarm(uint32_t seconds)
521 {
522  SG_NOTICE("alarm(" << seconds << ")");
523 
524  // Create the pending signal and pass it in
525  Process *pProcess =
526  Processor::information().getCurrentThread()->getParent();
527  PosixSubsystem *pSubsystem =
528  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
529  if (!pSubsystem)
530  {
531  ERROR("posix_alarm: no subsystem");
532  return -1;
533  }
534 
535  PosixSubsystem::SignalHandler *signalHandler =
536  pSubsystem->getSignalHandler(SIGALRM);
537  Event *pEvent = signalHandler->pEvent;
538 
539  // We now have the Event...
540  if (seconds == 0)
541  {
542  // Cancel the previous alarm, return the time it still had to go
543  if (pEvent)
544  return Machine::instance().getTimer()->removeAlarm(pEvent, false);
545  return 0;
546  }
547  else
548  {
549  if (pEvent)
550  {
551  // Stop any previous alarm
552  size_t ret =
553  Machine::instance().getTimer()->removeAlarm(pEvent, false);
554 
555  // Install the new one
556  Machine::instance().getTimer()->addAlarm(pEvent, seconds);
557 
558  // Return the time the previous event still had to go
559  return ret;
560  }
561  }
562 
563  // All done
564  return 0;
565 }
566 
567 int posix_sleep(uint32_t seconds)
568 {
569  SG_NOTICE("sleep");
570 
571  uint64_t startTick = Machine::instance().getTimer()->getTickCount();
572  Time::delay(seconds * Time::Multiplier::Second);
573 
577 
578  if (Processor::information().getCurrentThread()->wasInterrupted())
579  {
580  // Note: seconds is a uint32, therefore it should be safe to cast
581  // to half the width
582  uint64_t endTick = Machine::instance().getTimer()->getTickCount();
583  uint64_t elapsed = endTick - startTick;
584  uint32_t elapsedSecs = static_cast<uint32_t>(elapsed / 1000) + 1;
585 
586  if (elapsedSecs >= seconds)
587  return 0;
588  else
589  return elapsedSecs;
590  }
591 
592  return 0;
593 }
594 
595 int posix_usleep(size_t useconds)
596 {
597  SG_NOTICE("usleep");
598 
599  Time::delay(useconds * Time::Multiplier::Microsecond);
600 
604 
605  return 0;
606 }
607 
608 int posix_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
609 {
611  reinterpret_cast<uintptr_t>(rqtp), sizeof(struct timespec),
612  PosixSubsystem::SafeRead)) ||
614  reinterpret_cast<uintptr_t>(rmtp), sizeof(struct timespec),
615  PosixSubsystem::SafeWrite)))
616  {
617  SG_NOTICE("nanosleep -> invalid address");
618  SYSCALL_ERROR(InvalidArgument);
619  return -1;
620  }
621 
622  SG_NOTICE(
623  "nanosleep(" << Dec << rqtp->tv_sec << ":" << rqtp->tv_nsec << Hex
624  << ") - " << Machine::instance().getTimer()->getTickCount()
625  << ".");
626 
627  Time::Timestamp ts =
628  (rqtp->tv_sec * Time::Multiplier::Second) + rqtp->tv_nsec;
629  Time::delay(ts);
630 
631  if (rmtp)
632  {
633  rmtp->tv_nsec = rqtp->tv_nsec;
634  rmtp->tv_sec = rqtp->tv_sec;
635  }
636 
640 
641  return 0;
642 }
643 
644 int posix_clock_gettime(clockid_t clock_id, struct timespec *tp)
645 {
646  SG_NOTICE("clock_gettime");
648  reinterpret_cast<uintptr_t>(tp), sizeof(struct timespec),
649  PosixSubsystem::SafeWrite))
650  {
651  SYSCALL_ERROR(InvalidArgument);
652  return -1;
653  }
654 
655  // All clocks are equal, but some are more equal than others.
656  // Seriously though, we don't currently care about the id value.
657 
658  // We only care about the nanoseconds that may have passed in the past
659  // second - everything else is handled by the UNIX timestamp.
660  tp->tv_nsec = static_cast<time_t>(
661  (Machine::instance().getTimer()->getTickCount() * 1000ULL) %
662  1000000000ULL);
663  tp->tv_sec =
664  static_cast<time_t>(Machine::instance().getTimer()->getUnixTimestamp());
665 
666  return 0;
667 }
668 
669 int posix_sigaltstack(const stack_t *stack, stack_t *oldstack)
670 {
672 
673  // Verify arguments
674  if (!stack && !oldstack)
675  {
676  SYSCALL_ERROR(InvalidArgument);
677  return -1;
678  }
679  if (stack && (stack->ss_size < MINSIGSTKSZ))
680  {
681  SYSCALL_ERROR(OutOfMemory);
682  return -1;
683  }
684 
685  // Grab the subsystem for this thread
686  Thread *pThread = Processor::information().getCurrentThread();
687  Process *pProcess = pThread->getParent();
688  PosixSubsystem *pSubsystem =
689  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
690 
691  // Look at the current alternative stack
693  pSubsystem->getAlternateSignalStack();
694 
695  // Are we running on the alternate stack?
696  if (currStack.inUse)
697  {
698  SG_NOTICE("Can't set new alternate signal stack as it's the one we're "
699  "running on!");
700  SYSCALL_ERROR(InvalidArgument);
701  return -1;
702  }
703 
704  // Fill the old stack, if needed
705  if (oldstack)
706  {
707  oldstack->ss_sp = reinterpret_cast<void *>(currStack.base);
708  oldstack->ss_size = currStack.size;
709  oldstack->ss_flags = (currStack.inUse ? SA_ONSTACK : 0);
710  }
711 
712  // Set the new one
713  if (stack)
714  {
715  currStack.base = reinterpret_cast<uintptr_t>(stack->ss_sp);
716  currStack.size = stack->ss_size;
717  currStack.enabled = 1;
718  }
719 
720  // Success!
721  return 0;
722 }
723 
724 void pedigree_init_sigret()
725 {
726  SG_NOTICE("init_sigret");
727  static physical_uintptr_t sigretPhys = 0;
728 
729  // Handle allocation if needed.
730  if (sigretPhys == 0)
731  {
733  PhysicalMemoryManager::instance().pin(sigretPhys);
734 
735  // Map trampoline page in and bring across the sigret code.
736  Processor::information().getVirtualAddressSpace().map(
737  sigretPhys, reinterpret_cast<void *>(Event::getTrampoline()),
740 
741  MemoryCopy(
742  reinterpret_cast<void *>(Event::getTrampoline()),
743  reinterpret_cast<void *>(sigret_stub),
744  (reinterpret_cast<uintptr_t>(&sigret_stub_end) -
745  reinterpret_cast<uintptr_t>(sigret_stub)));
746 
747  // Mark read-only now that we have mapped in the page.
748  Processor::information().getVirtualAddressSpace().setFlags(
749  reinterpret_cast<void *>(Event::getTrampoline()),
751  }
752 
753  // Map the signal return stub to the correct location
754  if (!Processor::information().getVirtualAddressSpace().isMapped(
755  reinterpret_cast<void *>(Event::getTrampoline())))
756  {
757  Processor::information().getVirtualAddressSpace().map(
758  sigretPhys, reinterpret_cast<void *>(Event::getTrampoline()),
760  }
761 
762  // Install default signal handlers
763  Thread *pThread = Processor::information().getCurrentThread();
764  Process *pProcess = pThread->getParent();
765  PosixSubsystem *pSubsystem =
766  reinterpret_cast<PosixSubsystem *>(pProcess->getSubsystem());
767  if (!pSubsystem)
768  {
769  pSubsystem = new PosixSubsystem();
770  pProcess->setSubsystem(pSubsystem);
771  pSubsystem->setProcess(pProcess);
772  }
773 
774  for (size_t i = 0; i < 32; i++)
775  {
776  // Set all dispositions back to default, except if an ignore
777  // disposition was present (SIG_IGN does in fact carry through an exec)
778  int signalDisposition = 1;
779 
780  PosixSubsystem::SignalHandler *existingHandler =
781  pSubsystem->getSignalHandler(i);
782  if (existingHandler)
783  {
784  if (existingHandler->type == 2)
785  {
786  signalDisposition = 2;
787  }
788  }
789 
790  // Constructor zeroes out everything, which is correct for this initial
791  // setup of the signal handlers (except, of course, the handler
792  // location).
793  PosixSubsystem::SignalHandler *sigHandler =
795  sigHandler->sig = i;
796  sigHandler->type = signalDisposition;
797 
798  uintptr_t newHandler =
799  signalDisposition == 1 ?
800  reinterpret_cast<uintptr_t>(default_sig_handlers[i]) :
801  reinterpret_cast<uintptr_t>(sigign);
802 
803  sigHandler->pEvent = new SignalEvent(newHandler, i);
804 
805  pSubsystem->setSignalHandler(i, sigHandler);
806  }
807 
808  SG_NOTICE("Creating initial set of signal handlers is complete");
809 }
void pushBack(const T &value)
Definition: List.h:232
virtual void removeAlarm(class Event *pEvent)=0
static PhysicalMemoryManager & instance()
static bool getInterrupts()
void popState(bool clean=true)
Definition: Thread.cc:444
static uintptr_t getTrampoline()
Definition: Event.cc:66
virtual void pin(physical_uintptr_t page)=0
size_t getId()
Definition: Process.h:108
virtual Timer * getTimer()=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
size_t size
Size of the stack.
static ProcessorInformation & information()
Definition: Processor.cc:45
virtual Time::Timestamp getUnixTimestamp()
Definition: Timer.cc:23
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
#define WARNING(text)
Definition: Log.h:78
uintptr_t getHandlerAddress()
Definition: Event.h:108
bool sendEvent(Event *pEvent)
Definition: Thread.cc:529
uint32_t flags
Signal handler flags.
SignalHandler * getSignalHandler(size_t sig)
Process * getParent()
Definition: Process.h:150
virtual uint64_t getTickCount()=0
#define NOTICE(text)
Definition: Log.h:74
int type
Type - 0 = normal, 1 = SIG_DFL, 2 = SIG_IGN.
SignalEvent * pEvent
Event for the signal handler.
Definition: Log.h:136
size_t getNumProcesses()
Definition: Scheduler.cc:140
Iterator begin()
Definition: List.h:123
static Scheduler & instance()
Definition: Scheduler.h:48
Process * getProcess(size_t n)
Definition: Scheduler.cc:149
static void setInterrupts(bool bEnable)
size_t sig
Signal number.
uintptr_t base
The location of this stack.
bool inUse
Are we to use this alternate stack rather than a normal stack?
int processGroupId
Definition: PosixProcess.h:58
Thread * getThread(size_t n)
Definition: Process.cc:225
Status getStatus() const
Definition: Thread.h:192
Process * getParent() const
Definition: Thread.h:181
Definition: Thread.h:54
Definition: Event.h:48
void setSignalHandler(size_t sig, SignalHandler *handler)
virtual ProcessType getType()
Definition: Process.h:259
#define ERROR(text)
Definition: Log.h:82
void yield()
Definition: Scheduler.cc:135
Definition: Log.h:138
#define FATAL(text)
Definition: Log.h:89
virtual void addAlarm(class Event *pEvent, size_t alarmSecs, size_t alarmUsecs=0)=0
Iterator end()
Definition: List.h:135
virtual void setProcess(Process *p)
Definition: Subsystem.h:137
AlternateSignalStack & getAlternateSignalStack()
size_t count() const
Definition: List.h:227