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

Iain Sandoe developer@sandoe-acoustics.co.uk
Mon Dec 19 12:20:00 GMT 2011


On 19 Dec 2011, at 09:58, Tristan Gingold wrote:
> 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.

Seems reasonable - I suppose we can work on the principle that the  
section type can't be in an object unless it's supported - so we only  
need to check when creating/writing.

new version,
OK?
Iain


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/mach-o-i386.c                         |    1 +
  bfd/mach-o-target.c                       |    3 +-
  bfd/mach-o-x86-64.c                       |   11 ++++++++
  bfd/mach-o.c                              |   28 ++++++++++++-------
  bfd/mach-o.h                              |    3 +-
  gas/config/obj-macho.c                    |   41 ++++++++++++++++++ 
+---------
  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 +++++
  10 files changed, 106 insertions(+), 25 deletions(-)

diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c
index 3dadcb8..d106710 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 4aeb920..a2aa573 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 c86efb7..cc31a1c 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 dca8601..195f6d1 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -3553,21 +3553,20 @@ bfd_mach_o_stack_addr (enum  
bfd_mach_o_cpu_type type)
  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 +3574,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 +3792,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 23c3e1c..89dce1a 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/config/obj-macho.c b/gas/config/obj-macho.c
index 0852cde..be1c9ff 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/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