Discussion:
[PATCH 0/6] Fixes for new mach-o load commands
Roman Bolshakov
2018-11-06 14:06:32 UTC
Permalink
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.

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 | 48 +++++++++++++++---
bfd/mach-o.h | 44 ++++++++++++++--
binutils/ChangeLog | 11 ++++
binutils/od-macho.c | 103 +++++++++++++++++++++++++++++++++++++-
include/ChangeLog | 11 ++++
include/mach-o/external.h | 17 ++++++-
include/mach-o/loader.h | 5 +-
8 files changed, 244 insertions(+), 14 deletions(-)
--
2.19.1
Roman Bolshakov
2018-11-06 14:06:35 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
---
bfd/ChangeLog | 7 +++++++
bfd/mach-o.c | 6 +-----
bfd/mach-o.h | 6 ++----
binutils/ChangeLog | 5 +++++
binutils/od-macho.c | 13 ++++++++++++-
5 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d8b50f5381..4015c26cbf 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-02 Alan Modra <***@gmail.com>

PR 23850
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 1b461f5988..7e4aa7d068 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 bdbee0fff6..d8970aae88 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-03 H.J. Lu <***@intel.com>

* elfedit.c (update_elf_header): Move EI_MAG? check to ...
diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 8153adae92..98551118c0 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -1438,6 +1438,15 @@ 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 +1594,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 14:06:37 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>
Cc: 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 4015c26cbf..7dcdb45d3f 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-02 Alan Modra <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 7e4aa7d068..45d774f14e 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 d8970aae88..2e75d67dcd 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-03 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 98551118c0..c8972eaf7b 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -1596,6 +1596,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 124efb1775..b1115e973f 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 Sudakshina Das <***@arm.com>

* opcode/arm.h (ARM_ARCH_V8_5A): Move ARM_EXT2_PREDRES and
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 14:06:38 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>
Cc: 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 2e75d67dcd..d57efdd14f 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-03 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index c8972eaf7b..dec6228f48 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}
};

@@ -1591,6 +1592,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 14:06:39 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>
Cc: 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 7dcdb45d3f..b1df3af4ba 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-02 Alan Modra <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 45d774f14e..57ca8fb169 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 d57efdd14f..3db9bcdad8 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-03 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index dec6228f48..43a89bd68d 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}
};
@@ -1593,6 +1594,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 b1115e973f..25a5826664 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 Sudakshina Das <***@arm.com>

diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h
index c075a8e023..19c5e91d64 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_load_command_type;
--
2.19.1
Roman Bolshakov
2018-11-06 14:06:40 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>
Cc: 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 | 3 ++-
8 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b1df3af4ba..1f017f6fcd 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-02 Alan Modra <***@gmail.com>

diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 57ca8fb169..c5d6277c54 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;
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 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 3db9bcdad8..266ce272d9 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-03 H.J. Lu <***@intel.com>

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index 43a89bd68d..4f9bba1d55 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}
};

@@ -1660,6 +1661,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 25a5826664..f86bbbf08c 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 Sudakshina Das <***@arm.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 19c5e91d64..a3d20e04dc 100644
--- a/include/mach-o/loader.h
+++ b/include/mach-o/loader.h
@@ -186,7 +186,8 @@ typedef enum bfd_mach_o_load_command_type
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_VERSION_MIN_WATCHOS = 0x30, /* Minimal watchOS version. */
+ BFD_MACH_O_LC_NOTE = 0x31, /* Region of arbitrary data. */
}
bfd_mach_o_load_command_type;
--
2.19.1
Roman Bolshakov
2018-11-06 14:06:41 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>
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
t***@free.fr
2018-11-06 14:25:13 UTC
Permalink
Hello,
Post by Roman Bolshakov
+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);
+}
this doesn't follow the GNU code style. The '{' must be on a new line.

I haven't upgraded to latest Darwin, so I haven't checked the code.

Thanks,
Tristan.
Nick Clifton
2018-11-07 15:23:29 UTC
Permalink
Hi Roman,
Post by Roman Bolshakov
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,
binutils/23728, gdb/23742, binutils/23746
The patch series implements processing of the new commands in bfd and
dump routines in objectdump.
The patch series is approved and has been applied. I also made some
minor formatting tidy ups.

In the future, please could you provide the ChangeLog entries as plain
text, rather than context diffs, as they almost never apply cleanly.

Cheers
Nick
Roman Bolshakov
2018-11-08 17:02:01 UTC
Permalink
Post by Nick Clifton
The patch series is approved and has been applied. I also made some
minor formatting tidy ups.
In the future, please could you provide the ChangeLog entries as plain
text, rather than context diffs, as they almost never apply cleanly.
Thank you Nick, I have also had trouble rebasing. Will provide changelog
inside cover letter next time.

Best regards,
Roman

Loading...