Skip to content

Instantly share code, notes, and snippets.

@minoki
Last active October 19, 2023 09:38
Show Gist options
  • Save minoki/c667e9af0adaff569c238925670a68c1 to your computer and use it in GitHub Desktop.
Save minoki/c667e9af0adaff569c238925670a68c1 to your computer and use it in GitHub Desktop.
Code generation on x86_64
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h> // mmap, mprotect, munmap
#include <unistd.h>
typeof(int (*)(int)) adder(int y)
{
void *mem = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED) {
int e = errno;
fprintf(stderr, "mmap: %s (%d)\n", strerror(e), e);
abort();
}
unsigned char *instr = mem;
*instr++ = 0x81; *instr++ = 0xc7; // add edi, ...
memcpy(instr, &y, 4); instr += 4; // <imm32>
*instr++ = 0x89; *instr++ = 0xf8; // mov eax, edi
*instr++ = 0xc3; // ret
__builtin___clear_cache(mem, (void *)instr);
int ret = mprotect(mem, getpagesize(), PROT_READ | PROT_EXEC);
if (ret != 0) {
int e = errno;
fprintf(stderr, "mprotect: %s (%d)\n", strerror(e), e);
abort();
}
return (int (*)(int))mem;
}
int main(void)
{
int (*f)(int) = adder(3);
int (*g)(int) = adder(-7);
int (*h)(int) = adder(42);
printf("f(0) = %d\n", f(0));
printf("f(-5) = %d\n", f(-5));
printf("f(2) = %d\n", f(2));
printf("g(0) = %d\n", g(0));
printf("g(-5) = %d\n", g(-5));
printf("g(2) = %d\n", g(2));
printf("h(0) = %d\n", h(0));
printf("h(-5) = %d\n", h(-5));
printf("h(2) = %d\n", h(2));
}
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h> // mmap, mprotect, munmap
#include <unistd.h>
typeof(int (*)(int)) adder(int y)
{
void *mem = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED) {
int e = errno;
fprintf(stderr, "mmap: %s (%d)\n", strerror(e), e);
abort();
}
unsigned char *instr = mem;
*instr++ = 0x81; *instr++ = 0xc7; // add edi, ...
memcpy(instr, &y, 4); instr += 4; // <imm32>
*instr++ = 0x89; *instr++ = 0xf8; // mov eax, edi
*instr++ = 0xc3; // ret
__builtin___clear_cache(mem, (void *)instr);
return (int (*)(int))mem;
}
int main(void)
{
int (*f)(int) = adder(3);
int (*g)(int) = adder(-7);
int (*h)(int) = adder(42);
printf("f(0) = %d\n", f(0));
printf("f(-5) = %d\n", f(-5));
printf("f(2) = %d\n", f(2));
printf("g(0) = %d\n", g(0));
printf("g(-5) = %d\n", g(-5));
printf("g(2) = %d\n", g(2));
printf("h(0) = %d\n", h(0));
printf("h(-5) = %d\n", h(-5));
printf("h(2) = %d\n", h(2));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment