Behold!

I don't think this actually safely works though on x86 at least.
Pretty sure they use the virtual address for instruction caching and 
debuggers have to do synchronisation when modifying from a different 
address space.

oh well.

On Friday, May 29, 2020 at 9:46:38 AM UTC-7, Steven Stewart-Gallus wrote:
>
> Okay I have an idea.
> I can't shake the idea you could do fun tricks with thread local 
> executable pages.
>
> The theoretically fastest way of safepoint polling is inserting a trap 
> instruction. But icache overheads dominate. If the icache is based on 
> physical addresses and not virtual ones then it should be possible to remap 
> the page without doing icache synchronization.
> You should be able to have very fast safepoints by remapping the page.
>
> But I'm not sure there's a fast way to do a call/return from thread local 
> storage. And a call/return from a constant page still might not be faster 
> than just a load.
>
> TLDR:
> Limited self modifying code without icache syncing stuff could be possible 
> with memory management tricks as long as the icache and other stuff is 
> based on physical addresses.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/mechanical-sympathy/9ca6f9d0-1b06-44f9-b540-dca4a2d51bc4%40googlegroups.com.
#define _GNU_SOURCE 1

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

extern char __safepoint_start__;
extern char __safepoint_end__;

void  __attribute__ ((section (".text.safepoint.hook")))  __attribute__ ((aligned (4096)))  __attribute__ ((noinline)) safepoint() {
        puts("Should be overwritten always");
}

void __attribute__ ((section (".text.safepoint.functions")))    __attribute__ ((aligned (4096)))  __attribute__ ((aligned (4096))) __attribute__ ((noinline)) safepoint_nothing() {
        // be very very careful here...
}

void __attribute__ ((section (".text.safepoint.functions")))    __attribute__ ((aligned (4096)))  __attribute__ ((aligned (4096))) __attribute__ ((noinline)) safepoint_trap() {
        // be very very careful here... can't do nothing..
        __builtin_trap();
}


void map_safepoint(int fd, off_t offset)
{
        //fixme...
        int pagesize = getpagesize();
        void *start = safepoint;
        start = (void*)( (((uintptr_t)start) / pagesize) * pagesize);
        void *result = mmap(start, pagesize, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
        if (MAP_FAILED == result) {
                perror("mmap");
                exit(1);
        }
}

int do_nothing_fd;
int do_trap_fd;
void handler(int x) {
        puts("yes I know this is unsafe in a signal handler");
        // handle safepoint...
        map_safepoint(do_nothing_fd, 0);
}

int main() {
        do_nothing_fd = memfd_create("do_nothing", MFD_CLOEXEC);
        if (do_nothing_fd < 0) {
                perror("memfd_create");
                return 1;
        }
        if (write(do_nothing_fd, safepoint_nothing, getpagesize()) < 0) {
                perror("write");
                return 1;
        }

        do_trap_fd = memfd_create("do_trap", MFD_CLOEXEC);
        if (do_trap_fd < 0) {
                perror("memfd_create");
                return 1;
        }
        if (write(do_trap_fd, safepoint_trap, getpagesize()) < 0) {
                perror("write");
                return 1;
        }


        map_safepoint(do_nothing_fd, 0);

        {
                struct sigaction act = {0};
                act.sa_handler = handler;
                if (sigaction(SIGILL, &act, 0) < 0) {
                        perror("signal");
                        return 1;

                }
        }

        safepoint();

        map_safepoint(do_trap_fd, 0);

        safepoint();

        return 0;
}

Reply via email to