All new binaries compiled for macOS Mojave (10.14) and a few other new
platforms have started to use the new load command that essentially
replaced LC_*_VERSION_MIN commands.
Inability to handle the command prevented the whole set of binutils,
including gdb from processing new macOS binaries.
Signed-off-by: Roman Bolshakov <***@yadro.com>
Signed-off-by: Saagar Jha <***@saagarjha.com>
Cc: Tristan Gingold <***@free.fr>
Cc: Tom Tromey <***@tromey.com>
---
bfd/ChangeLog | 14 ++++++--
bfd/mach-o.c | 20 +++++++++++
bfd/mach-o.h | 29 ++++++++++++++++
binutils/ChangeLog | 6 +++-
binutils/od-macho.c | 71 ++++++++++++++++++++++++++++++++++++++-
include/ChangeLog | 2 ++
include/mach-o/external.h | 8 +++++
include/mach-o/loader.h | 1 +
8 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1f017f6fcd..6c6236032a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,13 +1,21 @@
2018-11-06 Roman Bolshakov <***@yadro.com>
Saagar Jha <***@saagarjha.com>
- * mach-o.h (bfd_mach_o_version_min_command): Don't split version into
- a few fields. Rename reserved to sdk.
+ * 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.
+ (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.
2018-11-02 Alan Modra <***@gmail.com>
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index c5d6277c54..cfcbadc8ea 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -4692,6 +4692,22 @@ bfd_mach_o_read_note (bfd *abfd, bfd_mach_o_load_command *command)
return TRUE;
}
+static bfd_boolean
+bfd_mach_o_read_build_version (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_build_version_command *cmd = &command->command.build_version;
+ struct mach_o_build_version_command_external raw;
+
+ if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->platform = bfd_get_32 (abfd, raw.platform);
+ cmd->minos = bfd_get_32 (abfd, raw.minos);
+ cmd->sdk = bfd_get_32 (abfd, raw.sdk);
+ cmd->ntools = bfd_get_32 (abfd, raw.ntools);
+ return TRUE;
+}
+
static bfd_boolean
bfd_mach_o_read_segment (bfd *abfd,
bfd_mach_o_load_command *command,
@@ -4904,6 +4920,10 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
if (!bfd_mach_o_read_note (abfd, command))
return FALSE;
break;
+ case BFD_MACH_O_LC_BUILD_VERSION:
+ if (!bfd_mach_o_read_build_version (abfd, command))
+ return FALSE;
+ break;
default:
command->len = 0;
_bfd_error_handler (_("%pB: unknown load command %#x"),
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index 805c30e4e2..e4951ec31b 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -113,6 +113,18 @@ bfd_mach_o_segment_command;
#define BFD_MACH_O_PROT_WRITE 0x02
#define BFD_MACH_O_PROT_EXECUTE 0x04
+/* Target platforms. */
+#define BFD_MACH_O_PLATFORM_MACOS 1
+#define BFD_MACH_O_PLATFORM_IOS 2
+#define BFD_MACH_O_PLATFORM_TVOS 3
+#define BFD_MACH_O_PLATFORM_WATCHOS 4
+#define BFD_MACH_O_PLATFORM_BRIDGEOS 5
+
+/* Build tools. */
+#define BFD_MACH_O_TOOL_CLANG 1
+#define BFD_MACH_O_TOOL_SWIFT 2
+#define BFD_MACH_O_TOOL_LD 3
+
/* Expanded internal representation of a relocation entry. */
typedef struct bfd_mach_o_reloc_info
{
@@ -557,6 +569,22 @@ typedef struct bfd_mach_o_note_command
}
bfd_mach_o_note_command;
+typedef struct bfd_mach_o_build_version_tool
+{
+ uint32_t tool;
+ uint32_t version;
+}
+bfd_mach_o_build_version_tool;
+
+typedef struct bfd_mach_o_build_version_command
+{
+ uint32_t platform;
+ uint32_t minos;
+ uint32_t sdk;
+ uint32_t ntools;
+}
+bfd_mach_o_build_version_command;
+
typedef struct bfd_mach_o_load_command
{
/* Next command in the single linked list. */
@@ -591,6 +619,7 @@ typedef struct bfd_mach_o_load_command
bfd_mach_o_main_command main;
bfd_mach_o_source_version_command source_version;
bfd_mach_o_note_command note;
+ bfd_mach_o_build_version_command build_version;
} command;
}
bfd_mach_o_load_command;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 266ce272d9..40e545063f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,9 +1,13 @@
2018-11-06 Roman Bolshakov <***@yadro.com>
Saagar Jha <***@saagarjha.com>
+ PR 23728
* 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.
+ 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
2018-11-03 H.J. Lu <***@intel.com>
diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 4f9bba1d55..fdcfc4de4a 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -212,6 +212,7 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
{ "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
{ "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
{ "note", BFD_MACH_O_LC_NOTE},
+ { "build_version", BFD_MACH_O_LC_BUILD_VERSION},
{ NULL, 0}
};
@@ -232,7 +233,25 @@ static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
{ "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
{ NULL, 0 }
};
-
+
+static const bfd_mach_o_xlat_name bfd_mach_o_platform_name[] =
+{
+ { "macos", BFD_MACH_O_PLATFORM_MACOS},
+ { "ios", BFD_MACH_O_PLATFORM_IOS},
+ { "tvos", BFD_MACH_O_PLATFORM_TVOS},
+ { "watchos", BFD_MACH_O_PLATFORM_WATCHOS},
+ { "bridgeos", BFD_MACH_O_PLATFORM_BRIDGEOS},
+ { NULL, 0 }
+};
+
+static const bfd_mach_o_xlat_name bfd_mach_o_tool_name[] =
+{
+ { "clang", BFD_MACH_O_TOOL_CLANG},
+ { "swift", BFD_MACH_O_TOOL_SWIFT},
+ { "ld", BFD_MACH_O_TOOL_LD},
+ { NULL, 0 }
+};
+
static void
bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
unsigned long val)
@@ -1450,6 +1469,53 @@ printf_version (uint32_t version) {
printf ("%u.%u.%u", maj, min, upd);
}
+static void
+dump_build_version (bfd *abfd, bfd_mach_o_load_command *cmd)
+{
+ const char *platform_name;
+ size_t tools_len, tools_offset;
+ bfd_mach_o_build_version_tool *tools, *tool;
+ bfd_mach_o_build_version_command *ver = &cmd->command.build_version;
+ uint32_t i;
+
+ platform_name = bfd_mach_o_get_name_or_null
+ (bfd_mach_o_platform_name, ver->platform);
+ if (platform_name == NULL)
+ printf (" platform: 0x%08x\n", ver->platform);
+ else
+ printf (" platform: %s\n", platform_name);
+ printf (" os: ");
+ printf_version (ver->minos);
+ printf ("\n sdk: ");
+ printf_version (ver->sdk);
+ printf ("\n ntools: %u\n", ver->ntools);
+
+ tools_len = sizeof (bfd_mach_o_build_version_tool) * ver->ntools;
+ tools_offset = cmd->offset + cmd->len - tools_len;
+
+ tools = xmalloc (tools_len);
+ if (bfd_seek (abfd, tools_offset, SEEK_SET) != 0
+ || bfd_bread (tools, tools_len, abfd) != tools_len) {
+ non_fatal (_("cannot read build tools"));
+ free (tools);
+ return;
+ }
+ for (i = 0, tool = tools; i < ver->ntools; i++, tool++)
+ {
+ const char * tool_name;
+ tool_name = bfd_mach_o_get_name_or_null
+ (bfd_mach_o_tool_name, tool->tool);
+ if (tool_name == NULL)
+ printf (" tool: 0x%08x\n", tool->tool);
+ else
+ printf (" tool: %s\n", tool_name);
+ printf (" version: ");
+ printf_version (tool->version);
+ printf ("\n");
+ }
+ free (tools);
+}
+
static void
dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
unsigned int idx, bfd_boolean verbose)
@@ -1673,6 +1739,9 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
printf ("\n");
break;
}
+ case BFD_MACH_O_LC_BUILD_VERSION:
+ dump_build_version (abfd, cmd);
+ break;
default:
break;
}
diff --git a/include/ChangeLog b/include/ChangeLog
index f86bbbf08c..bc86439c1c 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -4,8 +4,10 @@
* 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
+ (BFD_MACH_O_LC_BUILD_VERSION): Define
2018-11-06 Sudakshina Das <***@arm.com>
diff --git a/include/mach-o/external.h b/include/mach-o/external.h
index 7889b57794..22891e5be2 100644
--- a/include/mach-o/external.h
+++ b/include/mach-o/external.h
@@ -352,6 +352,14 @@ struct mach_o_note_command_external
unsigned char size[8]; /* Length of the note. */
};
+struct mach_o_build_version_command_external
+{
+ unsigned char platform[4]; /* Target platform. */
+ unsigned char minos[4]; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+ unsigned char sdk[4]; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+ unsigned char ntools[4]; /* Number of tool entries following this. */
+};
+
/* The LD_DATA_IN_CODE command use a linkedit_data_command that points to
a table of entries. */
diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h
index a3d20e04dc..e735986bc5 100644
--- a/include/mach-o/loader.h
+++ b/include/mach-o/loader.h
@@ -188,6 +188,7 @@ typedef enum bfd_mach_o_load_command_type
BFD_MACH_O_LC_VERSION_MIN_TVOS = 0x2f, /* Minimal tvOS version. */
BFD_MACH_O_LC_VERSION_MIN_WATCHOS = 0x30, /* Minimal watchOS version. */
BFD_MACH_O_LC_NOTE = 0x31, /* Region of arbitrary data. */
+ BFD_MACH_O_LC_BUILD_VERSION = 0x32, /* Generic build version. */
}
bfd_mach_o_load_command_type;
--
2.19.1