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 section stack.


this adds support for an elf-style section stack

OK?
Iain

gas:

	* config/obj-macho.c (section_stack): New type.
	 (sec_stack): New file scope var.
	(obj_mach_o_maybe_quoted_canonical_section_name): New.
	(obj_mach_o_push_sect): New.
	(obj_mach_o_pop_sect): New.
	(mach_o_pseudo_table): Add pushsection, popsection.

gas/testsuite:

	* gas/mach-o/push-pop-1.d: New.
	* gas/mach-o/push-pop-1.s: New.
	* gas/mach-o/warn-push-pop-1.s: New.

===

gas/config/obj-macho.c | 164 +++++++++++++++++++ +++++++++
gas/testsuite/gas/mach-o/push-pop-1.d | 17 +++
gas/testsuite/gas/mach-o/push-pop-1.s | 68 ++++++++++++
gas/testsuite/gas/mach-o/warn-push-pop-1.s | 7 +
4 files changed, 256 insertions(+), 0 deletions(-)


diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index abea09b..804d42b 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -45,6 +45,8 @@
 #include "mach-o/loader.h"
 #include "obj-macho.h"

+#include <string.h>
+
/* Forward decl. */
static segT obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed);


@@ -801,6 +803,165 @@ obj_mach_o_previous (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }

+/* Get a (possibly quoted) canonical section name. */
+
+static char *
+obj_mach_o_maybe_quoted_canonical_section_name (char *bf)
+{
+ SKIP_WHITESPACE ();
+ /* All of our 'canonical' section names start with a '.'. */
+ if (*input_line_pointer == '.')
+ {
+ char c;
+ int l = 0;
+
+ /* There's nothing to add to a canonical section name - so we end with
+ space or newline. */
+ while ((c = *input_line_pointer) != ' '
+ && c != '\t'
+ && !is_end_of_line[(unsigned char) c])
+ {
+ input_line_pointer++;
+ bf[l++] = c;
+ if (l > 255)
+ return NULL;
+ }
+ bf[l] = '\0';
+
+ /* We're not going to accept just '.' as a canonical section name. */
+ if (l == 1)
+ {
+ as_bad (_("missing name"));
+ return NULL;
+ }
+
+ return bf;
+ }
+ else if (*input_line_pointer == '"'
+ && *(input_line_pointer+1) == '.' ) /* Allow elf-like quoted name. */
+ {
+ int dummy;
+ char *sn;
+
+ sn = demand_copy_C_string (&dummy);
+ if (sn == NULL)
+ return NULL;
+
+ strncpy (bf, sn, 255);
+ return bf;
+ }
+
+ return NULL;
+}
+
+typedef struct section_stack
+{
+ struct section_stack *next;
+ segT seg;
+ segT prev_seg;
+} section_stack;
+
+static section_stack *sec_stack;
+
+static void
+obj_mach_o_push_sect (int ignore ATTRIBUTE_UNUSED)
+{
+ char canname[256];
+ segT new_sec = NULL;
+ segT old_sec = now_seg;
+ section_stack *top;
+ char *cn;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* See if it might be a canonical name - i.e. begins with a '.'. */
+ cn = obj_mach_o_maybe_quoted_canonical_section_name (canname);
+ if (cn != NULL)
+ {
+ /* Cater for the fact we might be creating one of the three base
+ sections. */
+ if (strcmp (canname, TEXT_SECTION_NAME) == 0)
+ new_sec = obj_mach_o_get_base_section (1);
+ else if (strcmp (canname, DATA_SECTION_NAME) == 0)
+ new_sec = obj_mach_o_get_base_section (2);
+ else if (strcmp (canname, BSS_SECTION_NAME) == 0)
+ new_sec = obj_mach_o_get_base_section (3);
+ else
+ {
+ /* It's not mandatory for this to work, the user might want
+ to declare a segment starting with a '.' - thus the somewhat
+ convoluted logic here. */
+ new_sec = obj_mach_o_segT_from_bfd_name (canname, 0);
+ if (new_sec != NULL)
+ /* We just dump the rest of the line - ignoring any elf-style
+ qualifiers that might have been present. */
+ ignore_rest_of_line ();
+ else
+ {
+ new_sec = obj_mach_o_parse_section ();
+ if (new_sec != NULL)
+ demand_empty_rest_of_line ();
+ }
+ }
+ }
+ else
+ {
+ new_sec = obj_mach_o_parse_section ();
+ if (new_sec != NULL)
+ demand_empty_rest_of_line ();
+ }
+
+ if (new_sec == NULL)
+ {
+ as_bad (_("couldn't parse section description"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ top = (section_stack *) xmalloc (sizeof (section_stack));
+ if (top == NULL)
+ {
+ as_bad (_("internal error: failed to allocate section stack"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ top->next = sec_stack;
+ top->seg = old_sec;
+ top->prev_seg = previous_section;
+ sec_stack = top;
+
+ if (old_sec != new_sec)
+ previous_section = old_sec;
+
+ subseg_set (new_sec, 0);
+}
+
+static void
+obj_mach_o_pop_sect (int ignore ATTRIBUTE_UNUSED)
+{
+ section_stack *top = sec_stack;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* pop the section stack, if there's anything on it. */
+ if (top == NULL)
+ {
+ as_warn (_(".popsection without corresponding .pushsection; ignored"));
+ return;
+ }
+
+ sec_stack = top->next;
+ previous_section = top->prev_seg;
+ subseg_set (top->seg, 0);
+ xfree (top);
+ demand_empty_rest_of_line ();
+}
+
/* Set properties that apply to the whole file. At present, the only
one defined, is subsections_via_symbols. */


@@ -920,6 +1081,9 @@ const pseudo_typeS mach_o_pseudo_table[] =

   /* Support the elf-style previous.  */
   { "previous", obj_mach_o_previous, 0},
+  /* Support an elf-style section stack.  */
+  { "pushsection", obj_mach_o_push_sect, 0},
+  { "popsection", obj_mach_o_pop_sect, 0},

/* Symbol-related. */
{ "indirect_symbol", obj_mach_o_placeholder, 0},
diff --git a/gas/testsuite/gas/mach-o/push-pop-1.d b/gas/testsuite/gas/ mach-o/push-pop-1.d
new file mode 100644
index 0000000..eb48ccc
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/push-pop-1.d
@@ -0,0 +1,17 @@
+#objdump: -t
+.*: +file format mach-o.*
+#...
+SYMBOL TABLE:
+(00000000)?00000000 g.*0f SECT.*01 0000 \[.text\] a
+(00000000)?00000000 g.*0f SECT.*02 0000 \[.debug_info\] b
+(00000000)?00000001 g.*0f SECT.*01 0000 \[.text\] c
+(00000000)?00000000 g.*0f SECT.*03 0000 \[__SOMEWHERE.__else\] d
+(00000000)?00000002 g.*0f SECT.*01 0000 \[.text\] e
+(00000000)?00000001 g.*0f SECT.*03 0000 \[__SOMEWHERE.__else\] f
+(00000000)?00000000 g.*0f SECT.*04 0000 \[.data\] g
+(00000000)?00000000 g.*0f SECT.*05 0000 \[.debug_abbrev\] h
+(00000000)?00000001 g.*0f SECT.*04 0000 \[.data\] i
+(00000000)?00000002 g.*0f SECT.*03 0000 \[__SOMEWHERE.__else\] j
+(00000000)?00000003 g.*0f SECT.*01 0000 \[.text\] k
+(00000000)?00000000 g.*0f SECT.*06 0000 \[.debug_aranges\] m
+(00000000)?00000004 g.*0f SECT.*01 0000 \[.text\] n
\ No newline at end of file
diff --git a/gas/testsuite/gas/mach-o/push-pop-1.s b/gas/testsuite/gas/ mach-o/push-pop-1.s
new file mode 100644
index 0000000..addfef3
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/push-pop-1.s
@@ -0,0 +1,68 @@
+ .text
+
+ .globl a
+a: .space 1
+
+ .pushsection .debug_info
+
+ .globl b
+b: .space 1
+
+ .popsection
+
+ .globl c
+c: .space 1
+
+ .pushsection __SOMEWHERE,__else,regular
+
+ .globl d
+d: .space 1
+
+ .popsection
+
+ .globl e
+e: .space 1
+
+ .pushsection __SOMEWHERE,__else,regular
+
+ .globl f
+f: .space 1
+
+ .pushsection .data
+
+ .globl g
+g: .space 1
+
+ .pushsection ".debug_abbrev"
+
+ .globl h
+h: .space 1
+
+ .popsection
+
+ .globl i
+i: .space 1
+
+ .popsection
+
+ .globl j
+j: .space 1
+
+ .popsection
+
+ .globl k
+k: .space 1
+
+# in a bid to make (easier) compatibility with elf code - we ignore the
+# remainder of the line when the section named is a well-known canonical one.
+# We can`t act on the information anyway.
+
+ .pushsection ".debug_aranges", "MS",@progbits,1
+
+ .globl m
+m: .space 1
+
+ .popsection
+
+ .globl n
+n: .space 1
diff --git a/gas/testsuite/gas/mach-o/warn-push-pop-1.s b/gas/ testsuite/gas/mach-o/warn-push-pop-1.s
new file mode 100644
index 0000000..a67cf27
--- /dev/null
+++ b/gas/testsuite/gas/mach-o/warn-push-pop-1.s
@@ -0,0 +1,7 @@
+# { dg-do assemble }
+ .text
+ .pushsection .debug_info
+ .popsection
+ .popsection
+
+# { dg-warning ".popsection without corresponding .pushsection; ignored" "" { target *-*-darwin*} 5 }



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