Bug 23728 - binutils fail on macOS 10.14 (Mojave) due to unimplemented LC_BUILD_VERSION Mach-O load command
Summary: binutils fail on macOS 10.14 (Mojave) due to unimplemented LC_BUILD_VERSION M...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.32
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 23742 23746 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-09-30 10:36 UTC by Gilles Gouaillardet
Modified: 2019-01-07 08:19 UTC (History)
9 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2018-10-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gilles Gouaillardet 2018-09-30 10:36:56 UTC
nm from latest binutils (both released 2.31.1 and HEAD) seems unable to handle binaries on OS X 10.14 (Mojave)

For example

./nm-new nm-new 
./nm-new: nm-new: unknown load command 0x32
./nm-new: nm-new: unknown load command 0x32
./nm-new: nm-new: file format not recognized

I simply
./configure --prefix=... && make
and the error is 100% reproducible.
Comment 1 Gilles Gouaillardet 2018-10-01 05:59:15 UTC
As pointed in https://github.com/Homebrew/homebrew-core/issues/32516#issuecomment-425773174 this issue could be related to Xcode 10 and not (only) to OS X 10.14
Comment 2 Izaak "Zaak" Beekman 2018-10-23 20:57:57 UTC
I can reproduce this on macOS 10.14 with XCode 10.
Comment 3 Francois-Xavier Coudert 2018-10-24 16:17:20 UTC
I can confirm that binutils does not handle Mach-O object files generated for 10.14. See below:

rmeur /tmp $ cat a.c
void foo (void) { ; }
rmeur /tmp $ clang -c a.c                           
rmeur /tmp $ mv a.o 10.14.o
rmeur /tmp $ gnm 10.14.o
gnm: 10.14.o: unknown load command 0x32
gnm: 10.14.o: unknown load command 0x32
gnm: 10.14.o: unknown load command 0x32
gnm: 10.14.o: file format not recognized
rmeur /tmp $ nm 10.14.o 
0000000000000000 T _foo

where nm is Apple's own nm, and gnm is GNU Binutils 2.31.1. Using the -mmacosx-version-min=10.13 compiler switch produces an object file for macOS 10.13 compatibility, which binutils can handle:

rmeur /tmp $ clang -c a.c -mmacosx-version-min=10.13               
rmeur /tmp $ mv a.o 10.13.o
rmeur /tmp $ gnm 10.13.o 
0000000000000000 T _foo
rmeur /tmp $ nm 10.13.o 
0000000000000000 T _foo

The two object files are generated by the system assembler from the exact same assembly file, so the difference is really created by the assembler. In fact, calling the system "objdump" on them gives the exact same disassembly:

rmeur /tmp $ objdump -D 10.14.o

10.14.o:	file format Mach-O 64-bit x86-64

Disassembly of section __TEXT,__text:
_foo:
       0:	55 	pushq	%rbp
       1:	48 89 e5 	movq	%rsp, %rbp
       4:	5d 	popq	%rbp
       5:	c3 	retq
Disassembly of section __LD,__compact_unwind:
__compact_unwind:
       8:	00 00 	addb	%al, (%rax)
       a:	00 00 	addb	%al, (%rax)
       c:	00 00 	addb	%al, (%rax)
       e:	00 00 	addb	%al, (%rax)
      10:	06  <unknown>
      11:	00 00 	addb	%al, (%rax)
      13:	00 00 	addb	%al, (%rax)
      15:	00 00 	addb	%al, (%rax)
      17:	01 00 	addl	%eax, (%rax)
      19:	00 00 	addb	%al, (%rax)
      1b:	00 00 	addb	%al, (%rax)
      1d:	00 00 	addb	%al, (%rax)
      1f:	00 00 	addb	%al, (%rax)
      21:	00 00 	addb	%al, (%rax)
      23:	00 00 	addb	%al, (%rax)
      25:	00 00 	addb	%al, (%rax)
      27:	00  <unknown>
Disassembly of section __TEXT,__eh_frame:
__eh_frame:
      28:	14 00 	adcb	$0, %al
      2a:	00 00 	addb	%al, (%rax)
      2c:	00 00 	addb	%al, (%rax)
      2e:	00 00 	addb	%al, (%rax)
      30:	01 7a 52 	addl	%edi, 82(%rdx)
      33:	00 01 	addb	%al, (%rcx)
      35:	78 10 	js	16 <__eh_frame+0x1f>
      37:	01 10 	addl	%edx, (%rax)
      39:	0c 07 	orb	$7, %al
      3b:	08 90 01 00 00 24 	orb	%dl, 603979777(%rax)
      41:	00 00 	addb	%al, (%rax)
      43:	00 1c 00 	addb	%bl, (%rax,%rax)
      46:	00 00 	addb	%al, (%rax)
      48:	b8 ff ff ff ff 	movl	$4294967295, %eax
      4d:	ff ff  <unknown>
      4f:	ff 06 	incl	(%rsi)
      51:	00 00 	addb	%al, (%rax)
      53:	00 00 	addb	%al, (%rax)
      55:	00 00 	addb	%al, (%rax)
      57:	00 00 	addb	%al, (%rax)
      59:	41 0e  <unknown>
      5b:	10 86 02 43 0d 06 	adcb	%al, 101532418(%rsi)
      61:	00 00 	addb	%al, (%rax)
      63:	00 00 	addb	%al, (%rax)
      65:	00 00 	addb	%al, (%rax)
      67:	00  <unknown>

(the output is exactly the same for 10.14)

I have placed the object files at https://www.dropbox.com/s/pn7gyyqfd1f0xdp/binutils-10.14.zip?dl=0
Comment 4 Francois-Xavier Coudert 2018-10-24 16:26:25 UTC
I've found the root of the issue. binutils does not handle load command 0x32 LC_BUILD_VERSION (nor 0x31 LC_NOTE, actually). They are defined in recent LLVM versions: see https://github.com/llvm-mirror/llvm/blob/master/include/llvm/BinaryFormat/MachO.def#L77

Looking at the output of objdump -private-headers there is one clear difference:

@@ -56,16 +56,18 @@ attributes NO_TOC STRIP_STATIC_SYMS LIVE
  reserved1 0
  reserved2 0
 Load command 1
-      cmd LC_VERSION_MIN_MACOSX
-  cmdsize 16
-  version 10.13
-      sdk n/a
+       cmd LC_BUILD_VERSION
+   cmdsize 24
+  platform macos
+       sdk n/a
+     minos 10.14
+    ntools 0
 Load command 2
      cmd LC_SYMTAB
  cmdsize 24


LC_VERSION_MIN_MACOSX is implemented in binutils, while LC_BUILD_VERSION is not. It is apparently new in Mojave.
Comment 5 Roman Bolshakov 2018-11-06 02:52:09 UTC
I'm wrapping up a patch series that adds full support for parsing and printing of LC_BUILD_VERSION.
Comment 6 Nick Clifton 2018-11-06 17:21:20 UTC
Hi Guys,

  I have applied a patch suggested by Romain in PR 23746 which might
  improve things in this area.  Would someone please test out the latest
  mainline sources to see if anything has improved ?

Cheers
  Nick
Comment 7 Sourceware Commits 2018-11-07 15:22:32 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fc7b364aba41819a5d74ae0ac69f050af282d057

commit fc7b364aba41819a5d74ae0ac69f050af282d057
Author: Roman Bolshakov <r.bolshakov@yadro.com>
Date:   Wed Nov 7 15:20:22 2018 +0000

    Add support for new load commands added by Apple to the MACH-O file format.
    
    bfd	* mach-o.h: Add new enums for BFD_MACH_O_PLATFORM_MACOS,
    	BFD_MACH_O_PLATFORM_IOS, BFD_MACH_O_PLATFORM_TVOS,
    	BFD_MACH_O_PLATFORM_WATCHOS, BFD_MACH_O_PLATFORM_BRIDGEOS,
    	BFD_MACH_O_TOOL_CLANG, BFD_MACH_O_TOOL_SWIFT, BFD_MACH_O_TOOL_LD.
    	(struct bfd_mach_o_note_command): New.
    	(struct bfd_mach_o_build_version_tool): New.
    	(struct bfd_mach_o_build_version_command): New.
    	(bfd_mach_o_read_version_min): Don't split version into
    	a few fields. Rename reserved to sdk.
    	* mach-o.c (bfd_mach_o_read_version_min): Don't split version into a
    	few fields. Rename reserved to sdk.
    	(bfd_mach_o_read_command): Handle LC_VERSION_MIN_TVOS, LC_NOTE,
    	LC_BUILD_VERSION.
    	(bfd_mach_o_read_note): New.
    	(bfd_mach_o_read_build_version): New.
    
    	PR 23728
    binutils* od-macho.c (printf_version): New.
    	(dump_load_command): Use it to print version. Print sdk version. Print
    	version info for watchOS and tvOS. Print LC_NOTE, LC_BUILD_VERSION.
    	(dump_buld_version): New.
    	(bfd_mach_o_platform_name): New
    	(bfd_mach_o_tool_name): New
    
    	* mach-o/external.h (mach_o_nversion_min_command_external): Rename
    	reserved to sdk.
    	(mach_o_note_command_external): New.
    	(mach_o_build_version_command_external): New.
    	* mach-o/loader.h (BFD_MACH_O_LC_VERSION_MIN_TVOS): Define.
    	(BFD_MACH_O_LC_NOTE): Define.
Comment 8 Tom Tromey 2018-11-15 16:30:47 UTC
*** Bug 23742 has been marked as a duplicate of this bug. ***
Comment 9 Tom Tromey 2018-11-15 16:34:12 UTC
I believe this is fixed now.
This will appear in gdb 8.3.
Comment 10 Tom Tromey 2018-12-10 17:26:10 UTC
*** Bug 23746 has been marked as a duplicate of this bug. ***
Comment 11 Tom Tromey 2018-12-11 21:25:37 UTC
*** Bug 23949 has been marked as a duplicate of this bug. ***
Comment 12 timothee cour 2019-01-06 21:31:43 UTC
my other bug report https://sourceware.org/bugzilla/show_bug.cgi?id=23949 was closed as a duplicate of this bug, however:
this bug says: 
* I believe this is fixed now.

whereas the problem I reported (that gdb is unusable on latest OSX, ie since Mojave) is still there, as you can see here https://github.com/Homebrew/homebrew-core/pull/35419#issuecomment-451734657
the problem is still not resolved in git head of gdb.
Comment 13 Nick Clifton 2019-01-07 08:19:43 UTC
(In reply to timothee cour from comment #12)
Hi Timothee,

> whereas the problem I reported (that gdb is unusable on latest OSX, ie since
> Mojave) is still there, as you can see here
> https://github.com/Homebrew/homebrew-core/pull/35419#issuecomment-451734657
> the problem is still not resolved in git head of gdb.

It looks like this is probably a different problem to the one that was fixed with this PR, so please could you open a new bug report, detailing the problem and with GDB as the component, rather than BINUTILS.

Cheers
  Nick