Skip to content

Instantly share code, notes, and snippets.

@liviaerxin
Last active June 16, 2023 11:46
Show Gist options
  • Save liviaerxin/a0e515d8e515a46873bebac68c8693dd to your computer and use it in GitHub Desktop.
Save liviaerxin/a0e515d8e515a46873bebac68c8693dd to your computer and use it in GitHub Desktop.
Determine Universal App Is Running as a Native or Translated Binary #apple-silicon

Check Universal App Is Running as Native or Translated Binrary

On Apple silicon, arm app is running as native binary and x86_64 app is translated by Rosseta before executing.

Make Test Demo

❯ clang -o arm_proc_translated proc_translated.c -target arm64-apple-macos11
❯ clang -o x86_64_proc_translated proc_translated.c -target x86_64-apple-macos11
❯ lipo -create -output universal_proc_translated x86_64_proc_translated arm_proc_translated
❯ file universal_proc_translated 
universal_proc_translated: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
universal_proc_translated (for architecture x86_64):	Mach-O 64-bit executable x86_64
universal_proc_translated (for architecture arm64):	Mach-O 64-bit executable arm64

Test:

❯ arch -x86_64 zsh 
❯ ./universal_proc_translated 
processIsTranslated: 1

❯ arch -arm64 zsh
❯ ./universal_proc_translated 
processIsTranslated: 0

References

Determine Whether Your App Is Running as a Translated Binary
Building a Universal macOS Binary

#include <stdio.h>
#include <sys/sysctl.h>
struct clockinfo getClockinfo(void) {
int mib[2];
unsigned int freq;
size_t len;
mib[0] = CTL_HW;
mib[1] = HW_CPU_FREQ;
len = sizeof(freq);
sysctl(mib, 2, &freq, &len, NULL, 0);
printf("%u\n", freq);
mib[0] = CTL_KERN;
mib[1] = KERN_CLOCKRATE;
struct clockinfo clockinfo;
len = sizeof(clockinfo);
sysctl(mib, 2, &clockinfo, &len, NULL, 0);
printf("clockinfo.hz: %d\n", clockinfo.hz);
printf("clockinfo.tick: %d\n", clockinfo.tick);
return clockinfo;
}
int main() {
getClockinfo();
}
#include <stdio.h>
#include <sys/sysctl.h>
#include <errno.h>
int processIsTranslated(void) {
int ret = 0;
size_t size = sizeof(ret);
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1)
{
if (errno == ENOENT)
return 0;
return -1;
}
return ret;
}
int main() {
int is = processIsTranslated();
printf("processIsTranslated: %d\n", is);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment