From c6643fcc058d6b4aebca75818fbbb705837a9fa3 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 20 Jun 2018 10:43:00 +0100 Subject: [PATCH] Stop objcopy from corrupting mach-o files. PR 23299 * mach-o.c (cputype): New function. (cpusubtype): New function. (bfd_mach_o_bfd_print_private_data): New function. Dispalys the values in the MACH-O file header. (bfd_mach_o_bfd_copy_private_header_data): Copy the cputype and cpusubtype fields from the input bfd's mach-o header to the output bfd. * mach-o-target.c (bfd_mach_o_bfd_print_private_bfd_data): Redefine to bfd_mach_o_bfd_print_private_data. * mach-o.h (bfd_mach_o_bfd_print_private_bfd_data): Prototype. --- bfd/ChangeLog | 14 +++++ bfd/mach-o-target.c | 2 +- bfd/mach-o.c | 140 +++++++++++++++++++++++++++++++++++++++++++- bfd/mach-o.h | 1 + 4 files changed, 153 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d12dc99425..d0f6668dcd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2018-06-20 Nick Clifton + + PR 23299 + * mach-o.c (cputype): New function. + (cpusubtype): New function. + (bfd_mach_o_bfd_print_private_data): New function. Dispalys the + values in the MACH-O file header. + (bfd_mach_o_bfd_copy_private_header_data): Copy the cputype and + cpusubtype fields from the input bfd's mach-o header to the output + bfd. + * mach-o-target.c (bfd_mach_o_bfd_print_private_bfd_data): + Redefine to bfd_mach_o_bfd_print_private_data. + * mach-o.h (bfd_mach_o_bfd_print_private_bfd_data): Prototype. + 2018-06-19 Maciej W. Rozycki PR ld/22966 diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index 9f3b487b8d..54d9641c02 100644 --- a/bfd/mach-o-target.c +++ b/bfd/mach-o-target.c @@ -26,7 +26,7 @@ #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data +#define bfd_mach_o_bfd_print_private_bfd_data bfd_mach_o_bfd_print_private_bfd_data #define bfd_mach_o_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false #define bfd_mach_o_bfd_is_local_label_name bfd_generic_is_local_label_name #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno diff --git a/bfd/mach-o.c b/bfd/mach-o.c index cfae354704..d58e62d94e 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -592,6 +592,124 @@ bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd, asection *isection, return TRUE; } +static const char * +cputype (unsigned long value) +{ + switch (value) + { + case BFD_MACH_O_CPU_TYPE_VAX: return "VAX"; + case BFD_MACH_O_CPU_TYPE_MC680x0: return "MC68k"; + case BFD_MACH_O_CPU_TYPE_I386: return "I386"; + case BFD_MACH_O_CPU_TYPE_MIPS: return "MIPS"; + case BFD_MACH_O_CPU_TYPE_MC98000: return "MC98k"; + case BFD_MACH_O_CPU_TYPE_HPPA: return "HPPA"; + case BFD_MACH_O_CPU_TYPE_ARM: return "ARM"; + case BFD_MACH_O_CPU_TYPE_MC88000: return "MC88K"; + case BFD_MACH_O_CPU_TYPE_SPARC: return "SPARC"; + case BFD_MACH_O_CPU_TYPE_I860: return "I860"; + case BFD_MACH_O_CPU_TYPE_ALPHA: return "ALPHA"; + case BFD_MACH_O_CPU_TYPE_POWERPC: return "PPC"; + case BFD_MACH_O_CPU_TYPE_POWERPC_64: return "PPC64"; + case BFD_MACH_O_CPU_TYPE_X86_64: return "X86_64"; + case BFD_MACH_O_CPU_TYPE_ARM64: return "ARM64"; + default: return _(""); + } +} + +static const char * +cpusubtype (unsigned long cputype, unsigned long cpusubtype) +{ + static char buffer[128]; + + buffer[0] = 0; + switch (cpusubtype & BFD_MACH_O_CPU_SUBTYPE_MASK) + { + case 0: + break; + case BFD_MACH_O_CPU_SUBTYPE_LIB64: + sprintf (buffer, " (LIB64)"); break; + default: + sprintf (buffer, _("")); break; + } + + cpusubtype &= ~ BFD_MACH_O_CPU_SUBTYPE_MASK; + + switch (cputype) + { + case BFD_MACH_O_CPU_TYPE_X86_64: + case BFD_MACH_O_CPU_TYPE_I386: + switch (cpusubtype) + { + case BFD_MACH_O_CPU_SUBTYPE_X86_ALL: + return strcat (buffer, " (X86_ALL)"); + default: + break; + } + break; + + case BFD_MACH_O_CPU_TYPE_ARM: + switch (cpusubtype) + { + case BFD_MACH_O_CPU_SUBTYPE_ARM_ALL: + return strcat (buffer, " (ARM_ALL)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM_V4T: + return strcat (buffer, " (ARM_V4T)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM_V6: + return strcat (buffer, " (ARM_V6)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM_V5TEJ: + return strcat (buffer, " (ARM_V5TEJ)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM_XSCALE: + return strcat (buffer, " (ARM_XSCALE)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM_V7: + return strcat (buffer, " (ARM_V7)"); + default: + break; + } + break; + + case BFD_MACH_O_CPU_TYPE_ARM64: + switch (cpusubtype) + { + case BFD_MACH_O_CPU_SUBTYPE_ARM64_ALL: + return strcat (buffer, " (ARM64_ALL)"); + case BFD_MACH_O_CPU_SUBTYPE_ARM64_V8: + return strcat (buffer, " (ARM64_V8)"); + default: + break; + } + break; + + default: + break; + } + + if (cpusubtype != 0) + return strcat (buffer, _(" ()")); + + return buffer; +} + +bfd_boolean +bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void *ptr) +{ + FILE * file = (FILE *) ptr; + bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + + fprintf (file, _(" MACH-O header:\n")); + fprintf (file, _(" magic: %#lx\n"), (long) mdata->header.magic); + fprintf (file, _(" cputype: %#lx (%s)\n"), (long) mdata->header.cputype, + cputype (mdata->header.cputype)); + fprintf (file, _(" cpusubtype: %#lx%s\n"), (long) mdata->header.cpusubtype, + cpusubtype (mdata->header.cputype, mdata->header.cpusubtype)); + fprintf (file, _(" filetype: %#lx\n"), (long) mdata->header.filetype); + fprintf (file, _(" ncmds: %#lx\n"), (long) mdata->header.ncmds); + fprintf (file, _(" sizeocmds: %#lx\n"), (long) mdata->header.sizeofcmds); + fprintf (file, _(" flags: %#lx\n"), (long) mdata->header.flags); + fprintf (file, _(" version: %x\n"), mdata->header.version); + + return TRUE; +} + /* Copy any private info we understand from the input bfd to the output bfd. */ @@ -615,6 +733,21 @@ bfd_mach_o_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd) /* Copy header flags. */ omdata->header.flags = imdata->header.flags; + /* PR 23299. Copy the cputype. */ + if (imdata->header.cputype != omdata->header.cputype) + { + if (omdata->header.cputype == 0) + omdata->header.cputype = imdata->header.cputype; + else if (imdata->header.cputype != 0) + /* Urg - what has happened ? */ + _bfd_error_handler (_("incompatible cputypes in mach-o files: %ld vs %ld"), + (long) imdata->header.cputype, + (long) omdata->header.cputype); + } + + /* Copy the cpusubtype. */ + omdata->header.cpusubtype = imdata->header.cpusubtype; + /* Copy commands. */ for (icmd = imdata->first_command; icmd != NULL; icmd = icmd->next) { @@ -1295,7 +1428,7 @@ bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, void bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel, - unsigned char *fields) + unsigned char *fields) { unsigned char info = fields[3]; @@ -1611,7 +1744,7 @@ bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels, static void bfd_mach_o_swap_out_non_scattered_reloc (bfd *abfd, unsigned char *fields, - bfd_mach_o_reloc_info *rel) + bfd_mach_o_reloc_info *rel) { unsigned char info = 0; @@ -5830,7 +5963,8 @@ bfd_mach_o_close_and_cleanup (bfd *abfd) return _bfd_generic_close_and_cleanup (abfd); } -bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd) +bfd_boolean +bfd_mach_o_free_cached_info (bfd *abfd) { bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); asection *asect; diff --git a/bfd/mach-o.h b/bfd/mach-o.h index c09e274f0c..d80d43991e 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -659,6 +659,7 @@ bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *, asection *, bfd *, asection *); bfd_boolean bfd_mach_o_bfd_copy_private_header_data (bfd *, bfd *); bfd_boolean bfd_mach_o_bfd_set_private_flags (bfd *, flagword); +bfd_boolean bfd_mach_o_bfd_print_private_bfd_data (bfd *, void *); long bfd_mach_o_get_symtab_upper_bound (bfd *); long bfd_mach_o_canonicalize_symtab (bfd *, asymbol **); long bfd_mach_o_get_synthetic_symtab (bfd *, long, asymbol **, long, -- 2.34.1