tech-pkg archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Can't build lang/openjdk{17,21} on NetBSD/aarch64 (Apple M3)
My previous mail about Apple Silicon's W^X enforcement turned out to be
wrong. I wrote this code to see if W+X works on the very chip, and
surprisingly, it worked:
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
const uint32_t insn_ret = 0xD65F03C0;
const uint32_t insn_nop = 0xD503201F;
int main() {
printf("Allocating a page with W+X. This would fail unless PaX MPROTECT
is enabled.\n");
void* page = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_EXEC|PROT_WRITE,
MAP_ANON, -1, 0);
if (page == MAP_FAILED)
err(1, "mmap failed. Did you forget to paxctl +m the executable?");
printf("Successfully mapped a page. Now writing some instructions on
it...\n");
uint32_t* insn_p = page;
*(insn_p++) = insn_ret;
*(insn_p++) = insn_nop;
__builtin___clear_cache(page, page + sysconf(_SC_PAGESIZE));
printf("Done. Now calling it as a function.\n");
typedef void(*thunk_t)();
thunk_t thunk = page;
thunk();
printf("We survived and returned to main(). The call was successful.\n");
printf("What if we rewrite instructions and run it again? Does that
work?\n");
insn_p = page;
*(insn_p++) = 0xD2800550; // mov x16, #42
*(insn_p++) = insn_ret;
*(insn_p++) = insn_nop;
__builtin___clear_cache(page, page + sysconf(_SC_PAGESIZE));
register uint64_t x16 __asm__("x16") = 0;
thunk();
// Tell the compiler that we just clobbered x16.
__asm__ __volatile__ ("": "=r"(x16));
if (x16 == 42)
printf("It worked!\n");
else
errx(1, "We tried to write 42 to x16 but x16 now contains something we
didn't expect: %lu\n", x16);
return 0;
}
So it's likely that the problem is about clearing instruction cache,
which OpenJDK 17 does, but somehow isn't working on this chip. But
omitting __builtin_clear_cache() from the code above did make it execute
wrong instructions so the builtin itself is working.
Home |
Main Index |
Thread Index |
Old Index