Add support for intel SERIALIZE instruction
[deliverable/binutils-gdb.git] / gas / config / obj-coff-seh.c
index 6c3fe7c8efd8c2596109cdc5f60642b23adf9b3c..9a44c44eec88bf0ff89e284e84fc66383ca084c4 100644 (file)
@@ -1,6 +1,5 @@
 /* seh pdata/xdata coff object file format
-   Copyright 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2009-2020 Free Software Foundation, Inc.
 
    This file is part of GAS.
 
@@ -49,7 +48,7 @@ get_pxdata_name (segT seg, const char *base_name)
   const char *name,*dollar, *dot;
   char *sname;
 
-  name = bfd_get_section_name (stdoutput, seg);
+  name = bfd_section_name (seg);
 
   dollar = strchr (name, '$');
   dot = strchr (name + 1, '.');
@@ -96,16 +95,16 @@ make_pxdata_seg (segT cseg, char *name)
 
   r = subseg_new (name, 0);
   /* Check if code segment is marked as linked once.  */
-  flags = bfd_get_section_flags (stdoutput, cseg)
-    & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
-       | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
-       | SEC_LINK_DUPLICATES_SAME_CONTENTS);
+  flags = (bfd_section_flags (cseg)
+          & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+             | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
+             | SEC_LINK_DUPLICATES_SAME_CONTENTS));
 
   /* Add standard section flags.  */
   flags |= SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA;
 
   /* Apply possibly linked once flags to new generated segment, too.  */
-  if (!bfd_set_section_flags (stdoutput, r, flags))
+  if (!bfd_set_section_flags (r, flags))
     as_bad (_("bfd_set_section_flags: %s"),
            bfd_errmsg (bfd_get_error ()));
 
@@ -155,6 +154,28 @@ seh_hash_find_or_make (segT cseg, const char *base_name)
   return item;
 }
 
+/* Check if current segment has same name.  */
+static int
+seh_validate_seg (const char *directive)
+{
+  const char *cseg_name, *nseg_name;
+  if (seh_ctx_cur->code_seg == now_seg)
+    return 1;
+  cseg_name = bfd_section_name (seh_ctx_cur->code_seg);
+  nseg_name = bfd_section_name (now_seg);
+  as_bad (_("%s used in segment '%s' instead of expected '%s'"),
+         directive, nseg_name, cseg_name);
+  ignore_rest_of_line ();
+  return 0;
+}
+
+/* Switch back to the code section, whatever that may be.  */
+static void
+obj_coff_seh_code (int ignored ATTRIBUTE_UNUSED)
+{
+  subseg_set (seh_ctx_cur->code_seg, 0);
+}
+
 static void
 switch_xdata (int subseg, segT code_seg)
 {
@@ -308,8 +329,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED)
 
   if (*input_line_pointer == '@')
     {
-      symbol_name = input_line_pointer;
-      name_end = get_symbol_end ();
+      name_end = get_symbol_name (&symbol_name);
 
       seh_ctx_cur->handler.X_op = O_constant;
       seh_ctx_cur->handler.X_add_number = 0;
@@ -322,7 +342,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED)
       else
        as_bad (_("unknown constant value '%s' for handler"), symbol_name);
 
-      *input_line_pointer = name_end;
+      (void) restore_line_pointer (name_end);
     }
   else
     expression (&seh_ctx_cur->handler);
@@ -338,8 +358,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED)
     {
       do
        {
-         symbol_name = input_line_pointer;
-         name_end = get_symbol_end ();
+         name_end = get_symbol_name (&symbol_name);
 
          if (strcasecmp (symbol_name, "@unwind") == 0)
            seh_ctx_cur->handler_flags |= UNW_FLAG_UHANDLER;
@@ -348,7 +367,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED)
          else
            as_bad (_(".seh_handler constant '%s' unknown"), symbol_name);
 
-         *input_line_pointer = name_end;
+         (void) restore_line_pointer (name_end);
        }
       while (skip_whitespace_and_comma (0));
     }
@@ -395,7 +414,7 @@ obj_coff_seh_endproc (int what ATTRIBUTE_UNUSED)
       as_bad (_(".seh_endproc used without .seh_proc"));
       return;
     }
-
+  seh_validate_seg (".seh_endproc");
   do_seh_endproc ();
 }
 
@@ -433,10 +452,9 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED)
 
   SKIP_WHITESPACE ();
 
-  symbol_name = input_line_pointer;
-  name_end = get_symbol_end ();
+  name_end = get_symbol_name (&symbol_name);
   seh_ctx_cur->func_name = xstrdup (symbol_name);
-  *input_line_pointer = name_end;
+  (void) restore_line_pointer (name_end);
 
   demand_empty_rest_of_line ();
 
@@ -448,7 +466,8 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED)
 static void
 obj_coff_seh_endprologue (int what ATTRIBUTE_UNUSED)
 {
-  if (!verify_context (".seh_endprologue"))
+  if (!verify_context (".seh_endprologue")
+      || !seh_validate_seg (".seh_endprologue"))
     return;
   demand_empty_rest_of_line ();
 
@@ -464,10 +483,7 @@ void
 obj_coff_seh_do_final (void)
 {
   if (seh_ctx_cur != NULL)
-    {
-      as_bad (_("open SEH entry at end of file (missing .cfi_endproc)"));
-      do_seh_endproc ();
-    }
+    as_bad (_("open SEH entry at end of file (missing .seh_endproc)"));
 }
 
 /* Enter a prologue element into current context (x64).  */
@@ -527,14 +543,13 @@ seh_x64_read_reg (const char *directive, int kind)
   SKIP_WHITESPACE ();
   if (*input_line_pointer == '%')
     ++input_line_pointer;
-  symbol_name = input_line_pointer;
-  name_end = get_symbol_end ();
+  name_end = get_symbol_name (& symbol_name);
 
   for (i = 0; i < 16; i++)
     if (! strcasecmp (regs[i], symbol_name))
       break;
 
-  *input_line_pointer = name_end;
+  (void) restore_line_pointer (name_end);
 
   /* Error if register not found, or EAX used as a frame pointer.  */
   if (i == 16 || (kind == 0 && i == 0))
@@ -553,7 +568,8 @@ obj_coff_seh_pushreg (int what ATTRIBUTE_UNUSED)
 {
   int reg;
 
-  if (!verify_context_and_target (".seh_pushreg", seh_kind_x64))
+  if (!verify_context_and_target (".seh_pushreg", seh_kind_x64)
+      || !seh_validate_seg (".seh_pushreg"))
     return;
 
   reg = seh_x64_read_reg (".seh_pushreg", 1);
@@ -570,7 +586,8 @@ obj_coff_seh_pushreg (int what ATTRIBUTE_UNUSED)
 static void
 obj_coff_seh_pushframe (int what ATTRIBUTE_UNUSED)
 {
-  if (!verify_context_and_target (".seh_pushframe", seh_kind_x64))
+  if (!verify_context_and_target (".seh_pushframe", seh_kind_x64)
+      || !seh_validate_seg (".seh_pushframe"))
     return;
   demand_empty_rest_of_line ();
 
@@ -586,7 +603,8 @@ obj_coff_seh_save (int what)
   int code, reg, scale;
   offsetT off;
 
-  if (!verify_context_and_target (directive, seh_kind_x64))
+  if (!verify_context_and_target (directive, seh_kind_x64)
+      || !seh_validate_seg (directive))
     return;
 
   reg = seh_x64_read_reg (directive, what);
@@ -631,7 +649,8 @@ obj_coff_seh_stackalloc (int what ATTRIBUTE_UNUSED)
   offsetT off;
   int code, info;
 
-  if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64))
+  if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64)
+      || !seh_validate_seg (".seh_stackalloc"))
     return;
 
   off = get_absolute_expression ();
@@ -668,7 +687,8 @@ obj_coff_seh_setframe (int what ATTRIBUTE_UNUSED)
   offsetT off;
   int reg;
 
-  if (!verify_context_and_target (".seh_setframe", seh_kind_x64))
+  if (!verify_context_and_target (".seh_setframe", seh_kind_x64)
+      || !seh_validate_seg (".seh_setframe"))
     return;
 
   reg = seh_x64_read_reg (".seh_setframe", 0);
This page took 0.029427 seconds and 4 git commands to generate.