This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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



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
+



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]