Files
borysp c24bddd5aa [LibOS] Rework signal handling and syscall emulation
Change log (most important only):
- unify CPU context structures - now we have only one version -
  `PAL_CONTEXT` - which is shared between LibOS and PALs and it should
  depend only on the host architecture (not OS),
- syscalls emulation changed:
  - dedicated LibOS stack is now used for syscalls emulation,
  - removed one indirection level in syscalls table - now it stores
    `shim_do_*` functions directly,
- signal handling - completely rewritten:
  - all signal queues use proper locking schemes now,
  - signals are handled *only* when returning to the user app from LibOS
    or PAL,
  - nested signals are now possible,
  - the app is allowed to jump out of signal handler with the same
    sematics as on normal Linux,
  - signal altstack is now fully supported,
  - syscall restarting is now supported,
  - doing a backtrace from the signal handler works properly,
- disallow injecting host-level signals, with one exception, see
  `sys.enable_sigterm_injection` manifest option for more details.
2021-02-05 14:11:21 +01:00

80 lines
2.3 KiB
C

/* XXX: What on earth is this supposed to be, an attempt to fit most UBs in one file? */
#include <stdbool.h>
#include "api.h"
#include "pal.h"
#include "pal_debug.h"
#define UNIT (pal_control.alloc_align)
static volatile int count = 0;
static void handler(bool is_in_pal, PAL_NUM arg, PAL_CONTEXT* context) {
__UNUSED(is_in_pal);
count++;
pal_printf("Memory Fault %d\n", count);
#if defined(__i386__) || defined(__x86_64__)
while (*(unsigned char*)context->rip != 0x90) {
context->rip++;
}
#else
#error Unsupported architecture
#endif
}
int main(int argc, char** argv, char** envp) {
volatile int c;
DkSetExceptionHandler(handler, PAL_EVENT_MEMFAULT);
void* mem1 = (void*)DkVirtualMemoryAlloc(NULL, UNIT * 4, 0, PAL_PROT_READ | PAL_PROT_WRITE);
if (mem1)
pal_printf("Memory Allocation OK\n");
void* mem2 = (void*)DkVirtualMemoryAlloc(NULL, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE);
if (mem2) {
c = count;
*(volatile int*)mem2 = 0;
pal_printf("(int *) %p = %d\n", mem2, *(volatile int*)mem2);
if (c == count)
pal_printf("Memory Allocation Protection (RW) OK\n");
DkVirtualMemoryProtect(mem2, UNIT, PAL_PROT_READ);
c = count;
*(volatile int*)mem2 = 0;
__asm__ volatile("nop");
if (c == count - 1)
pal_printf("Memory Protection (R) OK\n");
DkVirtualMemoryFree(mem2, UNIT);
c = count;
*(volatile int*)mem2 = 0;
__asm__ volatile("nop");
if (c == count - 1)
pal_printf("Memory Deallocation OK\n");
}
void* mem3 = (void*)pal_control.user_address.start;
void* mem4 = (void*)pal_control.user_address.end - UNIT;
mem3 = (void*)DkVirtualMemoryAlloc(mem3, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE);
mem4 = (void*)DkVirtualMemoryAlloc(mem4, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE);
if (mem3 && mem4)
pal_printf("Memory Allocation with Address OK\n");
/* Testing total memory */
pal_printf("Total Memory: %lu\n", pal_control.mem_info.mem_total);
/* Testing available memory (must be within valid range) */
PAL_NUM avail = DkMemoryAvailableQuota();
if (avail > 0 && avail < pal_control.mem_info.mem_total)
pal_printf("Get Memory Available Quota OK\n");
return 0;
}