From ab76eeafa578ca7e301e3aa014e4ed643e32ec2e Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Mon, 19 Dec 2011 15:42:37 +0000 Subject: [PATCH] bfd: * mach-o-i386.c (bfd_mach_o_section_type_valid_for_tgt): Define NULL. * mach-o-target.c (bfd_mach_o_backend_data): Initialize bfd_mach_o_section_type_valid_for_tgt * mach-o-x86-64.c (bfd_mach_o_section_type_valid_for_x86_64): New. (bfd_mach_o_section_type_valid_for_tgt): Set to bfd_mach_o_section_type_valid_for_x86_64. * mach-o.c (bfd_mach_o_section_type_name): Reorder and eliminate dup. (bfd_mach_o_section_attribute_name): Reorder. (bfd_mach_o_get_section_type_from_name): If the target has defined a validator for section types, then use it. * mach-o.h (bfd_mach_o_get_section_type_from_name): Alter declaration to include the bfd. gas: * config/obj-macho.c (obj_mach_o_section): Account for target-dependent section types. Improve error handling when wrong section types/attributes are specified. gas/testsuite: * gas/mach-o/err-sections-1.s: New. * gas/mach-o/err-sections-2.s: New. * gas/mach-o/sections-3.d: New. * gas/mach-o/sections-3.s: New. --- bfd/ChangeLog | 15 +++++++++ bfd/mach-o-i386.c | 1 + bfd/mach-o-target.c | 3 +- bfd/mach-o-x86-64.c | 11 ++++++ bfd/mach-o.c | 31 +++++++++++------ bfd/mach-o.h | 3 +- gas/ChangeLog | 6 ++++ gas/config/obj-macho.c | 41 ++++++++++++++++------- gas/testsuite/ChangeLog | 7 ++++ gas/testsuite/gas/mach-o/err-sections-1.s | 9 +++++ gas/testsuite/gas/mach-o/err-sections-2.s | 9 +++++ gas/testsuite/gas/mach-o/sections-3.d | 19 +++++++++++ gas/testsuite/gas/mach-o/sections-3.s | 7 ++++ 13 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 gas/testsuite/gas/mach-o/err-sections-1.s create mode 100644 gas/testsuite/gas/mach-o/err-sections-2.s create mode 100644 gas/testsuite/gas/mach-o/sections-3.d create mode 100644 gas/testsuite/gas/mach-o/sections-3.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b651abec4e8..a2d74994854 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2011-12-19 Iain Sandoe + + * mach-o-i386.c (bfd_mach_o_section_type_valid_for_tgt): Define NULL. + * mach-o-target.c (bfd_mach_o_backend_data): Initialize + bfd_mach_o_section_type_valid_for_tgt + * mach-o-x86-64.c (bfd_mach_o_section_type_valid_for_x86_64): New. + (bfd_mach_o_section_type_valid_for_tgt): Set to + bfd_mach_o_section_type_valid_for_x86_64. + * mach-o.c (bfd_mach_o_section_type_name): Reorder and eliminate dup. + (bfd_mach_o_section_attribute_name): Reorder. + (bfd_mach_o_get_section_type_from_name): If the target has defined a + validator for section types, then use it. + * mach-o.h (bfd_mach_o_get_section_type_from_name): Alter declaration + to include the bfd. + 2011-12-19 Chung-Lin Tang * reloc.c (BFD_RELOC_MIPS16_TLS_GD,BFD_RELOC_MIPS16_TLS_LDM, diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c index 3dadcb82789..d1067104132 100644 --- a/bfd/mach-o-i386.c +++ b/bfd/mach-o-i386.c @@ -338,6 +338,7 @@ const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] = #define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread #define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat +#define bfd_mach_o_section_type_valid_for_tgt NULL #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index 4aeb920d2bd..a2aa573c4f2 100644 --- a/bfd/mach-o-target.c +++ b/bfd/mach-o-target.c @@ -96,7 +96,8 @@ static const bfd_mach_o_backend_data TARGET_NAME_BACKEND = bfd_mach_o_swap_reloc_in, bfd_mach_o_swap_reloc_out, bfd_mach_o_print_thread, - bfd_mach_o_tgt_seg_table + bfd_mach_o_tgt_seg_table, + bfd_mach_o_section_type_valid_for_tgt }; const bfd_target TARGET_NAME = diff --git a/bfd/mach-o-x86-64.c b/bfd/mach-o-x86-64.c index c86efb71acb..cc31a1c3d67 100644 --- a/bfd/mach-o-x86-64.c +++ b/bfd/mach-o-x86-64.c @@ -281,6 +281,16 @@ bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, return NULL; } +static bfd_boolean +bfd_mach_o_section_type_valid_for_x86_64 (unsigned long val) +{ + if (val == BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS + || val == BFD_MACH_O_S_LAZY_SYMBOL_POINTERS + || val == BFD_MACH_O_S_SYMBOL_STUBS) + return FALSE; + return TRUE; +} + #define bfd_mach_o_swap_reloc_in bfd_mach_o_x86_64_swap_reloc_in #define bfd_mach_o_swap_reloc_out bfd_mach_o_x86_64_swap_reloc_out @@ -288,6 +298,7 @@ bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_x86_64_bfd_reloc_name_lookup #define bfd_mach_o_print_thread NULL #define bfd_mach_o_tgt_seg_table NULL +#define bfd_mach_o_section_type_valid_for_tgt bfd_mach_o_section_type_valid_for_x86_64 #define TARGET_NAME mach_o_x86_64_vec #define TARGET_STRING "mach-o-x86-64" diff --git a/bfd/mach-o.c b/bfd/mach-o.c index dca86013d64..cc68d8921c5 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -3550,24 +3550,26 @@ bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type) } } +/* The following two tables should be kept, as far as possible, in order of + most frequently used entries to optimize their use from gas. */ + const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] = { { "regular", BFD_MACH_O_S_REGULAR}, + { "coalesced", BFD_MACH_O_S_COALESCED}, { "zerofill", BFD_MACH_O_S_ZEROFILL}, { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS}, { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS}, { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS}, + { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS}, { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS}, - { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS}, - { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS}, - { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS}, { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS}, { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS}, - { "coalesced", BFD_MACH_O_S_COALESCED}, { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL}, { "interposing", BFD_MACH_O_S_INTERPOSING}, - { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS}, { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF}, + { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS}, + { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS}, { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS}, { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS}, { NULL, 0} @@ -3575,30 +3577,38 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] = const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] = { + { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS }, + { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS }, { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC }, { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC }, - { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS }, { "debug", BFD_MACH_O_S_ATTR_DEBUG }, - { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT }, { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP }, { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS }, { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC }, - { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS }, { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, + { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE }, { NULL, 0} }; /* Get the section type from NAME. Return 256 if NAME is unknown. */ unsigned int -bfd_mach_o_get_section_type_from_name (const char *name) +bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name) { const bfd_mach_o_xlat_name *x; + bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd); for (x = bfd_mach_o_section_type_name; x->name; x++) if (strcmp (x->name, name) == 0) - return x->val; + { + /* We found it... does the target support it? */ + if (bed->bfd_mach_o_section_type_valid_for_target == NULL + || bed->bfd_mach_o_section_type_valid_for_target (x->val)) + return x->val; /* OK. */ + else + break; /* Not supported. */ + } /* Maximum section ID = 0xff. */ return 256; } @@ -3785,6 +3795,7 @@ bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd) #define bfd_mach_o_swap_reloc_out NULL #define bfd_mach_o_print_thread NULL #define bfd_mach_o_tgt_seg_table NULL +#define bfd_mach_o_section_type_valid_for_tgt NULL #define TARGET_NAME mach_o_be_vec #define TARGET_STRING "mach-o-be" diff --git a/bfd/mach-o.h b/bfd/mach-o.h index 23c3e1c079c..89dce1a21ef 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -584,7 +584,7 @@ bfd_boolean bfd_mach_o_set_section_contents (bfd *, asection *, const void *, file_ptr, bfd_size_type); unsigned int bfd_mach_o_version (bfd *); -unsigned int bfd_mach_o_get_section_type_from_name (const char *); +unsigned int bfd_mach_o_get_section_type_from_name (bfd *, const char *); unsigned int bfd_mach_o_get_section_attribute_from_name (const char *); void bfd_mach_o_convert_section_name_to_bfd (bfd *, const char *, const char *, @@ -636,6 +636,7 @@ typedef struct bfd_mach_o_backend_data bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *, void *, char *); const mach_o_segment_name_xlat *segsec_names_xlat; + bfd_boolean (*bfd_mach_o_section_type_valid_for_target) (unsigned long); } bfd_mach_o_backend_data; diff --git a/gas/ChangeLog b/gas/ChangeLog index 9707060679a..6cfd3dbe5b2 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2011-12-19 Iain Sandoe + + * config/obj-macho.c (obj_mach_o_section): Account for target- + dependent section types. Improve error handling when wrong section + types/attributes are specified. + 2011-12-19 Chung-Lin Tang * config/tc-mips.c (mips_pseudo_table): Add tprelword/tpreldword diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c index 0852cde2e8d..be1c9ffe311 100644 --- a/gas/config/obj-macho.c +++ b/gas/config/obj-macho.c @@ -169,6 +169,10 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) char segname[17]; char sectname[17]; +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + /* Zero-length segment and section names are allowed. */ /* Parse segment name. */ memset (segname, 0, sizeof(segname)); @@ -203,16 +207,18 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) /* Temporarily make a string from the token. */ p[len] = 0; - sectype = bfd_mach_o_get_section_type_from_name (p); + sectype = bfd_mach_o_get_section_type_from_name (stdoutput, p); if (sectype > 255) /* Max Section ID == 255. */ { as_bad (_("unknown or invalid section type '%s'"), p); - sectype = BFD_MACH_O_S_REGULAR; + p[len] = tmpc; + ignore_rest_of_line (); + return; } else sectype_given = 1; /* Restore. */ - tmpc = p[len]; + p[len] = tmpc; /* Parse attributes. TODO: check validity of attributes for section type. */ @@ -241,7 +247,12 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) p[len] ='\0'; attr = bfd_mach_o_get_section_attribute_from_name (p); if (attr == -1) - as_bad (_("unknown or invalid section attribute '%s'"), p); + { + as_bad (_("unknown or invalid section attribute '%s'"), p); + p[len] = tmpc; + ignore_rest_of_line (); + return; + } else { secattr_given = 1; @@ -253,19 +264,26 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) while (*input_line_pointer == '+'); /* Parse sizeof_stub. */ - if (*input_line_pointer == ',') + if (secattr_given && *input_line_pointer == ',') { if (sectype != BFD_MACH_O_S_SYMBOL_STUBS) - as_bad (_("unexpected sizeof_stub expression")); + { + as_bad (_("unexpected section size information")); + ignore_rest_of_line (); + return; + } input_line_pointer++; sizeof_stub = get_absolute_expression (); } - else if (sectype == BFD_MACH_O_S_SYMBOL_STUBS) - as_bad (_("missing sizeof_stub expression")); + else if (secattr_given && sectype == BFD_MACH_O_S_SYMBOL_STUBS) + { + as_bad (_("missing sizeof_stub expression")); + ignore_rest_of_line (); + return; + } } } - demand_empty_rest_of_line (); flags = SEC_NO_FLAGS; /* This provides default bfd flags and default mach-o section type and @@ -296,10 +314,6 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) name = n; } -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - /* Sub-segments don't exists as is on Mach-O. */ sec = subseg_new (name, 0); @@ -334,6 +348,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED) || msect->flags != (secattr | sectype)) as_warn (_("Ignoring changed section attributes for %s"), name); } + demand_empty_rest_of_line (); } static segT diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index c9efc902f02..723b8c486fe 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-12-19 Iain Sandoe + + * gas/mach-o/err-sections-1.s: New. + * gas/mach-o/err-sections-2.s: New. + * gas/mach-o/sections-3.d: New. + * gas/mach-o/sections-3.s: New. + 2011-12-15 Iain Sandoe * gas/mach-o/subsect-via-symbols-0.d: New. diff --git a/gas/testsuite/gas/mach-o/err-sections-1.s b/gas/testsuite/gas/mach-o/err-sections-1.s new file mode 100644 index 00000000000..99447a7885c --- /dev/null +++ b/gas/testsuite/gas/mach-o/err-sections-1.s @@ -0,0 +1,9 @@ +# { dg-do assemble { target x86_64-*-darwin* } } + + .section __a,__b,symbol_stubs,strip_static_syms,4 + .section __a,__c,lazy_symbol_pointers,strip_static_syms,4 + .section __a,__d,non_lazy_symbol_pointers,strip_static_syms,4 + +# { dg-error "unknown or invalid section type .symbol_stubs." "" { target x86_64-*-darwin* } 3 } +# { dg-error "unknown or invalid section type .lazy_symbol_pointers." "" { target x86_64-*-darwin* } 4 } +# { dg-error "unknown or invalid section type .non_lazy_symbol_pointers." "" { target x86_64-*-darwin* } 5 } diff --git a/gas/testsuite/gas/mach-o/err-sections-2.s b/gas/testsuite/gas/mach-o/err-sections-2.s new file mode 100644 index 00000000000..3343066befc --- /dev/null +++ b/gas/testsuite/gas/mach-o/err-sections-2.s @@ -0,0 +1,9 @@ +# { dg-do assemble { target x86_64-*-darwin* } } + + .symbol_stub + .lazy_symbol_pointer + .non_lazy_symbol_pointer + +# { dg-error ".symbol_stub is not used for the selected target" "" { target x86_64-*-darwin* } 3 } +# { dg-error ".lazy_symbol_pointer is not used for the selected target" "" { target x86_64-*-darwin* } 4 } +# { dg-error ".non_lazy_symbol_pointer is not used for the selected target" "" { target x86_64-*-darwin* } 5 } diff --git a/gas/testsuite/gas/mach-o/sections-3.d b/gas/testsuite/gas/mach-o/sections-3.d new file mode 100644 index 00000000000..9d1daf4d94e --- /dev/null +++ b/gas/testsuite/gas/mach-o/sections-3.d @@ -0,0 +1,19 @@ +#objdump: -P section +#not-target: x86_64-*-darwin* +.*: +file format mach-o.* +#... + Section: __symbol_stub __TEXT.*\(bfdname: .symbol_stub\) + addr: (00000000)?00000000 size: (00000000)?00000000 offset: (00000000)?00000000 + align: 0 nreloc: 0 reloff: (00000000)?00000000 + flags: 80000008 \(type: symbol_stubs attr: pure_instructions\) + first indirect sym: 0 \(0 entries\) stub size: (16|20) reserved3: 0x0 + Section: __la_symbol_ptr __DATA.*\(bfdname: .lazy_symbol_pointer\) + addr: (00000000)?00000000 size: (00000000)?00000000 offset: (00000000)?00000000 + align: 2 nreloc: 0 reloff: (00000000)?00000000 + flags: 00000007 \(type: lazy_symbol_pointers attr: -\) + first indirect sym: 0 \(0 entries\) reserved2: 0x0 reserved3: 0x0 + Section: __nl_symbol_ptr __DATA.*\(bfdname: .non_lazy_symbol_pointer\) + addr: (00000000)?00000000 size: (00000000)?00000000 offset: (00000000)?00000000 + align: 2 nreloc: 0 reloff: (00000000)?00000000 + flags: 00000006 \(type: non_lazy_symbol_pointers attr: -\) + first indirect sym: 0 \(0 entries\) reserved2: 0x0 reserved3: 0x0 diff --git a/gas/testsuite/gas/mach-o/sections-3.s b/gas/testsuite/gas/mach-o/sections-3.s new file mode 100644 index 00000000000..17fae524975 --- /dev/null +++ b/gas/testsuite/gas/mach-o/sections-3.s @@ -0,0 +1,7 @@ + + .symbol_stub + + .lazy_symbol_pointer + + .non_lazy_symbol_pointer +