News for hackers. Stuff that matters.
Re:About the Rosetta Translation Environment by saagarjha on Tuesday June 23, 2020 @09:21PM (#23622805)
> Rosetta 2 is probably built on LLVM. Why wouldn't it be?

LLVM is kind of slow; JavaScriptCore abandoned it years ago for their FTL backend.

> The unique pattern of machine-code that must occur in any implementation of JIT, is a jump to a memory address that was computed entirely at runtime, i.e. with a https://en.wikipedia.org/wiki/Use-define_chain for that address value that leads back to a call to mmap(2) or malloc(2).

  void *region = mmap(0x100000000, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED, 0, 0);
  memcpy(region, code, 0x1000);
  mprotect(0x100000000, 0x1000, PROT_READ | PROT_EXEC);
  reinterpret_cast<(void (*)())>(region)();
Re:About the Rosetta Translation Environment by derefr on Wednesday June 24, 2020 @09:47AM (#23627812)
Re: your rebuttal code — that’s still a use-define chain. You don’t need the same literal pointer; you just need to know that the value of the pointer ultimately depended on a the output of mmap(2). Since the mmap(2) region address is passed into memcpy(2)—and memcpy(2) can fail, producing NULL—the output of memcpy(2) does then depend on the input. (Even if it didn’t, you could just lie to the compiler and tell it to pretend that memcpy(2) always depends on its input.)
Re:About the Rosetta Translation Environment by tom_mellior on Wednesday June 24, 2020 @10:44AM (#23628404)
> and memcpy(2) can fail, producing NULL

Huh, this is news to me. The memcpy(3) man page on my Linux box (there is no memcpy(2) here) doesn't mention this either, is this some special MacOS or BSD feature of memcpy? Under what circumstances would it determine that it should fail?

Your reasoning is strange anyway since the memcpy has nothing to do with anything, the implicit information flow from mmap to mprotect would exist even if the memcpy and the region variable were removed:

  mmap(0x100000000, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED, 0, 0);
  mprotect(0x100000000, 0x1000, PROT_READ | PROT_EXEC);