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]

[Patch mach-o/gas] support .previous


.previous is a nice feature and will help us with compatibility with elf-style code.

OK?
Iain

gas:

* config/obj-macho.c (previous_section): New file-scope var.
(obj_mach_o_parse_section): Split from obj_mach_o_section.
(obj_mach_o_section): Use obj_mach_o_parse_section, update previous.
(obj_mach_o_known_section): Update previous.
(obj_mach_o_objc_section): Likewise.
(obj_mach_o_debug_section): Likewise.
(obj_mach_o_opt_tgt_section): Likewise.
(obj_mach_o_get_base_section): Split from obj_mach_o_base_section.
(obj_mach_o_base_section): Use obj_mach_o_get_base_section, update previous.
(obj_mach_o_previous): New.
(mach_o_pseudo_table): Add previous.


gas/testsuite:

	* gas/mach-o/previous-1.d: New.
	* gas/mach-o/previous-1.s: New.
	* gas/mach-o/warn-prev-1.s: New.

==

gas/config/obj-macho.c | 185 ++++++++++++++++++++++ +---------
gas/testsuite/gas/mach-o/previous-1.d | 8 ++
gas/testsuite/gas/mach-o/previous-1.s | 20 ++++
gas/testsuite/gas/mach-o/warn-prev-1.s | 5 +
4 files changed, 167 insertions(+), 51 deletions(-)


diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 74fb0c9..abea09b 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -1,5 +1,5 @@
 /* Mach-O object file format
-   Copyright 2009, 2011 Free Software Foundation, Inc.
+   Copyright 2009, 2011, 2012 Free Software Foundation, Inc.

This file is part of GAS, the GNU Assembler.

@@ -48,6 +48,9 @@
/* Forward decl. */
static segT obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed);


+/* Support for .previous for improved compatibility with elf-style code. */
+static segT previous_section;
+
/* TODO: Implement "-dynamic"/"-static" command line options. */


static int obj_mach_o_is_static;
@@ -175,8 +178,8 @@ collect_16char_name (char *dest, const char *msg, int require_comma)
Not all section types and attributes are accepted by the Darwin system
assemblers as user-specifiable - although, at present, we do here. */


-static void
-obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
+static segT
+obj_mach_o_parse_section (void)
 {
   char *p;
   char c;
@@ -196,17 +199,13 @@ 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));
   if (collect_16char_name (segname, "segment", 1))
     {
       ignore_rest_of_line ();
-      return;
+      return NULL;
     }
   input_line_pointer++; /* Skip the terminating ',' */

@@ -240,7 +239,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
as_bad (_("unknown or invalid section type '%s'"), p);
p[len] = tmpc;
ignore_rest_of_line ();
- return;
+ return NULL;
}
else
sectype_given = 1;
@@ -278,7 +277,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
as_bad (_("unknown or invalid section attribute '%s'"), p);
p[len] = tmpc;
ignore_rest_of_line ();
- return;
+ return NULL;
}
else
{
@@ -297,7 +296,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
{
as_bad (_("unexpected section size information"));
ignore_rest_of_line ();
- return;
+ return NULL;
}


 	      input_line_pointer++;
@@ -307,7 +306,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
             {
               as_bad (_("missing sizeof_stub expression"));
 	      ignore_rest_of_line ();
-	      return;
+	      return NULL;
             }
         }
     }
@@ -341,8 +340,8 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
       name = n;
     }

-  /* Sub-segments don't exists as is on Mach-O.  */
-  sec = subseg_new (name, 0);
+  /* Get or create the section.  */
+  sec = subseg_get (name, 0);

   oldflags = bfd_get_section_flags (stdoutput, sec);
   msect = bfd_mach_o_get_mach_o_section (sec);
@@ -375,7 +374,30 @@ 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 ();
+
+  return sec;
+}
+
+static void
+obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
+{
+  segT new_seg;
+  segT old_seg = now_seg;
+
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
+  new_seg = obj_mach_o_parse_section ();
+
+  if (new_seg != NULL)
+    {
+      demand_empty_rest_of_line ();
+
+      subseg_set (new_seg, 0);
+      if (now_seg != old_seg)
+	previous_section = old_seg;
+    }
 }

 static segT
@@ -443,17 +465,23 @@ static const char * const known_sections[] =
 static void
 obj_mach_o_known_section (int sect_index)
 {
-  segT section;
+  segT new_seg;
+  segT old_seg = now_seg;

 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif

- section = obj_mach_o_segT_from_bfd_name (known_sections[sect_index], 1);
- if (section != NULL)
- subseg_set (section, 0);
+ new_seg = obj_mach_o_segT_from_bfd_name (known_sections[sect_index], 1);


+ if (new_seg != NULL)
+ {
+ subseg_set (new_seg, 0);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
+ }
/* else, we leave the section as it was; there was a fatal error anyway. */
+ demand_empty_rest_of_line ();
}


 static const char * const objc_sections[] =
@@ -491,22 +519,25 @@ static const char * const objc_sections[] =
 static void
 obj_mach_o_objc_section (int sect_index)
 {
-  segT section;
+  segT new_seg;
+  segT old_seg = now_seg;

 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif

- section = obj_mach_o_segT_from_bfd_name (objc_sections[sect_index], 1);
- if (section != NULL)
+ new_seg = obj_mach_o_segT_from_bfd_name (objc_sections[sect_index], 1);
+ if (new_seg != NULL)
{
obj_mach_o_seen_objc_section = 1; /* We need to ensure that certain
sections are present and in the
right order. */
- subseg_set (section, 0);
+ subseg_set (new_seg, 0);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
}
-
/* else, we leave the section as it was; there was a fatal error anyway. */
+ demand_empty_rest_of_line ();
}


 /* Debug section directives.  */
@@ -536,17 +567,22 @@ static const char * const debug_sections[] =
 static void
 obj_mach_o_debug_section (int sect_index)
 {
-  segT section;
+  segT new_seg;
+  segT old_seg = now_seg;

 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif

- section = obj_mach_o_segT_from_bfd_name (debug_sections[sect_index], 1);
- if (section != NULL)
- subseg_set (section, 0);
-
+ new_seg = obj_mach_o_segT_from_bfd_name (debug_sections[sect_index], 1);
+ if (new_seg != NULL)
+ {
+ subseg_set (new_seg, 0);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
+ }
/* else, we leave the section as it was; there was a fatal error anyway. */
+ demand_empty_rest_of_line ();
}


/* This could be moved to the tc-xx files, but there is so little dependency
@@ -584,22 +620,25 @@ static void
obj_mach_o_opt_tgt_section (int sect_index)
{
const struct opt_tgt_sect *tgtsct = &tgt_sections[sect_index];
- segT section;
+ segT new_seg;
+ segT old_seg = now_seg;


 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif

- section = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
- if (section == NULL)
+ new_seg = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
+ if (new_seg == NULL)
{
as_bad (_("%s is not used for the selected target"), tgtsct- >name);
/* Leave the section as it is. */
}
else
{
- bfd_mach_o_section *mo_sec = bfd_mach_o_get_mach_o_section (section);
- subseg_set (section, 0);
+ bfd_mach_o_section *mo_sec = bfd_mach_o_get_mach_o_section (new_seg);
+ subseg_set (new_seg, 0);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
#if defined (TC_I386)
mo_sec->reserved2 = tgtsct->x86_val;
#elif defined (TC_PPC)
@@ -608,26 +647,14 @@ obj_mach_o_opt_tgt_section (int sect_index)
mo_sec->reserved2 = 0;
#endif
}
+ demand_empty_rest_of_line ();
}


-/* We don't necessarily have the three 'base' sections on mach-o.
-   Normally, we would start up with only the 'text' section defined.
-   However, even that can be suppressed with (TODO) c/l option "-n".
-   Thus, we have to be able to create all three sections on-demand.  */
-
-static void
-obj_mach_o_base_section (int sect_index)
+static segT
+obj_mach_o_get_base_section (int sect_index)
 {
   segT section;

-#ifdef md_flush_pending_output
- md_flush_pending_output ();
-#endif
-
- /* We don't support numeric (or any other) qualifications on the
- well-known section shorthands. */
- demand_empty_rest_of_line ();
-
switch (sect_index)
{
/* Handle the three sections that are globally known within GAS.
@@ -659,10 +686,39 @@ obj_mach_o_base_section (int sect_index)
break;
default:
as_fatal (_("internal error: base section index out of range"));
- return;
+ return NULL;
break;
}
- subseg_set (section, 0);
+ return section;
+}
+
+/* We don't necessarily have the three 'base' sections on mach-o.
+ Normally, we would start up with only the 'text' section defined.
+ However, even that can be suppressed with (TODO) c/l option "-n".
+ Thus, we have to be able to create all three sections on-demand. */
+
+static void
+obj_mach_o_base_section (int sect_index)
+{
+ segT new_seg;
+ segT old_seg = now_seg;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ new_seg = obj_mach_o_get_base_section (sect_index);
+ if (new_seg != NULL)
+ {
+ subseg_set (new_seg, 0);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
+ }
+ /* else, we leave the section as it was; there was a fatal error anyway. */
+
+ /* We don't support numeric (or any other) qualifications on canonical
+ section names. */
+ demand_empty_rest_of_line ();
}


/* This finishes off parsing a .comm or .lcomm statement, which both can have
@@ -718,7 +774,31 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
static void
obj_mach_o_comm (int is_local)
{
+ segT old_seg = now_seg;
s_comm_internal (is_local, obj_mach_o_common_parse);
+ if (now_seg != old_seg)
+ previous_section = old_seg;
+}
+
+static void
+obj_mach_o_previous (int ignore ATTRIBUTE_UNUSED)
+{
+ segT old_prev;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (previous_section == 0)
+ {
+ as_warn (_(".previous, but no section switch seen; ignored"));
+ return;
+ }
+
+ old_prev = previous_section;
+ previous_section = now_seg;
+ subseg_set (old_prev, 0);
+ demand_empty_rest_of_line ();
}


 /* Set properties that apply to the whole file.  At present, the only
@@ -838,6 +918,9 @@ const pseudo_typeS mach_o_pseudo_table[] =

{ "section", obj_mach_o_section, 0},

+ /* Support the elf-style previous. */
+ { "previous", obj_mach_o_previous, 0},
+
/* Symbol-related. */
{ "indirect_symbol", obj_mach_o_placeholder, 0},
{ "weak_definition", obj_mach_o_placeholder, 0},
diff --git a/gas/testsuite/gas/mach-o/previous-1.d b/gas/testsuite/gas/ mach-o/previous-1.d
new file mode 100644
index 0000000..64d4ee5
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/previous-1.d
@@ -0,0 +1,8 @@
+#objdump: -t
+.*: +file format mach-o.*
+#...
+SYMBOL TABLE:
+(00000000)?00000000 g.*0f SECT.*01 0000 \[.text\] a
+(00000000)?00000000 g.*0f SECT.*02 0000 \[.data\] a1
+(00000000)?00000001 g.*0f SECT.*01 0000 \[.text\] a2
+(00000000)?00000001 g.*0f SECT.*02 0000 \[.data\] a3
\ No newline at end of file
diff --git a/gas/testsuite/gas/mach-o/previous-1.s b/gas/testsuite/gas/ mach-o/previous-1.s
new file mode 100644
index 0000000..5522db7
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/previous-1.s
@@ -0,0 +1,20 @@
+ .text
+
+ .globl a
+a: .space 1
+
+ .data
+
+ .globl a1
+a1: .space 1
+
+ .previous
+
+ .globl a2
+a2: .space 1
+
+ .previous
+
+ .globl a3
+a3: .space 1
+
diff --git a/gas/testsuite/gas/mach-o/warn-prev-1.s b/gas/testsuite/ gas/mach-o/warn-prev-1.s
new file mode 100644
index 0000000..fd0c0b5
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/warn-prev-1.s
@@ -0,0 +1,5 @@
+# { dg-do assemble }
+
+ .previous
+
+# { dg-warning ".previous, but no section switch seen; ignored" "" { target *-*-darwin*} 3 }



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