DWARFv5. Handle DW_TAG_atomic_type _Atomic type modifier.

Message ID 1403432716-8344-1-git-send-email-mjw@redhat.com
State Changes Requested, archived
Headers

Commit Message

Mark Wielaard June 22, 2014, 10:25 a.m. UTC
  This prototype patch matches the experimental patch to GCC:
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01677.html
The same questions apply to this patch:

The following is just a prototype to try out a new qualifier type tag
proposed for DWARFv5. There is not even a draft yet of DWARFv5, so this
is just based on a proposal that might or might not be adopted and/or
changed http://dwarfstd.org/ShowIssue.php?issue=131112.1

Since there is not even a draft of DWARFv5 I don't recommend adopting
this patch. All details may change in the future. I am mainly doing it
to give better feedback on the DWARFv5 proposals (in this case the
feedback would be that it is unfortunate we cannot easily do this as a
vendor extension with DW_TAG_GNU_atomic_type since that would break
backward compatibility). Feedback on the patch is of course still very
welcome.

Is there a recommended way for doing/keeping these kind of speculative
patches? I'll keep a local git branch with my experiments that I'll
rebase against master for larger updates. And would like to send out
new patches to the list for review even if we won't adopt them for now.
But if there is a better way/best practice for this kind of experimental
changes based on just ideas for a next version of a not yet public
standard please let me know.

gdb/ChangeLog

	* c-typeprint.c (cp_type_print_method_args): Handle '_Atomic'.
	(c_type_print_modifier): Likewise.
	* dwarf2read.c (error_check_comp_unit_head): Accept version 5.
	(read_tag_atomic_type): New function.
	(read_type_die_1): Handle DW_TAG_atomic_type.
	* gdbtypes.c (make_atomic_type): New function.
	(recursive_dump_type): Handle TYPE_ATOMIC.
	* gdbtypes.h (enum type_flag_values): Renumber.
	(enum type_instance_flag_value): Add TYPE_INSTANCE_FLAG_ATOMIC.
	(TYPE_ATOMIC): New macro.
	(make_atomic_type): Declare.

gdb/testsuite/ChangeLog

	* gdb.dwarf2/dw2-error.exp: Adjust for new error message.
	* gdb.dwarf2/dw2-atomic.S: New file.
	* gdb.dwarf2/dw2-atomic.c: New file.
	* gdb.dwarf2/dw2-atomic.exp: New file.

include/ChangeLog

	* dwarf2.def: Add DW_TAG_atomic_type.
---
 gdb/ChangeLog                                      |   14 +
 gdb/c-typeprint.c                                  |   11 +
 gdb/dwarf2read.c                                   |   23 ++-
 gdb/gdbtypes.c                                     |   15 +
 gdb/gdbtypes.h                                     |   35 ++-
 gdb/testsuite/ChangeLog                            |    7 +
 gdb/testsuite/gdb.dwarf2/dw2-atomic.S              |  330 ++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dw2-atomic.c              |   28 ++
 .../gdb.dwarf2/{dw2-error.exp => dw2-atomic.exp}   |   27 +-
 gdb/testsuite/gdb.dwarf2/dw2-error.exp             |    2 +-
 include/ChangeLog                                  |    4 +
 include/dwarf2.def                                 |    2 +
 12 files changed, 464 insertions(+), 34 deletions(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-atomic.S
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-atomic.c
 copy gdb/testsuite/gdb.dwarf2/{dw2-error.exp => dw2-atomic.exp} (55%)
  

Comments

Tom Tromey June 23, 2014, 4:27 p.m. UTC | #1
>>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:

Mark> This prototype patch matches the experimental patch to GCC:
Mark> https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01677.html

Thanks, Mark.

Mark> Since there is not even a draft of DWARFv5 I don't recommend adopting
Mark> this patch. All details may change in the future. I am mainly doing it
Mark> to give better feedback on the DWARFv5 proposals (in this case the
Mark> feedback would be that it is unfortunate we cannot easily do this as a
Mark> vendor extension with DW_TAG_GNU_atomic_type since that would break
Mark> backward compatibility).

I don't understand this bit.  It's reasonably normal to add a new GNU tag.

Mark> Is there a recommended way for doing/keeping these kind of
Mark> speculative patches?

Just hosting it on a public git somewhere.  I suppose we could resurrect
archer.git, though there are plenty of hosting services now.

Some nits follow.  The patch looks good overall.

Mark> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
Mark> index ba64256..50bc194 100644
Mark> --- a/gdb/dwarf2read.c
Mark> +++ b/gdb/dwarf2read.c
Mark> @@ -4286,9 +4286,9 @@ error_check_comp_unit_head (struct comp_unit_head *header,
Mark>    bfd *abfd = get_section_bfd_owner (section);
Mark>    const char *filename = get_section_file_name (section);
 
Mark> -  if (header->version != 2 && header->version != 3 && header->version != 4)
Mark> +  if (header->version < 2 || header->version > 5)
Mark>      error (_("Dwarf Error: wrong version in compilation unit header "
Mark> -	   "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
Mark> +	   "(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version,

Normally this should be a separate patch.  For one thing, then it could
go in even if _Atomic doesn't appear in DWARF 5.

Mark> +static struct type *
Mark> +read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)

gdb requires a comment before a new function.

Mark> diff --git a/gdb/testsuite/gdb.dwarf2/dw2-atomic.S b/gdb/testsuite/gdb.dwarf2/dw2-atomic.S

FWIW it's simpler and better to write this using the DWARF assembler in
the test suite.  enum-type.exp is an ok example of the kind of thing
you'd want to do -- just describing a new type and then testing it with
ptype.  Using the DWARF assembler would let you drop the x86-64-only
part of the test.

Mark> diff --git a/gdb/testsuite/gdb.dwarf2/dw2-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-atomic.exp

Hah, this confused me for a while, until I realized that git was
treating it like a copy.

Mark>  # First test that reading symbols fails.
Mark>  gdb_test "file $binfile" \
Mark> -    "Reading symbols.*Dwarf Error: wrong version in compilation unit header .is 153, should be 2, 3, or 4.*" \
Mark> +    "Reading symbols.*Dwarf Error: wrong version in compilation unit header .is 153, should be 2, 3, 4 or 5.*" \
Mark>      "file $testfile"

Should be in the separate DWARF 5 patch.

Tom
  
Mark Wielaard June 23, 2014, 5:06 p.m. UTC | #2
On Mon, 2014-06-23 at 10:27 -0600, Tom Tromey wrote:
> >>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:
> 
> Mark> This prototype patch matches the experimental patch to GCC:
> Mark> https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01677.html
> 
> Thanks, Mark.
> 
> Mark> Since there is not even a draft of DWARFv5 I don't recommend adopting
> Mark> this patch. All details may change in the future. I am mainly doing it
> Mark> to give better feedback on the DWARFv5 proposals (in this case the
> Mark> feedback would be that it is unfortunate we cannot easily do this as a
> Mark> vendor extension with DW_TAG_GNU_atomic_type since that would break
> Mark> backward compatibility).
> 
> I don't understand this bit.  It's reasonably normal to add a new GNU tag.

It is certainly reasonable to add new vendor attributes or tags, but
only for "independent" tags or attributes that consumers can easily
ignore if they aren't recognized. There is no mechanism for introducing
new vendor type qualifier tags like these in DWARF. The issue is that a
consumer cannot detect that a tag is just a type qualifier which can be
ignored if not recognized (all type qualifiers do use DW_AT_type to
point to the underlying type, but so do other non-qualifier tags that
have completely different semantics). So if we would add a vendor tag
and GCC starts annotating/wrapping other type tags with
DW_TAG_GNU_atomic_type then consumers will start failing to find the
underlying type (I already had to patch up various consumers when I
added DW_TAG_restrict_type, which has been standard since DWARFv3). So
if we would introduce a vendor extension to mark atomic types, then it
would have to work differently from the proposed type qualifier tag.

> Mark> Is there a recommended way for doing/keeping these kind of
> Mark> speculative patches?
> 
> Just hosting it on a public git somewhere.  I suppose we could resurrect
> archer.git, though there are plenty of hosting services now.

OK, I can host a repo on my own server or on gitorious. I was just
hoping there was some generic GDB way to host these works in progress,
so others know this is being worked on with the intention of being
merged eventually. I am afraid that if everybody starts hosting their
own repos at various places it will be harder for people to know which
active development is ongoing.

> Some nits follow.  The patch looks good overall.

Thanks. I'll fix the issues and post when I find a good way to host my
repo.

Cheers,

Mark
  
Pedro Alves June 23, 2014, 5:48 p.m. UTC | #3
On 06/23/2014 06:06 PM, Mark Wielaard wrote:
> OK, I can host a repo on my own server or on gitorious. I was just
> hoping there was some generic GDB way to host these works in progress,
> so others know this is being worked on with the intention of being
> merged eventually.

The best is to add a wiki page, and then add a pointer here:

 https://sourceware.org/gdb/wiki/OngoingWork
  
Tom Tromey June 23, 2014, 5:59 p.m. UTC | #4
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> The best is to add a wiki page, and then add a pointer here:
Pedro>  https://sourceware.org/gdb/wiki/OngoingWork

Yeah.  And I think bugzilla works well for smaller things.

Tom
  
Eric Christopher June 23, 2014, 6:01 p.m. UTC | #5
> It is certainly reasonable to add new vendor attributes or tags, but
> only for "independent" tags or attributes that consumers can easily
> ignore if they aren't recognized. There is no mechanism for introducing
> new vendor type qualifier tags like these in DWARF. The issue is that a
> consumer cannot detect that a tag is just a type qualifier which can be
> ignored if not recognized (all type qualifiers do use DW_AT_type to
> point to the underlying type, but so do other non-qualifier tags that
> have completely different semantics). So if we would add a vendor tag
> and GCC starts annotating/wrapping other type tags with
> DW_TAG_GNU_atomic_type then consumers will start failing to find the
> underlying type (I already had to patch up various consumers when I
> added DW_TAG_restrict_type, which has been standard since DWARFv3). So
> if we would introduce a vendor extension to mark atomic types, then it
> would have to work differently from the proposed type qualifier tag.
>

FWIW a new vendor tag, even for such as this, would be a better
solution. The numbers you choose for any attributes, if the proposals
are accepted, would not necessarily be the same ones you chose. That
confusion between numbers in consumers is worse than an unknown tag
IMO.

-eric
  
Mark Wielaard June 23, 2014, 9:33 p.m. UTC | #6
On Mon, 2014-06-23 at 11:01 -0700, Eric Christopher wrote:
> FWIW a new vendor tag, even for such as this, would be a better
> solution. The numbers you choose for any attributes, if the proposals
> are accepted, would not necessarily be the same ones you chose. That
> confusion between numbers in consumers is worse than an unknown tag
> IMO.

Most certainly agreed. I normally work on other DWARF consumers and I
know all too well that whatever GCC/GDB adopts is what the rest of the
toolchain ends up having to support. The goal of the prototype patches
wasn't to get them integrated/adopted before DWARFv5 is finalized. The
goal was just to create something to see if it is doable (both GCC and
GDB seem to have nice datastructures already setup, so even for someone
like me without any prior knowledge of either program it was easy to
add) and give feedback on the proposal to see if it is worth it to adopt
for the next DWARF spec.

I'll think the answer is yes and I'll keep the patches around. So that
if there is a new DWARF standard version then we have an implementation
for the GNU toolchain as soon as it is final. But there isn't even a
first working draft at this point, just a bunch of proposals which might
or might not be adopted in their current or in some completely different
form. So these patches might not be integrated till next year.

For anything that does get integrated into GCC or GDB before DWARFv5 is
final we should certainly use a GNU vendor extension so that the rest of
the toolchain can easily adopt it. But that won't be possible in the
current form since DWARF type qualifier tags aren't vendor extensible.
And I don't know if anybody even needs it right now. Maybe if it is
useful for the GDB/GCC compiler expression effort we could create a GNU
vendor extension?

Cheers,

Mark
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 734b910..6284ad4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@ 
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* c-typeprint.c (cp_type_print_method_args): Handle '_Atomic'.
+	(c_type_print_modifier): Likewise.
+	* dwarf2read.c (error_check_comp_unit_head): Accept version 5.
+	(read_tag_atomic_type): New function.
+	(read_type_die_1): Handle DW_TAG_atomic_type.
+	* gdbtypes.c (make_atomic_type): New function.
+	(recursive_dump_type): Handle TYPE_ATOMIC.
+	* gdbtypes.h (enum type_flag_values): Renumber.
+	(enum type_instance_flag_value): Add TYPE_INSTANCE_FLAG_ATOMIC.
+	(TYPE_ATOMIC): New macro.
+	(make_atomic_type): Declare.
+
 2014-06-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	Fix --with-system-readline with readline-6.3 patch 5.
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 305f92d..72effce 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -272,6 +272,9 @@  cp_type_print_method_args (struct type *mtype, const char *prefix,
 
       if (TYPE_RESTRICT (domain))
 	fprintf_filtered (stream, " restrict");
+
+      if (TYPE_ATOMIC (domain))
+	fprintf_filtered (stream, " _Atomic");
     }
 }
 
@@ -433,6 +436,14 @@  c_type_print_modifier (struct type *type, struct ui_file *stream,
       did_print_modifier = 1;
     }
 
+  if (TYPE_ATOMIC (type))
+    {
+      if (did_print_modifier || need_pre_space)
+	fprintf_filtered (stream, " ");
+      fprintf_filtered (stream, "_Atomic");
+      did_print_modifier = 1;
+    }
+
   address_space_id = address_space_int_to_name (get_type_arch (type),
 						TYPE_INSTANCE_FLAGS (type));
   if (address_space_id)
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ba64256..50bc194 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4286,9 +4286,9 @@  error_check_comp_unit_head (struct comp_unit_head *header,
   bfd *abfd = get_section_bfd_owner (section);
   const char *filename = get_section_file_name (section);
 
-  if (header->version != 2 && header->version != 3 && header->version != 4)
+  if (header->version < 2 || header->version > 5)
     error (_("Dwarf Error: wrong version in compilation unit header "
-	   "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
+	   "(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version,
 	   filename);
 
   if (header->abbrev_offset.sect_off
@@ -14160,6 +14160,22 @@  read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, cv_type, cu);
 }
 
+static struct type *
+read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *base_type, *cv_type;
+
+  base_type = die_type (die, cu);
+
+  /* The die_type call above may have already set the type for this DIE.  */
+  cv_type = get_die_type (die, cu);
+  if (cv_type)
+    return cv_type;
+
+  cv_type = make_atomic_type (base_type);
+  return set_die_type (die, cv_type, cu);
+}
+
 /* Extract all information from a DW_TAG_string_type DIE and add to
    the user defined type vector.  It isn't really a user defined type,
    but it behaves like one, with other DIE's using an AT_user_def_type
@@ -18489,6 +18505,9 @@  read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_module:
       this_type = read_module_type (die, cu);
       break;
+    case DW_TAG_atomic_type:
+      this_type = read_tag_atomic_type (die, cu);
+      break;
     default:
       complaint (&symfile_complaints,
 		 _("unexpected tag in read_type_die: '%s'"),
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index d0c002f..42ff588 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -706,6 +706,17 @@  make_restrict_type (struct type *type)
 			      NULL);
 }
 
+/* Make a '_Atomic'-qualified version of TYPE.  */
+
+struct type *
+make_atomic_type (struct type *type)
+{
+  return make_qualified_type (type,
+			      (TYPE_INSTANCE_FLAGS (type)
+			       | TYPE_INSTANCE_FLAG_ATOMIC),
+			      NULL);
+}
+
 /* Replace the contents of ntype with the type *type.  This changes the
    contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
    the changes are propogated to all types in the TYPE_CHAIN.
@@ -3785,6 +3796,10 @@  recursive_dump_type (struct type *type, int spaces)
     {
       puts_filtered (" TYPE_FLAG_RESTRICT");
     }
+  if (TYPE_ATOMIC (type))
+    {
+      puts_filtered (" TYPE_FLAG_ATOMIC");
+    }
   puts_filtered ("\n");
 
   printfi_filtered (spaces, "flags");
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index bb6352d..03468f8 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -203,18 +203,18 @@  enum type_code
 
 enum type_flag_value
 {
-  TYPE_FLAG_UNSIGNED = (1 << 8),
-  TYPE_FLAG_NOSIGN = (1 << 9),
-  TYPE_FLAG_STUB = (1 << 10),
-  TYPE_FLAG_TARGET_STUB = (1 << 11),
-  TYPE_FLAG_STATIC = (1 << 12),
-  TYPE_FLAG_PROTOTYPED = (1 << 13),
-  TYPE_FLAG_INCOMPLETE = (1 << 14),
-  TYPE_FLAG_VARARGS = (1 << 15),
-  TYPE_FLAG_VECTOR = (1 << 16),
-  TYPE_FLAG_FIXED_INSTANCE = (1 << 17),
-  TYPE_FLAG_STUB_SUPPORTED = (1 << 18),
-  TYPE_FLAG_GNU_IFUNC = (1 << 19),
+  TYPE_FLAG_UNSIGNED = (1 << 9),
+  TYPE_FLAG_NOSIGN = (1 << 10),
+  TYPE_FLAG_STUB = (1 << 11),
+  TYPE_FLAG_TARGET_STUB = (1 << 12),
+  TYPE_FLAG_STATIC = (1 << 13),
+  TYPE_FLAG_PROTOTYPED = (1 << 14),
+  TYPE_FLAG_INCOMPLETE = (1 << 15),
+  TYPE_FLAG_VARARGS = (1 << 16),
+  TYPE_FLAG_VECTOR = (1 << 17),
+  TYPE_FLAG_FIXED_INSTANCE = (1 << 18),
+  TYPE_FLAG_STUB_SUPPORTED = (1 << 19),
+  TYPE_FLAG_GNU_IFUNC = (1 << 20),
 
   /* * Used for error-checking.  */
   TYPE_FLAG_MIN = TYPE_FLAG_UNSIGNED
@@ -233,7 +233,8 @@  enum type_instance_flag_value
   TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1 = (1 << 4),
   TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2 = (1 << 5),
   TYPE_INSTANCE_FLAG_NOTTEXT = (1 << 6),
-  TYPE_INSTANCE_FLAG_RESTRICT = (1 << 7)
+  TYPE_INSTANCE_FLAG_RESTRICT = (1 << 7),
+  TYPE_INSTANCE_FLAG_ATOMIC = (1 << 8)
 };
 
 /* * Unsigned integer type.  If this is not set for a TYPE_CODE_INT,
@@ -365,6 +366,12 @@  enum type_instance_flag_value
 #define TYPE_RESTRICT(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_RESTRICT)
 
+/* * Atomic type.  If this is set, the corresponding type has an
+   _Atomic modifier.  */
+
+#define TYPE_ATOMIC(t) \
+  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -1627,6 +1634,8 @@  extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
 extern struct type *make_restrict_type (struct type *);
 
+extern struct type *make_atomic_type (struct type *);
+
 extern void replace_type (struct type *, struct type *);
 
 extern int address_space_name_to_int (struct gdbarch *, char *);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 1e7ef7f..f44881f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@ 
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* gdb.dwarf2/dw2-error.exp: Adjust for new error message.
+	* gdb.dwarf2/dw2-atomic.S: New file.
+	* gdb.dwarf2/dw2-atomic.c: New file.
+	* gdb.dwarf2/dw2-atomic.exp: New file.
+
 2014-06-20  Gary Benson  <gbenson@redhat.com>
 
 	* gdb.arch/i386-avx.exp: Fix include file location.
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-atomic.S b/gdb/testsuite/gdb.dwarf2/dw2-atomic.S
new file mode 100644
index 0000000..17e7b3d
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-atomic.S
@@ -0,0 +1,330 @@ 
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   This was created using gcc -S -std=c11 -gdwarf-5 dw2-atomic.c.
+
+  */
+
+	.file	"dw2-atomic.c"
+	.text
+.Ltext0:
+	.globl	f
+	.type	f, @function
+f:
+.LFB0:
+	.file 1 "dw2-atomic.c"
+	.loc 1 19 0
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	movq	%rdi, -24(%rbp)
+	.loc 1 20 0
+	movq	-24(%rbp), %rax
+	movzbl	(%rax), %eax
+	movb	%al, -1(%rbp)
+	movzbl	-1(%rbp), %eax
+	movsbl	%al, %eax
+	.loc 1 21 0
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	f, .-f
+	.comm	hipsters,8,8
+	.globl	main
+	.type	main, @function
+main:
+.LFB1:
+	.loc 1 26 0
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	subq	$16, %rsp
+	.loc 1 27 0
+	movq	hipsters(%rip), %rax
+	movq	%rax, -8(%rbp)
+	movq	-8(%rbp), %rax
+	movq	%rax, %rdi
+	call	f
+	.loc 1 28 0
+	leave
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	main, .-main
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0xb0
+	.value	0x5
+	.long	.Ldebug_abbrev0
+	.byte	0x8
+	.uleb128 0x1
+	.long	.LASF1
+	.byte	0x1
+	.long	.LASF2
+	.long	.LASF3
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.long	.Ldebug_line0
+	.uleb128 0x2
+	.string	"f"
+	.byte	0x1
+	.byte	0x12
+	.long	0x59
+	.quad	.LFB0
+	.quad	.LFE0-.LFB0
+	.uleb128 0x1
+	.byte	0x9c
+	.long	0x59
+	.uleb128 0x3
+	.string	"x"
+	.byte	0x1
+	.byte	0x12
+	.long	0x60
+	.uleb128 0x2
+	.byte	0x91
+	.sleb128 -40
+	.byte	0
+	.uleb128 0x4
+	.byte	0x4
+	.byte	0x5
+	.string	"int"
+	.uleb128 0x5
+	.long	0x65
+	.uleb128 0x6
+	.long	0x6a
+	.uleb128 0x7
+	.byte	0x8
+	.long	0x70
+	.uleb128 0x5
+	.long	0x75
+	.uleb128 0x8
+	.long	0x7a
+	.uleb128 0x9
+	.byte	0x1
+	.byte	0x6
+	.long	.LASF0
+	.uleb128 0xa
+	.long	.LASF4
+	.byte	0x1
+	.byte	0x19
+	.long	0x59
+	.quad	.LFB1
+	.quad	.LFE1-.LFB1
+	.uleb128 0x1
+	.byte	0x9c
+	.uleb128 0xb
+	.long	.LASF5
+	.byte	0x1
+	.byte	0x17
+	.long	0x60
+	.uleb128 0x9
+	.byte	0x3
+	.quad	hipsters
+	.byte	0
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0xe
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x10
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0x1
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x27
+	.uleb128 0x19
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x40
+	.uleb128 0x18
+	.uleb128 0x2117
+	.uleb128 0x19
+	.uleb128 0x1
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x5
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x18
+	.byte	0
+	.byte	0
+	.uleb128 0x4
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.byte	0
+	.byte	0
+	.uleb128 0x5
+	.uleb128 0x47
+	.byte	0
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x6
+	.uleb128 0x35
+	.byte	0
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x7
+	.uleb128 0xf
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x8
+	.uleb128 0x26
+	.byte	0
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x9
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.byte	0
+	.byte	0
+	.uleb128 0xa
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x40
+	.uleb128 0x18
+	.uleb128 0x2116
+	.uleb128 0x19
+	.byte	0
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0x34
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x2
+	.uleb128 0x18
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_aranges,"",@progbits
+	.long	0x2c
+	.value	0x2
+	.long	.Ldebug_info0
+	.byte	0x8
+	.byte	0
+	.value	0
+	.value	0
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.quad	0
+	.quad	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF2:
+	.string	"dw2-atomic.c"
+.LASF4:
+	.string	"main"
+.LASF3:
+	.string	"/home/mark/src/binutils-gdb/gdb/testsuite/gdb.dwarf2"
+.LASF5:
+	.string	"hipsters"
+.LASF0:
+	.string	"char"
+.LASF1:
+	.string	"GNU C 4.10.0 20140618 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -std=c11"
+	.ident	"GCC: (GNU) 4.10.0 20140618 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-atomic.c b/gdb/testsuite/gdb.dwarf2/dw2-atomic.c
new file mode 100644
index 0000000..a22513b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-atomic.c
@@ -0,0 +1,28 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int f (const _Atomic char * volatile _Atomic x)
+{
+  return x[0];
+}
+
+_Atomic const char * _Atomic volatile hipsters;
+
+int main()
+{
+  return f(hipsters);
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-atomic.exp
similarity index 55%
copy from gdb/testsuite/gdb.dwarf2/dw2-error.exp
copy to gdb/testsuite/gdb.dwarf2/dw2-atomic.exp
index 65eac6d..43c7db5 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-error.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-atomic.exp
@@ -1,4 +1,4 @@ 
-# Copyright 2012-2014 Free Software Foundation, Inc.
+# Copyright 2014 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -17,27 +17,18 @@  load_lib dwarf.exp
 
 # This test can only be run on targets which support DWARF-2 and use gas.
 if {![dwarf2_support]} {
-    return 0  
+    return 0
+}
+
+# This test can only be run on x86-64 targets.
+if {![istarget x86_64-*] || ![is_lp64_target]} {
+    return 0
 }
 
 standard_testfile .S
 
-# We can't use prepare_for_testing here because we need to check the
-# 'file' command's output.
-if {[build_executable $testfile.exp $testfile $srcfile {nodebug}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {nodebug}]} {
     return -1
 }
 
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-
-gdb_test_no_output "set breakpoint pending off"
-
-# First test that reading symbols fails.
-gdb_test "file $binfile" \
-    "Reading symbols.*Dwarf Error: wrong version in compilation unit header .is 153, should be 2, 3, or 4.*" \
-    "file $testfile"
-
-# Now check that we can still break given the minimal symbol.
-gdb_test "break main" "Breakpoint $decimal.*"
+gdb_test "ptype f" "int \\(const _Atomic char \\\* volatile _Atomic\\)"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-error.exp
index 65eac6d..260765e 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-error.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-error.exp
@@ -36,7 +36,7 @@  gdb_test_no_output "set breakpoint pending off"
 
 # First test that reading symbols fails.
 gdb_test "file $binfile" \
-    "Reading symbols.*Dwarf Error: wrong version in compilation unit header .is 153, should be 2, 3, or 4.*" \
+    "Reading symbols.*Dwarf Error: wrong version in compilation unit header .is 153, should be 2, 3, 4 or 5.*" \
     "file $testfile"
 
 # Now check that we can still break given the minimal symbol.
diff --git a/include/ChangeLog b/include/ChangeLog
index 96ae31d..23f27a9 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@ 
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf2.def: Add DW_TAG_atomic_type.
+
 2014-06-13  Alan Modra  <amodra@gmail.com>
 
 	* bfdlink.h (struct bfd_link_hash_table): Add hash_table_free field.
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 71a37b3..6941922 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -133,6 +133,8 @@  DW_TAG (DW_TAG_shared_type, 0x40)
 DW_TAG (DW_TAG_type_unit, 0x41)
 DW_TAG (DW_TAG_rvalue_reference_type, 0x42)
 DW_TAG (DW_TAG_template_alias, 0x43)
+/* DWARF 5.  */
+DW_TAG (DW_TAG_atomic_type, 0x47)
 
 DW_TAG_DUP (DW_TAG_lo_user, 0x4080)
 DW_TAG_DUP (DW_TAG_hi_user, 0xffff)