aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/obj-coff-seh.c170
-rw-r--r--gas/config/obj-coff-seh.h2
-rw-r--r--gas/testsuite/ChangeLog8
-rwxr-xr-xgas/testsuite/gas/pe/pe.exp3
-rw-r--r--gas/testsuite/gas/pe/peseh-x64-4.d7
-rw-r--r--gas/testsuite/gas/pe/peseh-x64-4.s564
-rw-r--r--gas/testsuite/gas/pe/peseh-x64-5.d10
-rw-r--r--gas/testsuite/gas/pe/peseh-x64-6.d10
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/scripttempl/pep.sc7
11 files changed, 765 insertions, 27 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fb08c90..6f5aa0c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2010-09-15 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/obj-coff-seh.h (seh_context): New member code_seg.
+ * config/obj-coff-seh.c: Implementing xdata/pdata section cloning
+ for link-once code-segment.
+
2010-09-14 Jie Zhang <jie@codesourcery.com>
* doc/c-arm.texi: Document -mcpu=cortex-m4.
diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c
index d2d01b1..6c3fe7c 100644
--- a/gas/config/obj-coff-seh.c
+++ b/gas/config/obj-coff-seh.c
@@ -22,42 +22,153 @@
#include "obj-coff-seh.h"
+/* Private segment collection list. */
+struct seh_seg_list {
+ segT seg;
+ int subseg;
+ char *seg_name;
+};
+
/* Local data. */
static seh_context *seh_ctx_cur = NULL;
-static segT xdata_seg;
-static segT pdata_seg;
-static int xdata_subseg;
+static struct hash_control *seh_hash;
+
+static struct seh_seg_list *x_segcur = NULL;
+static struct seh_seg_list *p_segcur = NULL;
static void write_function_xdata (seh_context *);
static void write_function_pdata (seh_context *);
-static void
-switch_xdata (int subseg)
+/* Build based on segment the derived .pdata/.xdata
+ segment name containing origin segment's postfix name part. */
+static char *
+get_pxdata_name (segT seg, const char *base_name)
{
- if (xdata_seg == NULL)
- {
- xdata_seg = subseg_new (".xdata", 0);
- bfd_set_section_flags (stdoutput, xdata_seg,
- ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
- & bfd_applicable_section_flags (stdoutput)));
- }
- subseg_set (xdata_seg, subseg);
+ const char *name,*dollar, *dot;
+ char *sname;
+
+ name = bfd_get_section_name (stdoutput, seg);
+
+ dollar = strchr (name, '$');
+ dot = strchr (name + 1, '.');
+
+ if (!dollar && !dot)
+ name = "";
+ else if (!dollar)
+ name = dot;
+ else if (!dot)
+ name = dollar;
+ else if (dot < dollar)
+ name = dot;
+ else
+ name = dollar;
+
+ sname = concat (base_name, name, NULL);
+
+ return sname;
+}
+
+/* Allocate a seh_seg_list structure. */
+static struct seh_seg_list *
+alloc_pxdata_item (segT seg, int subseg, char *name)
+{
+ struct seh_seg_list *r;
+
+ r = (struct seh_seg_list *)
+ xmalloc (sizeof (struct seh_seg_list) + strlen (name));
+ r->seg = seg;
+ r->subseg = subseg;
+ r->seg_name = name;
+ return r;
+}
+
+/* Generate pdata/xdata segment with same linkonce properties
+ of based segment. */
+static segT
+make_pxdata_seg (segT cseg, char *name)
+{
+ segT save_seg = now_seg;
+ int save_subseg = now_subseg;
+ segT r;
+ flagword flags;
+
+ 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);
+
+ /* 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))
+ as_bad (_("bfd_set_section_flags: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ /* Restore to previous segment. */
+ subseg_set (save_seg, save_subseg);
+ return r;
}
static void
-switch_pdata (void)
+seh_hash_insert (const char *name, struct seh_seg_list *item)
+{
+ const char *error_string;
+
+ if ((error_string = hash_jam (seh_hash, name, (char *) item)))
+ as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
+ name, error_string);
+}
+
+static struct seh_seg_list *
+seh_hash_find (char *name)
{
- if (pdata_seg == NULL)
+ return (struct seh_seg_list *) hash_find (seh_hash, name);
+}
+
+static struct seh_seg_list *
+seh_hash_find_or_make (segT cseg, const char *base_name)
+{
+ struct seh_seg_list *item;
+ char *name;
+
+ /* Initialize seh_hash once. */
+ if (!seh_hash)
+ seh_hash = hash_new ();
+
+ name = get_pxdata_name (cseg, base_name);
+
+ item = seh_hash_find (name);
+ if (!item)
{
- pdata_seg = subseg_new (".pdata", 0);
- bfd_set_section_flags (stdoutput, pdata_seg,
- ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
- & bfd_applicable_section_flags (stdoutput)));
+ item = alloc_pxdata_item (make_pxdata_seg (cseg, name), 0, name);
+
+ seh_hash_insert (item->seg_name, item);
}
else
- subseg_set (pdata_seg, 0);
+ free (name);
+
+ return item;
+}
+
+static void
+switch_xdata (int subseg, segT code_seg)
+{
+ x_segcur = seh_hash_find_or_make (code_seg, ".xdata");
+
+ subseg_set (x_segcur->seg, subseg);
+}
+
+static void
+switch_pdata (segT code_seg)
+{
+ p_segcur = seh_hash_find_or_make (code_seg, ".pdata");
+
+ subseg_set (p_segcur->seg, p_segcur->subseg);
}
/* Parsing routines. */
@@ -260,7 +371,7 @@ obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED)
return;
demand_empty_rest_of_line ();
- switch_xdata (seh_ctx_cur->subsection + 1);
+ switch_xdata (seh_ctx_cur->subsection + 1, seh_ctx_cur->code_seg);
}
/* Mark end of current context. */
@@ -311,10 +422,13 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED)
seh_ctx_cur = XCNEW (seh_context);
+ seh_ctx_cur->code_seg = now_seg;
+
if (seh_get_target_kind () == seh_kind_x64)
{
- seh_ctx_cur->subsection = xdata_subseg;
- xdata_subseg += 2;
+ x_segcur = seh_hash_find_or_make (seh_ctx_cur->code_seg, ".xdata");
+ seh_ctx_cur->subsection = x_segcur->subseg;
+ x_segcur->subseg += 2;
}
SKIP_WHITESPACE ();
@@ -766,7 +880,7 @@ write_function_xdata (seh_context *c)
if (seh_get_target_kind () != seh_kind_x64)
return;
- switch_xdata (c->subsection);
+ switch_xdata (c->subsection, c->code_seg);
seh_x64_write_function_xdata (c);
@@ -832,8 +946,8 @@ write_function_pdata (seh_context *c)
expressionS exp;
segT save_seg = now_seg;
int save_subseg = now_subseg;
-
- switch_pdata ();
+ memset (&exp, 0, sizeof (expressionS));
+ switch_pdata (c->code_seg);
switch (seh_get_target_kind ())
{
@@ -843,8 +957,12 @@ write_function_pdata (seh_context *c)
exp.X_add_symbol = c->start_addr;
emit_expr (&exp, 4);
+ exp.X_op = O_symbol_rva;
+ exp.X_add_number = 0;
exp.X_add_symbol = c->end_addr;
emit_expr (&exp, 4);
+ exp.X_op = O_symbol_rva;
+ exp.X_add_number = 0;
exp.X_add_symbol = c->xdata_addr;
emit_expr (&exp, 4);
break;
diff --git a/gas/config/obj-coff-seh.h b/gas/config/obj-coff-seh.h
index 429c100..22267be 100644
--- a/gas/config/obj-coff-seh.h
+++ b/gas/config/obj-coff-seh.h
@@ -90,6 +90,8 @@ typedef struct seh_context
{
struct seh_context *next;
+ /* Initial code-segment. */
+ segT code_seg;
/* Function name. */
char *func_name;
/* BeginAddress. */
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 2af2d3c..126b881 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2010-09-15 Kai Tietz <kai.tietz@onevision.com>
+
+ * gas/pe/pe.exp: Add peseh-x64-4,5,6 tests.
+ * gas/pe/peseh-x64-4.s: New.
+ * gas/pe/peseh-x64-4.d: New.
+ * gas/pe/peseh-x64-5.d: New.
+ * gas/pe/peseh-x64-6.d: New.
+
2010-09-14 Maciej W. Rozycki <macro@codesourcery.com>
* gas/mips/mips32r2-sync.d: New test for MIPS32r2 "sync"
diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp
index 8982719..6e6063c 100755
--- a/gas/testsuite/gas/pe/pe.exp
+++ b/gas/testsuite/gas/pe/pe.exp
@@ -44,4 +44,7 @@ if ([istarget "x86_64-*-mingw*"]) then {
run_dump_test "peseh-x64"
run_dump_test "peseh-x64-2"
run_dump_test "peseh-x64-3"
+ run_dump_test "peseh-x64-4"
+ run_dump_test "peseh-x64-5"
+ run_dump_test "peseh-x64-6"
}
diff --git a/gas/testsuite/gas/pe/peseh-x64-4.d b/gas/testsuite/gas/pe/peseh-x64-4.d
new file mode 100644
index 0000000..adc73f9
--- /dev/null
+++ b/gas/testsuite/gas/pe/peseh-x64-4.d
@@ -0,0 +1,7 @@
+#objdump: -s -j .xdata\$_ZN5VBase1fEv
+#name: PE x64 SEH test named sections
+
+.*: .*
+
+Contents of section .xdata\$_ZN5VBase1fEv:
+ 0000 01040205 04030150 .*
diff --git a/gas/testsuite/gas/pe/peseh-x64-4.s b/gas/testsuite/gas/pe/peseh-x64-4.s
new file mode 100644
index 0000000..d412cff
--- /dev/null
+++ b/gas/testsuite/gas/pe/peseh-x64-4.s
@@ -0,0 +1,564 @@
+ .file "t4.C"
+ .section .text$_ZN5VBase1fEv,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN5VBase1fEv
+ .def _ZN5VBase1fEv; .scl 2; .type 32; .endef
+ .seh_proc _ZN5VBase1fEv
+_ZN5VBase1fEv:
+.LFB0:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ nop
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN10StreamBaseD2Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN10StreamBaseD2Ev
+ .def _ZN10StreamBaseD2Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN10StreamBaseD2Ev
+_ZN10StreamBaseD2Ev:
+.LFB2:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq 16(%rbp), %rax
+ leaq 16+_ZTV10StreamBase(%rip), %rdx
+ movq %rdx, (%rax)
+ movl $0, %eax
+ andl $1, %eax
+ testb %al, %al
+ je .L2
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+.L2:
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN10StreamBaseD1Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN10StreamBaseD1Ev
+ .def _ZN10StreamBaseD1Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN10StreamBaseD1Ev
+_ZN10StreamBaseD1Ev:
+.LFB3:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq 16(%rbp), %rax
+ leaq 16+_ZTV10StreamBase(%rip), %rdx
+ movq %rdx, (%rax)
+ movl $2, %eax
+ andl $1, %eax
+ testb %al, %al
+ je .L5
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+.L5:
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN10StreamBaseD0Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN10StreamBaseD0Ev
+ .def _ZN10StreamBaseD0Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN10StreamBaseD0Ev
+_ZN10StreamBaseD0Ev:
+.LFB4:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq 16(%rbp), %rcx
+ call _ZN10StreamBaseD1Ev
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN6StreamD2Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN6StreamD2Ev
+ .def _ZN6StreamD2Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN6StreamD2Ev
+_ZN6StreamD2Ev:
+.LFB6:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq %rdx, 24(%rbp)
+ movq 24(%rbp), %rax
+ movq (%rax), %rdx
+ movq 16(%rbp), %rax
+ movq %rdx, (%rax)
+ movq 16(%rbp), %rax
+ movq (%rax), %rax
+ subq $24, %rax
+ movq (%rax), %rax
+ addq 16(%rbp), %rax
+ movq 24(%rbp), %rdx
+ addq $8, %rdx
+ movq (%rdx), %rdx
+ movq %rdx, (%rax)
+ movq 16(%rbp), %rcx
+ call _ZN10StreamBaseD2Ev
+ movl $0, %eax
+ andl $2, %eax
+ testl %eax, %eax
+ je .L11
+ movq 16(%rbp), %rax
+ addq $8, %rax
+ movq %rax, %rcx
+ call _ZN5VBaseD2Ev
+.L11:
+ movl $0, %eax
+ andl $1, %eax
+ testb %al, %al
+ je .L10
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+.L10:
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN6StreamD1Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN6StreamD1Ev
+ .def _ZN6StreamD1Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN6StreamD1Ev
+_ZN6StreamD1Ev:
+.LFB7:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ leaq 24+_ZTV6Stream(%rip), %rdx
+ movq 16(%rbp), %rax
+ movq %rdx, (%rax)
+ movl $8, %eax
+ addq 16(%rbp), %rax
+ leaq 64+_ZTV6Stream(%rip), %rdx
+ movq %rdx, (%rax)
+ movq 16(%rbp), %rcx
+ call _ZN10StreamBaseD2Ev
+ movl $2, %eax
+ andl $2, %eax
+ testl %eax, %eax
+ je .L14
+ movq 16(%rbp), %rax
+ addq $8, %rax
+ movq %rax, %rcx
+ call _ZN5VBaseD2Ev
+.L14:
+ movl $2, %eax
+ andl $1, %eax
+ testb %al, %al
+ je .L13
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+.L13:
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .section .text$_ZN6StreamD0Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN6StreamD0Ev
+ .def _ZN6StreamD0Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN6StreamD0Ev
+_ZN6StreamD0Ev:
+.LFB8:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq 16(%rbp), %rcx
+ call _ZN6StreamD1Ev
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .globl r
+ .bss
+ .align 4
+r:
+ .space 4
+ .section .text$_ZN13DerivedStreamD1Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN13DerivedStreamD1Ev
+ .def _ZN13DerivedStreamD1Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN13DerivedStreamD1Ev
+_ZN13DerivedStreamD1Ev:
+.LFB12:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ pushq %rbx
+ .seh_pushreg %rbx
+ subq $40, %rsp
+ .seh_stackalloc 40
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ leaq 24+_ZTV13DerivedStream(%rip), %rdx
+ movq 16(%rbp), %rax
+ movq %rdx, (%rax)
+ movl $8, %eax
+ addq 16(%rbp), %rax
+ leaq 64+_ZTV13DerivedStream(%rip), %rdx
+ movq %rdx, (%rax)
+ leaq _ZTT13DerivedStream(%rip), %rax
+ addq $8, %rax
+ movq %rax, %rdx
+ movq 16(%rbp), %rcx
+.LEHB0:
+ call _ZN6StreamD2Ev
+.LEHE0:
+ movl $2, %eax
+ andl $2, %eax
+ testl %eax, %eax
+ je .L19
+ movq 16(%rbp), %rax
+ addq $8, %rax
+ movq %rax, %rcx
+.LEHB1:
+ call _ZN5VBaseD2Ev
+.LEHE1:
+.L19:
+ movl $2, %eax
+ andl $1, %eax
+ testb %al, %al
+ je .L18
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+ jmp .L18
+.L23:
+ movq %rax, %rbx
+ movl $2, %eax
+ andl $2, %eax
+ testl %eax, %eax
+ je .L22
+ movq 16(%rbp), %rax
+ addq $8, %rax
+ movq %rax, %rcx
+ call _ZN5VBaseD2Ev
+.L22:
+ movq %rbx, %rax
+ movq %rax, %rcx
+.LEHB2:
+ call _Unwind_Resume
+ nop
+.LEHE2:
+.L18:
+ nop
+ addq $40, %rsp
+ popq %rbx
+ popq %rbp
+ ret
+ .def __gxx_personality_v0; .scl 2; .type 32; .endef
+ .seh_handler _GCC_specific_handler, @unwind, @except
+ .seh_handlerdata
+ .rva __gxx_personality_v0
+ .section .text$_ZN13DerivedStreamD1Ev,"x"
+ .linkonce discard
+ .seh_handlerdata
+.LLSDA12:
+ .byte 0xff
+ .byte 0xff
+ .byte 0x1
+ .uleb128 .LLSDACSE12-.LLSDACSB12
+.LLSDACSB12:
+ .uleb128 .LEHB0-.LFB12
+ .uleb128 .LEHE0-.LEHB0
+ .uleb128 .L23-.LFB12
+ .uleb128 0
+ .uleb128 .LEHB1-.LFB12
+ .uleb128 .LEHE1-.LEHB1
+ .uleb128 0
+ .uleb128 0
+ .uleb128 .LEHB2-.LFB12
+ .uleb128 .LEHE2-.LEHB2
+ .uleb128 0
+ .uleb128 0
+.LLSDACSE12:
+ .section .text$_ZN13DerivedStreamD1Ev,"x"
+ .linkonce discard
+ .seh_endproc
+ .section .text$_ZN13DerivedStreamD0Ev,"x"
+ .linkonce discard
+ .align 2
+ .globl _ZN13DerivedStreamD0Ev
+ .def _ZN13DerivedStreamD0Ev; .scl 2; .type 32; .endef
+ .seh_proc _ZN13DerivedStreamD0Ev
+_ZN13DerivedStreamD0Ev:
+.LFB13:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
+ .seh_endprologue
+ movq %rcx, 16(%rbp)
+ movq 16(%rbp), %rcx
+ call _ZN13DerivedStreamD1Ev
+ movq 16(%rbp), %rcx
+ call _ZdlPv
+ nop
+ addq $32, %rsp
+ popq %rbp
+ ret
+ .seh_endproc
+ .text
+ .globl _Z7ctor2_xv
+ .def _Z7ctor2_xv; .scl 2; .type 32; .endef
+ .seh_proc _Z7ctor2_xv
+_Z7ctor2_xv:
+.LFB9:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $48, %rsp
+ .seh_stackalloc 48
+ .seh_endprologue
+ leaq -16(%rbp), %rax
+ movq %rax, %rcx
+.LEHB3:
+ call _ZN13DerivedStreamC1Ev
+ leaq -16(%rbp), %rax
+ movq %rax, %rcx
+ call _ZN13DerivedStreamD1Ev
+.LEHE3:
+.L29:
+ movl r(%rip), %eax
+ testl %eax, %eax
+ je .L27
+.LEHB4:
+ call abort
+ nop
+.L27:
+ movl $0, %ecx
+ call exit
+ nop
+.L30:
+ movq %rax, %rcx
+ call __cxa_begin_catch
+ call __cxa_end_catch
+.LEHE4:
+ jmp .L29
+ .seh_handler _GCC_specific_handler, @unwind, @except
+ .seh_handlerdata
+ .rva __gxx_personality_v0
+ .text
+ .seh_handlerdata
+ .align 4
+.LLSDA9:
+ .byte 0xff
+ .byte 0x9b
+ .uleb128 .LLSDATT9-.LLSDATTD9
+.LLSDATTD9:
+ .byte 0x1
+ .uleb128 .LLSDACSE9-.LLSDACSB9
+.LLSDACSB9:
+ .uleb128 .LEHB3-.LFB9
+ .uleb128 .LEHE3-.LEHB3
+ .uleb128 .L30-.LFB9
+ .uleb128 0x1
+ .uleb128 .LEHB4-.LFB9
+ .uleb128 .LEHE4-.LEHB4
+ .uleb128 0
+ .uleb128 0
+.LLSDACSE9:
+ .byte 0x1
+ .byte 0
+ .align 4
+ .long 0
+
+.LLSDATT9:
+ .text
+ .seh_endproc
+ .globl _ZTV13DerivedStream
+ .section .data$_ZTV13DerivedStream,"w"
+ .linkonce same_size
+ .align 32
+_ZTV13DerivedStream:
+ .quad 8
+ .quad 0
+ .quad _ZTI13DerivedStream
+ .quad _ZN13DerivedStreamD1Ev
+ .quad _ZN13DerivedStreamD0Ev
+ .quad 0
+ .quad -8
+ .quad _ZTI13DerivedStream
+ .quad _ZN5VBase1fEv
+ .globl _ZTT13DerivedStream
+ .section .data$_ZTT13DerivedStream,"w"
+ .linkonce same_size
+ .align 32
+_ZTT13DerivedStream:
+ .quad _ZTV13DerivedStream+24
+ .quad _ZTC13DerivedStream0_6Stream+24
+ .quad _ZTC13DerivedStream0_6Stream+64
+ .quad _ZTV13DerivedStream+64
+ .globl _ZTC13DerivedStream0_6Stream
+ .section .data$_ZTC13DerivedStream0_6Stream,"w"
+ .linkonce same_size
+ .align 32
+_ZTC13DerivedStream0_6Stream:
+ .quad 8
+ .quad 0
+ .quad _ZTI6Stream
+ .quad _ZN6StreamD1Ev
+ .quad _ZN6StreamD0Ev
+ .quad 0
+ .quad -8
+ .quad _ZTI6Stream
+ .quad _ZN5VBase1fEv
+ .globl _ZTV6Stream
+ .section .data$_ZTV6Stream,"w"
+ .linkonce same_size
+ .align 32
+_ZTV6Stream:
+ .quad 8
+ .quad 0
+ .quad _ZTI6Stream
+ .quad _ZN6StreamD1Ev
+ .quad _ZN6StreamD0Ev
+ .quad 0
+ .quad -8
+ .quad _ZTI6Stream
+ .quad _ZN5VBase1fEv
+ .globl _ZTT6Stream
+ .section .data$_ZTT6Stream,"w"
+ .linkonce same_size
+ .align 16
+_ZTT6Stream:
+ .quad _ZTV6Stream+24
+ .quad _ZTV6Stream+64
+ .globl _ZTV10StreamBase
+ .section .data$_ZTV10StreamBase,"w"
+ .linkonce same_size
+ .align 32
+_ZTV10StreamBase:
+ .quad 0
+ .quad _ZTI10StreamBase
+ .quad _ZN10StreamBaseD1Ev
+ .quad _ZN10StreamBaseD0Ev
+ .globl _ZTS13DerivedStream
+ .section .rdata$_ZTS13DerivedStream,"dr"
+ .linkonce same_size
+ .align 16
+_ZTS13DerivedStream:
+ .ascii "13DerivedStream\0"
+ .globl _ZTI13DerivedStream
+ .section .data$_ZTI13DerivedStream,"w"
+ .linkonce same_size
+ .align 16
+_ZTI13DerivedStream:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS13DerivedStream
+ .quad _ZTI6Stream
+ .globl _ZTS6Stream
+ .section .rdata$_ZTS6Stream,"dr"
+ .linkonce same_size
+_ZTS6Stream:
+ .ascii "6Stream\0"
+ .globl _ZTI6Stream
+ .section .data$_ZTI6Stream,"w"
+ .linkonce same_size
+ .align 32
+_ZTI6Stream:
+ .quad _ZTVN10__cxxabiv121__vmi_class_type_infoE+16
+ .quad _ZTS6Stream
+ .long 0
+ .long 2
+ .quad _ZTI5VBase
+ .long -6141
+ .space 4
+ .quad _ZTI10StreamBase
+ .long 2
+ .space 4
+ .globl _ZTS10StreamBase
+ .section .rdata$_ZTS10StreamBase,"dr"
+ .linkonce same_size
+_ZTS10StreamBase:
+ .ascii "10StreamBase\0"
+ .globl _ZTI10StreamBase
+ .section .data$_ZTI10StreamBase,"w"
+ .linkonce same_size
+ .align 16
+_ZTI10StreamBase:
+ .quad _ZTVN10__cxxabiv117__class_type_infoE+16
+ .quad _ZTS10StreamBase
+ .globl _ZTS5VBase
+ .section .rdata$_ZTS5VBase,"dr"
+ .linkonce same_size
+_ZTS5VBase:
+ .ascii "5VBase\0"
+ .globl _ZTI5VBase
+ .section .data$_ZTI5VBase,"w"
+ .linkonce same_size
+ .align 16
+_ZTI5VBase:
+ .quad _ZTVN10__cxxabiv117__class_type_infoE+16
+ .quad _ZTS5VBase
+ .def _ZdlPv; .scl 2; .type 32; .endef
+ .def _ZN5VBaseD2Ev; .scl 2; .type 32; .endef
+ .def _Unwind_Resume; .scl 2; .type 32; .endef
+ .def _ZN13DerivedStreamC1Ev; .scl 2; .type 32; .endef
+ .def abort; .scl 2; .type 32; .endef
+ .def exit; .scl 2; .type 32; .endef
+ .def __cxa_begin_catch; .scl 2; .type 32; .endef
+ .def __cxa_end_catch; .scl 2; .type 32; .endef
diff --git a/gas/testsuite/gas/pe/peseh-x64-5.d b/gas/testsuite/gas/pe/peseh-x64-5.d
new file mode 100644
index 0000000..430b902
--- /dev/null
+++ b/gas/testsuite/gas/pe/peseh-x64-5.d
@@ -0,0 +1,10 @@
+#source: peseh-x64-4.s
+#objdump: -h -j .xdata\$_ZN5VBase1fEv
+#name: PE x64 SEH test sections flags xdata
+
+.*: .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 4 .xdata\$_ZN5VBase1fEv 00000008 0000000000000000 0000000000000000 000007a4 2\*\*2
+ CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_DISCARD
diff --git a/gas/testsuite/gas/pe/peseh-x64-6.d b/gas/testsuite/gas/pe/peseh-x64-6.d
new file mode 100644
index 0000000..f76c2fb
--- /dev/null
+++ b/gas/testsuite/gas/pe/peseh-x64-6.d
@@ -0,0 +1,10 @@
+#source: peseh-x64-4.s
+#objdump: -h -j .pdata\$_ZN5VBase1fEv
+#name: PE x64 SEH test sections flags pdata
+
+.*: .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 5 .pdata\$_ZN5VBase1fEv 0000000c 0000000000000000 0000000000000000 000007ac 2\*\*2
+ CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA, LINK_ONCE_DISCARD
diff --git a/ld/ChangeLog b/ld/ChangeLog
index ef96de5..c905d86 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2010-09-15 Kai Tietz <kai.tietz@onevision.com>
+
+ * scripttempl/pep.sc: Add .xdata segment and
+ put into .pdata all segments beginning with .pdata.
+
2010-09-10 Alan Modra <amodra@gmail.com>
PR ld/11931
diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc
index 7134a4e..75abc9f 100644
--- a/ld/scripttempl/pep.sc
+++ b/ld/scripttempl/pep.sc
@@ -118,7 +118,12 @@ SECTIONS
.pdata ${RELOCATING+BLOCK(__section_alignment__)} :
{
- *(.pdata)
+ *(.pdata*)
+ }
+
+ .xdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.xdata*)
}
.bss ${RELOCATING+BLOCK(__section_alignment__)} :