/* 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.
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, '.');
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 ()));
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)
{
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;
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);
{
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;
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));
}
as_bad (_(".seh_endproc used without .seh_proc"));
return;
}
-
+ seh_validate_seg (".seh_endproc");
do_seh_endproc ();
}
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 ();
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 ();
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). */
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))
{
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);
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 ();
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);
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 ();
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);