[Patch mach-o/gas] make section type names target-dependent.

Tristan Gingold gingold@adacore.com
Mon Dec 19 09:59:00 GMT 2011


On Dec 16, 2011, at 9:34 PM, Iain Sandoe wrote:

> I am trying to test the four main Darwin targets as I implement things ..
> .. the Idea being that, one day, we will simply be able to enable them all in configure...
> 
> Testing my current stuff (for symbol type qualifiers) reminded me that some section types are not applicable to all targets.
> (At present, specifically, that means that x86-64 doesn't support symbol stubs, or {non,}lazy_symbol_stubs).
> 
> The patch below checks for a target-specific table ahead of the generic one.
> I followed the current style of printing in binutils/od-macho.c and parsing in bfd/mach-o.c although I wonder if it might be more obvious to put them both back into bfd/mach-o.c and just publish the accessor routines.

Thank you for working on that.

May I suggest a slightly different approach (feel free to discuss it) ?

These section types are defined independently of the targets.  So I think they must stay in bfd_mach_o_section_type_name.
I agree that some are not valid on some targets.  So just add a subtarget hook that returns FALSE if the section type is not supported by
the target.

Tristan.

> 
> OK?
> Iain
> 
> bfd:
> 
> 	* mach-o-i386.c (mach_o_i386_section_type_names): New.
> 	(bfd_mach_o_tgt_section_type_names): Use mach_o_i386_section_type_names.
> 	* mach-o-target.c (bfd_mach_o_tgt_section_type_names): New initializer.
> 	* mach-o-x86-64.c (bfd_mach_o_tgt_section_type_names): Initialize to NULL.
> 	* mach-o.c (bfd_mach_o_section_type_name): Remove target-dependent entries.
> 	(mach_o_default_additional_section_type_names): New.
> 	(bfd_mach_o_get_section_type_from_name): Look for target-specific entries.
> 	(bfd_mach_o_tgt_section_type_names): Use default additions for {le,be}_vec.
> 	* mach-o.h (bfd_mach_o_get_section_type_from_name): Alter definition to include
> 	bfd.
> 
> binutils:
> 
> 	* od-macho.c (dump_section): Account for target-dependent section types.
> 
> 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/mach-o-i386.c                         |    9 ++++++++
> bfd/mach-o-target.c                       |    3 +-
> bfd/mach-o-x86-64.c                       |    1 +
> bfd/mach-o.c                              |   22 ++++++++++++++++----
> bfd/mach-o.h                              |    3 +-
> binutils/od-macho.c                       |   16 +++++++++++---
> gas/config/obj-macho.c                    |   30 ++++++++++++++++++++++++----
> 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 ++++++
> 11 files changed, 112 insertions(+), 16 deletions(-)
> 
> diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c
> index 3dadcb8..2d92075 100644
> --- a/bfd/mach-o-i386.c
> +++ b/bfd/mach-o-i386.c
> @@ -333,11 +333,20 @@ const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] =
>     { NULL, NULL }
>   };
> 
> +const bfd_mach_o_xlat_name mach_o_i386_section_type_names[] =
> +{
> +  { "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},
> +  { NULL, 0}
> +};
> +
> #define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in
> #define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out
> #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_tgt_section_type_names mach_o_i386_section_type_names
> 
> #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 4aeb920..3d4b494 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_tgt_section_type_names
> };
> 
> const bfd_target TARGET_NAME =
> diff --git a/bfd/mach-o-x86-64.c b/bfd/mach-o-x86-64.c
> index c86efb7..0abd319 100644
> --- a/bfd/mach-o-x86-64.c
> +++ b/bfd/mach-o-x86-64.c
> @@ -288,6 +288,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_tgt_section_type_names NULL
> 
> #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 dca8601..edd5ce5 100644
> --- a/bfd/mach-o.c
> +++ b/bfd/mach-o.c
> @@ -3558,9 +3558,6 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
>   { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
>   { "8byte_literals", BFD_MACH_O_S_8BYTE_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},
> @@ -3568,7 +3565,6 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
>   { "interposing", BFD_MACH_O_S_INTERPOSING},
>   { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
>   { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
> -  { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
>   { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
>   { NULL, 0}
> };
> @@ -3589,12 +3585,27 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
>   { NULL, 0}
> };
> 
> +const bfd_mach_o_xlat_name mach_o_default_additional_section_type_names[] =
> +{
> +  { "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},
> +  { 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);
> +
> +  /* First try any target-specific translations defined...  */
> +  if (bed->section_type_names)
> +    for (x = bed->section_type_names; x->name; x++)
> +      if (strcmp (x->name, name) == 0)
> +	return x->val;
> 
>   for (x = bfd_mach_o_section_type_name; x->name; x++)
>     if (strcmp (x->name, name) == 0)
> @@ -3785,6 +3796,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_tgt_section_type_names mach_o_default_additional_section_type_names
> 
> #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 23c3e1c..af688c2 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;
> +  const bfd_mach_o_xlat_name *section_type_names;
> }
> bfd_mach_o_backend_data;
> 
> diff --git a/binutils/od-macho.c b/binutils/od-macho.c
> index c5e315d..b13d2f9 100644
> --- a/binutils/od-macho.c
> +++ b/binutils/od-macho.c
> @@ -314,8 +314,12 @@ dump_section_map (bfd *abfd)
> }
> 
> static void
> -dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
> +dump_section (bfd *abfd, bfd_mach_o_section *sec)
> {
> +  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
> +  const char * secttype_name = NULL;
> +  unsigned typ = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
> +
>   printf (" Section: %-16s %-16s (bfdname: %s)\n",
>            sec->sectname, sec->segname, sec->bfdsection->name);
>   printf ("  addr: ");
> @@ -329,9 +333,13 @@ dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
>   printf ("  nreloc: %lu  reloff: ", sec->nreloc);
>   printf_vma (sec->reloff);
>   printf ("\n");
> -  printf ("  flags: %08lx (type: %s", sec->flags,
> -          bfd_mach_o_get_name (bfd_mach_o_section_type_name,
> -                               sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
> +  if (bed->section_type_names != NULL)
> +    secttype_name = bfd_mach_o_get_name_or_null (bed->section_type_names,
> +						 typ);
> +  if (secttype_name == NULL)
> +    secttype_name = bfd_mach_o_get_name (bfd_mach_o_section_type_name,typ);
> +
> +  printf ("  flags: %08lx (type: %s", sec->flags, secttype_name);
>   printf (" attr: ");
>   bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
>                           sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
> diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
> index 0852cde..e5da7d1 100644
> --- a/gas/config/obj-macho.c
> +++ b/gas/config/obj-macho.c
> @@ -168,6 +168,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
>   bfd_mach_o_section *msect;
>   char segname[17];
>   char sectname[17];
> +  int error = 0;
> 
>   /* Zero-length segment and section names are allowed.  */
>   /* Parse segment name.  */
> @@ -203,10 +204,12 @@ 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);
> +	  ignore_rest_of_line ();
> +	  error = 1;
>           sectype = BFD_MACH_O_S_REGULAR;
>         }
>       else
> @@ -241,7 +244,11 @@ 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);
> +		  ignore_rest_of_line ();
> +		  error = 1;
> +                }
>               else
> 		{
> 		  secattr_given = 1;
> @@ -256,16 +263,29 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
>           if (*input_line_pointer == ',')
>             {
>               if (sectype != BFD_MACH_O_S_SYMBOL_STUBS)
> -                as_bad (_("unexpected sizeof_stub expression"));
> +                {
> +		  as_bad (_("unexpected sizeof_stub expression"));
> +		  ignore_rest_of_line ();
> +		  error = 1;
> +		}
> 
> 	      input_line_pointer++;
>               sizeof_stub = get_absolute_expression ();
>             }
>           else if (sectype == BFD_MACH_O_S_SYMBOL_STUBS)
> -            as_bad (_("missing sizeof_stub expression"));
> +            {
> +              as_bad (_("missing sizeof_stub expression"));
> +	      ignore_rest_of_line ();
> +              error = 1;
> +            }
>         }
>     }
> -  demand_empty_rest_of_line ();
> +
> +  if (error)
> +    /* Don't issue a bunch of unhelpful additional errors.  */
> +    ignore_rest_of_line ();
> +  else
> +    demand_empty_rest_of_line ();
> 
>   flags = SEC_NO_FLAGS;
>   /* This provides default bfd flags and default mach-o section type and
> 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 0000000..99447a7
> --- /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 0000000..3343066
> --- /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 0000000..9d1daf4
> --- /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 0000000..17fae52
> --- /dev/null
> +++ b/gas/testsuite/gas/mach-o/sections-3.s
> @@ -0,0 +1,7 @@
> +
> +	.symbol_stub
> +	
> +	.lazy_symbol_pointer
> +	
> +	.non_lazy_symbol_pointer
> +
> 
> 	



More information about the Binutils mailing list