diff options
author | Nick Clifton <nickc@redhat.com> | 2018-06-20 10:43:00 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-06-20 10:43:00 +0100 |
commit | c6643fcc058d6b4aebca75818fbbb705837a9fa3 (patch) | |
tree | 0e99ca41b74b546834d8b2151f9b855200146f68 /bfd | |
parent | ebb1332297da904a4adab0d3696a5512604f5edd (diff) | |
download | gdb-c6643fcc058d6b4aebca75818fbbb705837a9fa3.zip gdb-c6643fcc058d6b4aebca75818fbbb705837a9fa3.tar.gz gdb-c6643fcc058d6b4aebca75818fbbb705837a9fa3.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/mach-o-target.c | 2 | ||||
-rw-r--r-- | bfd/mach-o.c | 140 | ||||
-rw-r--r-- | bfd/mach-o.h | 1 |
4 files changed, 153 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d12dc99..d0f6668 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2018-06-20 Nick Clifton <nickc@redhat.com> + + 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 <macro@mips.com> PR ld/22966 diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index 9f3b487..54d9641 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 cfae354..d58e62d 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 _("<unknown>"); + } +} + +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, _("<unknown mask flags>")); 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, _(" (<unknown>)")); + + 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 c09e274..d80d439 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, |