Created
March 15, 2026 21:14
-
-
Save theMackabu/87462690ec724c8f38fe932daa89ce76 to your computer and use it in GitHub Desktop.
undefined behavior land
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #define fmt(x) _Generic((x), \ | |
| int: "%d", \ | |
| long: "%ld", \ | |
| float: "%f", \ | |
| double: "%lf", \ | |
| char: "%c", \ | |
| char*: "%s", \ | |
| const char*: "%s", \ | |
| default: "%p" \ | |
| ) | |
| #define print_one(x) printf(fmt(x), x) | |
| #define PRINT_1(a) print_one(a) | |
| #define PRINT_2(a,b) print_one(a); print_one(b) | |
| #define PRINT_3(a,b,c) print_one(a); print_one(b); print_one(c) | |
| #define PRINT_4(a,b,c,d) print_one(a); print_one(b); print_one(c); print_one(d) | |
| #define PRINT_5(a,b,c,d,e) print_one(a); print_one(b); print_one(c); print_one(d); print_one(e) | |
| #define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME | |
| #define print(...) GET_MACRO(__VA_ARGS__, PRINT_5,PRINT_4,PRINT_3,PRINT_2,PRINT_1)(__VA_ARGS__) | |
| int main(void){ | |
| print("This print works in c and does not care about types\n"); | |
| char* name = "Pablo"; | |
| int age = 67; | |
| print("this guy's name is ", name, " and he's ", age, " years old\n"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdarg.h> | |
| #include <stdint.h> | |
| #include <signal.h> | |
| #include <setjmp.h> | |
| #define SENTINEL 0xDEADBEEFCAFEBABEULL | |
| static sigjmp_buf probe_jmp; | |
| static void probe_handler(int sig) { siglongjmp(probe_jmp, 1); } | |
| static int can_read(uint64_t v) { | |
| struct sigaction sa = { | |
| .sa_handler = probe_handler | |
| }, old_bus, old_segv; | |
| sigaction(SIGBUS, &sa, &old_bus); | |
| sigaction(SIGSEGV, &sa, &old_segv); | |
| volatile int ok = 0; | |
| if (sigsetjmp(probe_jmp, 1) == 0) { | |
| (void)*(volatile char *)(uintptr_t)v; | |
| ok = 1; | |
| } | |
| sigaction(SIGBUS, &old_bus, NULL); | |
| sigaction(SIGSEGV, &old_segv, NULL); | |
| return ok; | |
| } | |
| __attribute__((noinline)) | |
| static void __print_inner(int dummy, ...) { | |
| enum { T_INT, T_STR, T_DBL, T_COUNT }; | |
| va_list ap; | |
| va_start(ap, dummy); | |
| uint64_t *slot = (uint64_t *)(void *)ap; | |
| static const void *dispatch[] = { | |
| [T_INT] = &&l_int, | |
| [T_STR] = &&l_str, | |
| [T_DBL] = &&l_double, | |
| }; | |
| while (*slot != SENTINEL) { | |
| uint64_t v = *slot++; | |
| uint8_t t = T_INT; | |
| if (v >= 0x1000 && v <= 0x0000ffffffffffff && can_read(v)) { | |
| unsigned char c = *(unsigned char *)(uintptr_t)v; | |
| if ((c >= 0x20 && c < 0x7f) || c == '\n' || c == '\t' || c == '\r' || c == '\0') t = T_STR; | |
| } | |
| if (t == T_INT && v > 0x7FFFFFFF) { | |
| uint64_t exp = (v >> 52) & 0x7FF; | |
| if (exp > 0 && exp < 0x7FF) t = T_DBL; | |
| } | |
| if (t < T_COUNT && dispatch[t]) goto *dispatch[t]; | |
| continue; | |
| l_double: { | |
| double d; | |
| __builtin_memcpy(&d, &v, 8); | |
| printf("%g", d); | |
| continue; | |
| } | |
| l_int: printf("%d", (int)v); continue; | |
| l_str: printf("%s", (const char *)(uintptr_t)v); continue; | |
| } | |
| va_end(ap); | |
| } | |
| #define print(...) __print_inner(0, __VA_ARGS__, SENTINEL) | |
| int main(void) { | |
| print("This print works in c and does not care about types\n"); | |
| char *name = "Pablo"; | |
| int age = 67; | |
| double pi = 3.14159; | |
| long big = 42L; | |
| print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdarg.h> | |
| #include <stdint.h> | |
| #include <signal.h> | |
| #include <setjmp.h> | |
| #define SENTINEL 0xDEADBEEFCAFEBABEULL | |
| static sigjmp_buf probe_jmp; | |
| static void probe_handler(int sig) { siglongjmp(probe_jmp, 1); } | |
| __attribute__((noinline)) | |
| static void __print_inner(int dummy, ...) { | |
| enum { T_INT, T_STR, T_DBL, T_COUNT }; | |
| va_list ap; | |
| va_start(ap, dummy); | |
| uint64_t *slot = (uint64_t *)(void *)ap; | |
| static const void *dispatch[] = { | |
| [T_INT] = &&l_int, | |
| [T_STR] = &&l_str, | |
| [T_DBL] = &&l_double, | |
| }; | |
| struct sigaction sa = {.sa_handler = probe_handler}, ob, os; | |
| sigaction(SIGBUS, &sa, &ob); | |
| sigaction(SIGSEGV, &sa, &os); | |
| while (*slot != SENTINEL) { | |
| uint64_t v = *slot++; | |
| uint8_t t = T_INT; | |
| if (sigsetjmp(probe_jmp, 1) == 0) { | |
| uint32_t is_str; | |
| __asm__ volatile( | |
| "ldrb %w[c], [%[ptr]]\n\t" | |
| "sub %w[r], %w[c], #0x20\n\t" | |
| "cmp %w[r], #0x5F\n\t" | |
| "cset %w[r], lo\n\t" | |
| "sub %w[c], %w[c], #9\n\t" | |
| "cmp %w[c], #5\n\t" | |
| "csinc %w[r], %w[r], %w[r], hs" | |
| : [r] "=&r"(is_str), [c] "=&r"((uint32_t){0}) | |
| : [ptr] "r"((void*)(uintptr_t)v) | |
| : "cc", "memory" | |
| ); | |
| if (is_str) t = T_STR; | |
| } | |
| if (t == T_INT && v > 0x7FFFFFFF) { | |
| uint32_t is_dbl; | |
| __asm__ volatile( | |
| "ubfx %w[e], %w[hi], #20, #11\n\t" | |
| "sub %w[e], %w[e], #1\n\t" | |
| "cmp %w[e], #0x7FE\n\t" | |
| "cset %w[e], lo" | |
| : [e] "=r"(is_dbl) : [hi] "r"((uint32_t)(v >> 32)) : "cc" | |
| ); | |
| if (is_dbl) t = T_DBL; | |
| } | |
| if (t < T_COUNT) goto *dispatch[t]; | |
| continue; | |
| l_str: printf("%s", (const char *)(uintptr_t)v); continue; | |
| l_double: { double d; __builtin_memcpy(&d, &v, 8); printf("%g", d); continue; } | |
| l_int: printf("%d", (int)v); continue; | |
| } | |
| sigaction(SIGBUS, &ob, NULL); | |
| sigaction(SIGSEGV, &os, NULL); | |
| va_end(ap); | |
| } | |
| #define print(...) __print_inner(0, __VA_ARGS__, SENTINEL) | |
| int main(void) { | |
| print("This print works in c and does not care about types\n"); | |
| char *name = "Pablo"; | |
| int age = 67; | |
| double pi = 3.14159; | |
| long big = 42L; | |
| print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdarg.h> | |
| #include <stdint.h> | |
| #include <signal.h> | |
| #include <setjmp.h> | |
| #define SENTINEL 0xDEADBEEFCAFEBABEULL | |
| static sigjmp_buf jmp; | |
| static void handler(int s) { siglongjmp(jmp, 1); } | |
| static void _print(int d, ...) { | |
| va_list ap; va_start(ap, d); | |
| uint64_t *slot = (uint64_t *)(void *)ap; | |
| struct sigaction sa = {.sa_handler = handler}, ob, os; | |
| sigaction(SIGBUS, &sa, &ob); sigaction(SIGSEGV, &sa, &os); | |
| for (uint64_t v; (v = *slot++) != SENTINEL;) { | |
| int t = 0; | |
| if (!sigsetjmp(jmp, 1)) { | |
| unsigned char c = *(char *)(uintptr_t)v; | |
| t = (c - 9u < 5) || (c - 0x20u < 0x5F); | |
| } | |
| if (!t && ((v >> 52 & 0x7FF) - 1u < 0x7FE)) t = 2; | |
| double f; __builtin_memcpy(&f, &v, 8); | |
| t == 1 | |
| ? printf("%s", (char *)(uintptr_t)v) | |
| : t == 2 ? printf("%g", f) | |
| : printf("%d", (int)v); | |
| } | |
| sigaction(SIGBUS, &ob, 0); sigaction(SIGSEGV, &os, 0); | |
| } | |
| #define print(...) _print(0, __VA_ARGS__, SENTINEL) | |
| int main(void) { | |
| print("This print works in c and does not care about types\n"); | |
| char *name = "Pablo"; | |
| int age = 67; | |
| double pi = 3.14159; | |
| long big = 42L; | |
| print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment