0

File (cmd tool) shows /bin/ls is a fat binary on macOS (Sonoma 14.2.1 on Apple M1) and otool -f confirms that:

% file /bin/ls
/bin/ls: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/bin/ls (for architecture x86_64):  Mach-O 64-bit executable x86_64
/bin/ls (for architecture arm64e):  Mach-O 64-bit executable arm64e
% otool -f /bin/ls
Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 16777223
    cpusubtype 3
    capabilities 0x0
    offset 16384
    size 72896
    align 2^14 (16384)
architecture 1
    cputype 16777228
    cpusubtype 2
    capabilities 0x80
    offset 98304
    size 88816
    align 2^14 (16384)

However, otool -h shows only one Mach-O header:

% otool -h /bin/ls
/bin/ls:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          2  0x80           2    19       1728 0x00200085

The same behavior can be observed for other binaries in /bin folder.

Interestingly, otool -h does show all architectures for fat binaries being part of 3rd party applications (being arm64, while system binaries are arm64e). Example:

% otool -h /Applications/Firefox.app/Contents/MacOS/firefox 
/Applications/Firefox.app/Contents/MacOS/firefox (architecture x86_64):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777223          3  0x80           2    21       1856 0x00210085
/Applications/Firefox.app/Contents/MacOS/firefox (architecture arm64):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    22       1880 0x00210085

Why does otool -h not show x86_64 Mach-O header for system binaries (arm64e) while it does show it for 3rd party binaries (arm64)?

1 Answer 1

2

See this nearly 10-year old question https://stackoverflow.com/questions/27354315/what-is-the-difference-between-mach-headers-and-fat-headers regarding mach and fat headers.

I believe it is still correct and what you need is:

otool -h -arch all /bin/ls

or (better because it decodes some items):

otool -hV -arch all /bin/ls

to give:

/bin/ls (architecture x86_64):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64   X86_64        ALL  0x00     EXECUTE    18       1816   NOUNDEFS DYLDLINK TWOLEVEL PIE
/bin/ls (architecture arm64e):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64    ARM64          E USR00     EXECUTE    19       1728   NOUNDEFS DYLDLINK TWOLEVEL PIE
2
  • otool -arch all works, but interestingly otool -h does show all architectures for fat binaries being part of 3rd party applications (and arm64, not arm64e as system binaries). I've edited the question.
    – mrn
    Commented Mar 29 at 9:32
  • Sorry, I don't know the details of how fat binaries are built. I can only answer your question about the use of otool.
    – Gilby
    Commented Mar 29 at 21:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .