Discussion:
[PATCH v2 0/6] Fixes for new mach-o load commands
Roman Bolshakov
2018-11-06 21:12:48 UTC
Permalink
Hello dear maintainers,

Apple has added a set of new load commands that weren't handled by bfd.
Some of them are rarely processed by binutils, like binaries with
LC_VERSION_MIN_TVOS.

But inability to handle LC_BUILD_VERSION resulted in a few bug reports,
and rendered binutils/gdb to be unusable with Mojave binaries:
binutils/23728, gdb/23742, binutils/23746

The patch series implements processing of the new commands in bfd and
dump routines in objectdump.

I'm leaving the original cover message as is because couple hours after
v1 patchset, another commit came into master brach that fixes the
aforementioned errors on macOS Mojave by skipping LC_BUILD_VERSION
command.

The patchset should still be helpful as it does parse LC_BUILD_VERSION
and a few other load commands.

--
Best regards,
Roman

Changes in v2:
* Reformatted printf_version to follow GNU style
* Rebased to master

Roman Bolshakov (6):
mach-o: Don't split version into a few fields
mach-o: Print sdk field in LC_VERSION_MIN_*
mach-o: Print LC_VERSION_MIN_WATCHOS
mach-o: Handle LC_VERSION_MIN_TVOS
mach-o: Handle LC_NOTE
mach-o: Handle LC_BUILD_VERSION command

bfd/ChangeLog | 19 +++++++
bfd/mach-o.c | 49 +++++++++++++++---
bfd/mach-o.h | 44 ++++++++++++++--
binutils/ChangeLog | 11 ++++
binutils/od-macho.c | 104 +++++++++++++++++++++++++++++++++++++-
include/ChangeLog | 10 ++++
include/mach-o/external.h | 17 ++++++-
include/mach-o/loader.h | 2 +
8 files changed, 242 insertions(+), 14 deletions(-)
--
2.19.1
Roman Bolshakov
2018-11-06 21:12:50 UTC
Permalink
X.Y.Z tuple is used for minos version and sdk version fields in a number of
load commands:
LC_VERSION_MIN_MACOSX
LC_VERSION_MIN_IOS
LC_VERSION_MIN_WATCHOS
LC_VERSION_MIN_TVOS
LC_BUILD_VERSION

We could use a macro to avoid code duplication for reading and setting
the X/Y/Z fields in all the load commands. But since there're no users
of the fields except od, we can just add a function that properly prints
all version components out of 4-byte unsigned integer and remove the
version subfields until they're really needed.

This also fixes incorrect length of the first version subfield as it
should be two bytes long instead of one:
X.Y.Z is encoded in nibbles xxxx.yy.zz

Signed-off-by: Roman Bolshakov <***@yadro.com>
Reviewed-by: Tristan Gingold <***@free.fr>
---
bfd/ChangeLog | 7 +++++++
bfd/mach-o.c | 6 +-----
bfd/mach-o.h | 6 ++----
binutils/ChangeLog | 5 +++++
binutils/od-macho.c | 14 +++++++++++++-
5 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 155251d3d4..d90e4576f1 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-06 Roman Bolshakov <***@yadro.com>
+
+ * mach-o.h (bfd_mach_o_version_min_command): Don't split version into
+ a few fields.
+ * mach-o.c (bfd_mach_o_read_version_min): Don't split version into a
+ few fields.
+
2018-11-06 Romain Margheriti <***@gmail.com>

PR 23742
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 1d0ade3a02..e3d5dbe0d5 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -4598,15 +4598,11 @@ bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
{
bfd_mach_o_version_min_command *cmd = &command->command.version_min;
struct mach_o_version_min_command_external raw;
- unsigned int ver;

if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;

- ver = bfd_get_32 (abfd, raw.version);
- cmd->rel = ver >> 16;
- cmd->maj = ver >> 8;
- cmd->min = ver;
+ cmd->version = bfd_get_32 (abfd, raw.version);
cmd->reserved = bfd_get_32 (abfd, raw.reserved);
return TRUE;
}
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index d80d43991e..4fd229f352 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -519,10 +519,8 @@ bfd_mach_o_dyld_info_command;

typedef struct bfd_mach_o_version_min_command
{
- unsigned char rel;
- unsigned char maj;
- unsigned char min;
- unsigned int reserved;
+ uint32_t version;
+ uint32_t reserved;
}
bfd_mach_o_version_min_command;

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index f484f92294..089d7a61b6 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-06 Roman Bolshakov <***@yadro.com>
+
+ * od-macho.c (printf_version): New.
+ (dump_load_command): Use it to print version.
+
2018-11-06 H.J. Lu <***@intel.com>

* doc/binutils.texi: Document --enable-x86-feature and
diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 8153adae92..9b10f2d654 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -1438,6 +1438,16 @@ dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
free (buf);
}

+static void
+printf_version (uint32_t version)
+{
+ uint32_t maj, min, upd;
+ maj = (version >> 16) & 0xffff;
+ min = (version >> 8) & 0xff;
+ upd = version & 0xff;
+ printf ("%u.%u.%u", maj, min, upd);
+}
+
static void
dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
unsigned int idx, bfd_boolean verbose)
@@ -1585,7 +1595,9 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
{
bfd_mach_o_version_min_command *ver = &cmd->command.version_min;

- printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
+ printf (" os: ");
+ printf_version (ver->version);
+ printf ("\n");
}
break;
case BFD_MACH_O_LC_SOURCE_VERSION:
--
2.19.1
Roman Bolshakov
2018-11-06 21:12:52 UTC
Permalink
sdk field was read by bfd but never printed.
Rename it to sdk and dump it in od.

Signed-off-by: Roman Bolshakov <***@yadro.com>
Signed-off-by: Saagar Jha <***@saagarjha.com>
Reviewed-by: Tristan Gingold <***@free.fr>
---
bfd/ChangeLog | 5 +++--
bfd/mach-o.c | 2 +-
bfd/mach-o.h | 2 +-
binutils/ChangeLog | 3 ++-
binutils/od-macho.c | 2 ++
include/ChangeLog | 6 ++++++
include/mach-o/external.h | 2 +-
7 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d90e4576f1..5ec55af648 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,9 +1,10 @@
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.
+ a few fields. Rename reserved to sdk.
* mach-o.c (bfd_mach_o_read_version_min): Don't split version into a
- few fields.
+ few fields. Rename reserved to sdk.

2018-11-06 Romain Margheriti <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index e3d5dbe0d5..78de9f4637 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -4603,7 +4603,7 @@ bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
return FALSE;

cmd->version = bfd_get_32 (abfd, raw.version);
- cmd->reserved = bfd_get_32 (abfd, raw.reserved);
+ cmd->sdk = bfd_get_32 (abfd, raw.sdk);
return TRUE;
}

diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index 4fd229f352..28ccb09c69 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -520,7 +520,7 @@ bfd_mach_o_dyld_info_command;
typedef struct bfd_mach_o_version_min_command
{
uint32_t version;
- uint32_t reserved;
+ uint32_t sdk;
}
bfd_mach_o_version_min_command;

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 089d7a61b6..270ee4d693 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,7 +1,8 @@
2018-11-06 Roman Bolshakov <***@yadro.com>
+ Saagar Jha <***@saagarjha.com>

* od-macho.c (printf_version): New.
- (dump_load_command): Use it to print version.
+ (dump_load_command): Use it to print version. Print sdk version.

2018-11-06 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 9b10f2d654..d394c75774 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -1597,6 +1597,8 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,

printf (" os: ");
printf_version (ver->version);
+ printf ("\n sdk: ");
+ printf_version (ver->sdk);
printf ("\n");
}
break;
diff --git a/include/ChangeLog b/include/ChangeLog
index 3bcf18047b..d9548a4747 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-06 Roman Bolshakov <***@yadro.com>
+ Saagar Jha <***@saagarjha.com>
+
+ * mach-o/external.h (mach_o_version_min_command_external): Rename
+ reserved to sdk.
+
2018-11-06 Romain Margheriti <***@gmail.com>

PR 23742
diff --git a/include/mach-o/external.h b/include/mach-o/external.h
index 2609bad982..aa7260a58a 100644
--- a/include/mach-o/external.h
+++ b/include/mach-o/external.h
@@ -308,7 +308,7 @@ struct mach_o_twolevel_hints_command_external
struct mach_o_version_min_command_external
{
unsigned char version[4];
- unsigned char reserved[4];
+ unsigned char sdk[4];
};

struct mach_o_encryption_info_command_external
--
2.19.1
Roman Bolshakov
2018-11-06 21:12:54 UTC
Permalink
Content of LC_VERSION_MIN_WATCHOS gets parsed by bfd but objdump doesn't
print it.

Signed-off-by: Roman Bolshakov <***@yadro.com>
Reviewed-by: Tristan Gingold <***@free.fr>
---
binutils/ChangeLog | 3 ++-
binutils/od-macho.c | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 270ee4d693..ce07ba8d58 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -2,7 +2,8 @@
Saagar Jha <***@saagarjha.com>

* od-macho.c (printf_version): New.
- (dump_load_command): Use it to print version. Print sdk version.
+ (dump_load_command): Use it to print version. Print sdk version. Print
+ version info for watchOS.

2018-11-06 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index d394c75774..dc64342c65 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -209,6 +209,7 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
{ "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
{ "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
{ "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
+ { "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
{ NULL, 0}
};

@@ -1592,6 +1593,7 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
break;
case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
+ case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
{
bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
--
2.19.1
Roman Bolshakov
2018-11-06 21:12:56 UTC
Permalink
The load command was introduced shortly after LC_VERSION_MIN_WATCHOS. It
has exactly the same format as the other load commands from the same
family.

Signed-off-by: Roman Bolshakov <***@yadro.com>
Reviewed-by: Tristan Gingold <***@free.fr>
---
bfd/ChangeLog | 1 +
bfd/mach-o.c | 1 +
binutils/ChangeLog | 2 +-
binutils/od-macho.c | 2 ++
include/ChangeLog | 1 +
include/mach-o/loader.h | 1 +
6 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5ec55af648..87047fb0eb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -5,6 +5,7 @@
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.

2018-11-06 Romain Margheriti <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 78de9f4637..d6de267397 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -4873,6 +4873,7 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
+ case BFD_MACH_O_LC_VERSION_MIN_TVOS:
if (!bfd_mach_o_read_version_min (abfd, command))
return FALSE;
break;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index ce07ba8d58..6b05f37eae 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -3,7 +3,7 @@

* od-macho.c (printf_version): New.
(dump_load_command): Use it to print version. Print sdk version. Print
- version info for watchOS.
+ version info for watchOS and tvOS.

2018-11-06 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index dc64342c65..9f2d51a2da 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -209,6 +209,7 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
{ "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
{ "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
{ "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
+ { "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
{ "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
{ NULL, 0}
};
@@ -1594,6 +1595,7 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
+ case BFD_MACH_O_LC_VERSION_MIN_TVOS:
{
bfd_mach_o_version_min_command *ver = &cmd->command.version_min;

diff --git a/include/ChangeLog b/include/ChangeLog
index d9548a4747..a55fab8f00 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -3,6 +3,7 @@

* mach-o/external.h (mach_o_version_min_command_external): Rename
reserved to sdk.
+ * mach-o/loader.h (BFD_MACH_O_LC_VERSION_MIN_TVOS): Define

2018-11-06 Romain Margheriti <***@gmail.com>

diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h
index 9abc51c35d..acc31f0499 100644
--- a/include/mach-o/loader.h
+++ b/include/mach-o/loader.h
@@ -185,6 +185,7 @@ typedef enum bfd_mach_o_load_command_type
BFD_MACH_O_LC_ENCRYPTION_INFO_64 = 0x2c, /* Encrypted 64 bit seg info. */
BFD_MACH_O_LC_LINKER_OPTIONS = 0x2d, /* Linker options. */
BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT = 0x2e, /* Optimization hints. */
+ 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_BUILD_VERSION = 0x32 /* Records linker, SDK, OS, and tools version used. */
}
--
2.19.1
Roman Bolshakov
2018-11-06 21:13:00 UTC
Permalink
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>
Reviewed-by: Tristan Gingold <***@free.fr>
Cc: Tom Tromey <***@tromey.com>
Cc: Nick Clifton <***@redhat.com>
---
bfd/ChangeLog | 14 ++++++--
bfd/mach-o.c | 21 +++++++++++-
bfd/mach-o.h | 29 ++++++++++++++++
binutils/ChangeLog | 6 +++-
binutils/od-macho.c | 71 ++++++++++++++++++++++++++++++++++++++-
include/ChangeLog | 1 +
include/mach-o/external.h | 8 +++++
7 files changed, 144 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0e3d3457ee..4c81d3838c 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-06 Romain Margheriti <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 9d01566240..024f29ed6c 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,8 +4920,11 @@ 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_LINKER_OPTIONS:
case BFD_MACH_O_LC_BUILD_VERSION:
+ if (!bfd_mach_o_read_build_version (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LINKER_OPTIONS:
break;
default:
command->len = 0;
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 3b17ec76db..afa9fc6015 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-06 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index f56c32ff67..33488b4eca 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)
@@ -1451,6 +1470,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)
@@ -1674,6 +1740,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 210451fb80..b0878c6c67 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -4,6 +4,7 @@
* 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

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. */
--
2.19.1
Roman Bolshakov
2018-11-06 21:12:58 UTC
Permalink
This is a new command to describe a region of any data. Initially, it's
used in in MH_CORE files.

Signed-off-by: Roman Bolshakov <***@yadro.com>
Signed-off-by: Saagar Jha <***@saagarjha.com>
Reviewed-by: Tristan Gingold <***@free.fr>
---
bfd/ChangeLog | 4 +++-
bfd/mach-o.c | 19 +++++++++++++++++++
bfd/mach-o.h | 9 +++++++++
binutils/ChangeLog | 2 +-
binutils/od-macho.c | 13 +++++++++++++
include/ChangeLog | 4 +++-
include/mach-o/external.h | 7 +++++++
include/mach-o/loader.h | 1 +
8 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 87047fb0eb..0e3d3457ee 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -3,9 +3,11 @@

* mach-o.h (bfd_mach_o_version_min_command): Don't split version into
a few fields. Rename reserved to sdk.
+ (struct bfd_mach_o_note_command): New.
* 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.
+ (bfd_mach_o_read_command): Handle LC_VERSION_MIN_TVOS, LC_NOTE.
+ (bfd_mach_o_read_note): New.

2018-11-06 Romain Margheriti <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index d6de267397..9d01566240 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -4677,6 +4677,21 @@ bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command)
return TRUE;
}

+static bfd_boolean
+bfd_mach_o_read_note (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_note_command *cmd = &command->command.note;
+ struct mach_o_note_command_external raw;
+
+ if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ memcpy (cmd->data_owner, raw.data_owner, 16);
+ cmd->offset = bfd_get_64 (abfd, raw.offset);
+ cmd->size = bfd_get_64 (abfd, raw.size);
+ return TRUE;
+}
+
static bfd_boolean
bfd_mach_o_read_segment (bfd *abfd,
bfd_mach_o_load_command *command,
@@ -4885,6 +4900,10 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
if (!bfd_mach_o_read_source_version (abfd, command))
return FALSE;
break;
+ case BFD_MACH_O_LC_NOTE:
+ if (!bfd_mach_o_read_note (abfd, command))
+ return FALSE;
+ break;
case BFD_MACH_O_LC_LINKER_OPTIONS:
case BFD_MACH_O_LC_BUILD_VERSION:
break;
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index 28ccb09c69..805c30e4e2 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -549,6 +549,14 @@ typedef struct bfd_mach_o_source_version_command
}
bfd_mach_o_source_version_command;

+typedef struct bfd_mach_o_note_command
+{
+ char data_owner[16];
+ bfd_uint64_t offset;
+ bfd_uint64_t size;
+}
+bfd_mach_o_note_command;
+
typedef struct bfd_mach_o_load_command
{
/* Next command in the single linked list. */
@@ -582,6 +590,7 @@ typedef struct bfd_mach_o_load_command
bfd_mach_o_fvmlib_command fvmlib;
bfd_mach_o_main_command main;
bfd_mach_o_source_version_command source_version;
+ bfd_mach_o_note_command note;
} command;
}
bfd_mach_o_load_command;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6b05f37eae..3b17ec76db 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -3,7 +3,7 @@

* od-macho.c (printf_version): New.
(dump_load_command): Use it to print version. Print sdk version. Print
- version info for watchOS and tvOS.
+ version info for watchOS and tvOS. Print LC_NOTE.

2018-11-06 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 9f2d51a2da..f56c32ff67 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -211,6 +211,7 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
{ "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
{ "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},
{ NULL, 0}
};

@@ -1661,6 +1662,18 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
printf ("\n");
break;
}
+ case BFD_MACH_O_LC_NOTE:
+ {
+ bfd_mach_o_note_command *note = &cmd->command.note;
+ printf (" data owner: %.16s\n", note->data_owner);
+ printf (" offset: ");
+ printf_uint64 (note->offset);
+ printf ("\n"
+ " size: ");
+ printf_uint64 (note->size);
+ printf ("\n");
+ break;
+ }
default:
break;
}
diff --git a/include/ChangeLog b/include/ChangeLog
index a55fab8f00..210451fb80 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,9 +1,11 @@
2018-11-06 Roman Bolshakov <***@yadro.com>
Saagar Jha <***@saagarjha.com>

- * mach-o/external.h (mach_o_version_min_command_external): Rename
+ * mach-o/external.h (mach_o_nversion_min_command_external): Rename
reserved to sdk.
+ (mach_o_note_command_external): New
* mach-o/loader.h (BFD_MACH_O_LC_VERSION_MIN_TVOS): Define
+ (BFD_MACH_O_LC_NOTE): Define

2018-11-06 Romain Margheriti <***@gmail.com>

diff --git a/include/mach-o/external.h b/include/mach-o/external.h
index aa7260a58a..7889b57794 100644
--- a/include/mach-o/external.h
+++ b/include/mach-o/external.h
@@ -345,6 +345,13 @@ struct mach_o_source_version_command_external
and 24 bits for A. */
};

+struct mach_o_note_command_external
+{
+ unsigned char data_owner[16]; /* Owner name for this note. */
+ unsigned char offset[8]; /* File offset of the note. */
+ unsigned char size[8]; /* Length of the note. */
+};
+
/* 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 acc31f0499..5cbc411b36 100644
--- a/include/mach-o/loader.h
+++ b/include/mach-o/loader.h
@@ -187,6 +187,7 @@ typedef enum bfd_mach_o_load_command_type
BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT = 0x2e, /* Optimization hints. */
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 /* Records linker, SDK, OS, and tools version used. */
}
bfd_mach_o_load_command_type;
--
2.19.1
Continue reading on narkive:
Loading...