public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-10-10 21:30 Josh Stone
  0 siblings, 0 replies; 8+ messages in thread
From: Josh Stone @ 2014-10-10 21:30 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 2314 bytes --]

On 10/10/2014 11:42 AM, Roland McGrath wrote:
> The description in your prologue and the libdw.h comment do not match what
> the code actually does.  You describe it as going until it hits one of the
> known categories of actual type.  But what it actually does is go only as
> long as it is seeing one of the known categories of wrapper type.  I'm not
> really sure which it should do (or if it should instead do something
> different from either), but the description should match the behavior.
> 
> As described, it would fall down if a new tag were introduced for a new
> category of actual type.  As implemented, it would fall down if a new tag
> were introduced for a new category of wrapper type.

I think peeling through something unrecognized is worse than stopping,
so I'd update the description to match the current code.

FWIW, DWARF4 Figure 15 (under section 5.2) lists type modifier tags.  Of
those those we should peel through const, restrict, and volatile, and
stop at pointer, ref, and rvalue_ref.  I'm not sure about packed or
shared though.  It's odd to me that typedef didn't make this list, but
it should be peeled too.

> A third potential approach would be to attempt future-proofing for those
> cases.  That is, just keep going as long as there is a DW_AT_type
> attribute.  But that would need a special case for DW_TAG_pointer_type and
> DW_TAG_reference_type, where you want to stop even though it has a
> DW_AT_type referring to another type.  I can't think of any other cases
> where an "actual" type has a DW_AT_type, but there might well be some.  If
> any new tag were like DW_TAG_pointer_type rather than like
> DW_TAG_const_type et al, then this approach would fall down there.

Going through DWARF4 appendix A for those DW_TAG_*_type which suggest
DW_AT_type, I'd also exclude these from peeling:

DW_TAG_array_type
DW_TAG_enumeration_type
DW_TAG_ptr_to_member_type
DW_TAG_set_type
DW_TAG_subrange_type
DW_TAG_subroutine_type

> So firstly we need to decide which kinds of future addition we expect and
> thus how to handle the future-proofing.  Then we need to have descriptions
> and implementation that match.

IMO, a blacklist of what not to peel is more dangerous to the future
than a whitelist of what we know can be peeled.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-11-08 13:18 Mark Wielaard
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2014-11-08 13:18 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]

On Wed, Nov 05, 2014 at 05:02:30PM +0100, Petr Machata wrote:
> Mark Wielaard <mjw@redhat.com> writes:
> 
> > Is it clear what the intent of the function is?
> 
> Yes.

Thanks, I have pushed the patch to master now.

> > And when we do extend the tags that get peeled, do we need to update
> > the function symbol version?
> 
> I don't think so.  If we are adding new tags (i.e. from a new Dwarf
> version) and the additions fit into existing contract, then callers
> should benefit from the improvements without having to be rebuilt.
> 
> Adding more tags from existing versions is something of a gray area, as
> the code could easily assume a set of tags that are peeled.  I still
> lean towards not bumping.  If the contract didn't change, this is just
> bugfixing.  We really should have peeled this particular tag, as it fits
> the bill, but we forgot about it.

There could in theory also be GNU extensions that are added for older
DWARF versions (when not using -gstrict-dwarf). But it is probably not
a good idea for GCC to output them for older versions in the first place.

I agree with not having to bump the symbol version in general.
Lets go with that plan for now. We can always reconsider if we actually
do have to add new tags in the future.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-11-05 16:02 Petr Machata
  0 siblings, 0 replies; 8+ messages in thread
From: Petr Machata @ 2014-11-05 16:02 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 758 bytes --]

Mark Wielaard <mjw@redhat.com> writes:

> Is it clear what the intent of the function is?

Yes.

> And when we do extend the tags that get peeled, do we need to update
> the function symbol version?

I don't think so.  If we are adding new tags (i.e. from a new Dwarf
version) and the additions fit into existing contract, then callers
should benefit from the improvements without having to be rebuilt.

Adding more tags from existing versions is something of a gray area, as
the code could easily assume a set of tags that are peeled.  I still
lean towards not bumping.  If the contract didn't change, this is just
bugfixing.  We really should have peeled this particular tag, as it fits
the bill, but we forgot about it.

Thanks,
Petr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-11-05 13:29 Mark Wielaard
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2014-11-05 13:29 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 1895 bytes --]

On Thu, 2014-10-30 at 12:47 +0100, Mark Wielaard wrote:
> What would be the correct way to describe that future versions might add
> those to the white list of tags to be peeled? My goal really is to have
> a type peel function that user code can depend on if they need to do
> something like find the underlying return type in the backends or like
> the dwarf_aggregate_size function. So that when DWARFv5 comes out, or
> some new GNU qualifier tag is added, all the user has to do is upgrade
> to a newer elfutils that knows about those.

So how about this description for libdw.h?

+/* For type aliases and qualifier type DIEs follow the DW_AT_type
+   attribute (recursively) and return the underlying type Dwarf_Die.
+   Returns 0 when RESULT contains a Dwarf_Die (possibly equal to the
+   given DIE) that isn't a type alias or qualifier type.  Returns 1
+   when RESULT contains a type alias or qualifier Dwarf_Die that
+   couldn't be peeled further (it doesn't have a DW_TAG_type
+   attribute).  Returns -1 when an error occured.
+
+   The current DWARF specification defines one type alias tag
+   (DW_TAG_typedef) and three qualifier type tags (DW_TAG_const_type,
+   DW_TAG_volatile_type, DW_TAG_restrict_type).  A future version of
+   this function might peel other alias or qualifier type tags if a
+   future DWARF version or GNU extension defines other type aliases or
+   qualifier type tags that don't modify or change the structural
+   layout of the underlying type.  */
+extern int dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
+    __nonnull_attribute__ (2);

That is the only change compared to the original patch. The
implementation and test cases are the same.

Is it clear what the intent of the function is? And when we do extend
the tags that get peeled, do we need to update the function symbol
version?

Thanks,

Mark

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-10-30 11:47 Mark Wielaard
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2014-10-30 11:47 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 4266 bytes --]

On Fri, 2014-10-10 at 14:30 -0700, Josh Stone wrote:
> On 10/10/2014 11:42 AM, Roland McGrath wrote:
> > The description in your prologue and the libdw.h comment do not match what
> > the code actually does.  You describe it as going until it hits one of the
> > known categories of actual type.  But what it actually does is go only as
> > long as it is seeing one of the known categories of wrapper type.  I'm not
> > really sure which it should do (or if it should instead do something
> > different from either), but the description should match the behavior.
> > 
> > As described, it would fall down if a new tag were introduced for a new
> > category of actual type.  As implemented, it would fall down if a new tag
> > were introduced for a new category of wrapper type.
> 
> I think peeling through something unrecognized is worse than stopping,
> so I'd update the description to match the current code.

Yeah, you caught me. No good deed goes unpunished. For once I write the
documentation before the code to make sure I don't forget. And then of
course I find out it cannot actually written as documented, but forget
to update the documentation...

> FWIW, DWARF4 Figure 15 (under section 5.2) lists type modifier tags.  Of
> those those we should peel through const, restrict, and volatile, and
> stop at pointer, ref, and rvalue_ref.  I'm not sure about packed or
> shared though.

Both packed and shared change the structural layout of the underlying
type, so they are different from type aliases or qualifier tags.

>   It's odd to me that typedef didn't make this list, but
> it should be peeled too.

Yes, DWARF has a special type for type aliases (typedefs), but kind of
lumps qualifiers, storage and structural type modifiers together. In the
text that is, there is no actual way to identify this group of tags.
They don't even share a common unique attribute. As can be seen by...

> > A third potential approach would be to attempt future-proofing for those
> > cases.  That is, just keep going as long as there is a DW_AT_type
> > attribute.  But that would need a special case for DW_TAG_pointer_type and
> > DW_TAG_reference_type, where you want to stop even though it has a
> > DW_AT_type referring to another type.  I can't think of any other cases
> > where an "actual" type has a DW_AT_type, but there might well be some.  If
> > any new tag were like DW_TAG_pointer_type rather than like
> > DW_TAG_const_type et al, then this approach would fall down there.
> 
> Going through DWARF4 appendix A for those DW_TAG_*_type which suggest
> DW_AT_type, I'd also exclude these from peeling:
> 
> DW_TAG_array_type
> DW_TAG_enumeration_type
> DW_TAG_ptr_to_member_type
> DW_TAG_set_type
> DW_TAG_subrange_type
> DW_TAG_subroutine_type

Right, there is no one semantic/structural meaning to DW_AT_type. So
depending on it being present isn't really a good way to distinguish
between the types to include/exclude.

> > So firstly we need to decide which kinds of future addition we expect and
> > thus how to handle the future-proofing.  Then we need to have descriptions
> > and implementation that match.
> 
> IMO, a blacklist of what not to peel is more dangerous to the future
> than a whitelist of what we know can be peeled.

Agreed. That is why I ended up implementing it as an explicit whitelist
that just includes typedef, const_type, volatile_type and restrict_type.

Other possible future modifier type tags with the same properties are
are DW_TAG_atomic_type which will probably be added with DWARFv5 (or as
GNU extension), and maybe DW_TAG_GNU_aligned_type which I have been
toying with for GCC/GDB. But I think that will be turned into an
attribute instead.

What would be the correct way to describe that future versions might add
those to the white list of tags to be peeled? My goal really is to have
a type peel function that user code can depend on if they need to do
something like find the underlying return type in the backends or like
the dwarf_aggregate_size function. So that when DWARFv5 comes out, or
some new GNU qualifier tag is added, all the user has to do is upgrade
to a newer elfutils that knows about those.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-10-10 21:45 Roland McGrath
  0 siblings, 0 replies; 8+ messages in thread
From: Roland McGrath @ 2014-10-10 21:45 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 139 bytes --]

> IMO, a blacklist of what not to peel is more dangerous to the future
> than a whitelist of what we know can be peeled.

Fair enough.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-10-10 18:42 Roland McGrath
  0 siblings, 0 replies; 8+ messages in thread
From: Roland McGrath @ 2014-10-10 18:42 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 1418 bytes --]

The description in your prologue and the libdw.h comment do not match what
the code actually does.  You describe it as going until it hits one of the
known categories of actual type.  But what it actually does is go only as
long as it is seeing one of the known categories of wrapper type.  I'm not
really sure which it should do (or if it should instead do something
different from either), but the description should match the behavior.

As described, it would fall down if a new tag were introduced for a new
category of actual type.  As implemented, it would fall down if a new tag
were introduced for a new category of wrapper type.

A third potential approach would be to attempt future-proofing for those
cases.  That is, just keep going as long as there is a DW_AT_type
attribute.  But that would need a special case for DW_TAG_pointer_type and
DW_TAG_reference_type, where you want to stop even though it has a
DW_AT_type referring to another type.  I can't think of any other cases
where an "actual" type has a DW_AT_type, but there might well be some.  If
any new tag were like DW_TAG_pointer_type rather than like
DW_TAG_const_type et al, then this approach would fall down there.

So firstly we need to decide which kinds of future addition we expect and
thus how to handle the future-proofing.  Then we need to have descriptions
and implementation that match.


Thanks,
Roland

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
@ 2014-10-06 20:29 Mark Wielaard
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2014-10-06 20:29 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 15088 bytes --]

On irc Josh pointed out that dwarf_aggregate_size still doesn't work
correctly for qualified types. Since handling qualified types is a
common issue (we already have support for it in the backends for the
return type and I have had to fix issues with it in other programs
before) I added a new libdw function for it and use that in both the
backends and dwarf_aggregate_size. This will also help when DWARFv5
adds new qualified type tags.

Add new function dwarf_peel_type. Some type annotations in DWARF are
specified by modifier tag type wrappers instead of attributes.
For type aliases (typedef) and qualifiers (const, volatile, restrict)
tags dwarf_peel_type follows the DW_AT_type attributes till it finds
a base, user-defined, reference or pointer type DIE.

Use this new function in the backends for return type DIEs (replacing
the existing dwarf_peel_type there) and in dwarf_aggregate_size so
it can provide the sizes for qualified types too. Add a new version
and testcase for the new dwarf_aggregate_size functionality.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 ChangeLog                    |   4 +++
 NEWS                         |   5 +++
 backends/ChangeLog           |   5 +++
 backends/libebl_CPU.h        |  22 +++----------
 libdw/ChangeLog              |  10 ++++++
 libdw/Makefile.am            |   2 +-
 libdw/dwarf_aggregate_size.c |  14 ++++++--
 libdw/dwarf_peel_type.c      |  74 +++++++++++++++++++++++++++++++++++++++++++
 libdw/libdw.h                |  11 +++++++
 libdw/libdw.map              |  12 ++++++-
 libdw/libdwP.h               |   1 +
 tests/ChangeLog              |   6 ++++
 tests/Makefile.am            |   3 +-
 tests/run-aggregate-size.sh  |  40 ++++++++++++++++++++++-
 tests/testfile-sizes3.o.bz2  | Bin 0 -> 1147 bytes
 15 files changed, 185 insertions(+), 24 deletions(-)
 create mode 100644 libdw/dwarf_peel_type.c
 create mode 100644 tests/testfile-sizes3.o.bz2

diff --git a/ChangeLog b/ChangeLog
index 8277932..0947608 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: New section 0.161. Add dwarf_peel_type.
+
 2014-08-25  Mark Wielaard  <mjw@redhat.com>
 
 	* configure.ac: Set version to 0.160.
diff --git a/NEWS b/NEWS
index aceb3e3..130856e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Version 0.161
+
+libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses
+       dwarf_peel_type to also provide the sizes of qualified types.
+
 Version 0.160
 
 libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die.
diff --git a/backends/ChangeLog b/backends/ChangeLog
index a335b20..82a2bf1 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl_CPU.h (dwarf_peel_type): Removed.
+	(dwarf_peeled_die_type): Use libdw dwarf_peel_type.
+
 2014-07-18  Kyle McMartin  <kyle@redhat.com>
 	    Mark Wielaard  <mjw@redhat.com>
 
diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h
index fa0d4f2..ef2b922 100644
--- a/backends/libebl_CPU.h
+++ b/backends/libebl_CPU.h
@@ -53,23 +53,6 @@ extern bool (*generic_debugscn_p) (const char *) attribute_hidden;
      if (_die == NULL) return -1; \
      dwarf_tag (_die); })
 
-/* Follow typedefs and qualifiers to get to the actual type.  */
-static inline int
-dwarf_peel_type (Dwarf_Die *typediep, Dwarf_Attribute *attrp)
-{
-  int tag = DWARF_TAG_OR_RETURN (typediep);
-  while (tag == DW_TAG_typedef
-	 || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
-	 || tag == DW_TAG_restrict_type)
-    {
-      attrp = dwarf_attr_integrate (typediep, DW_AT_type, attrp);
-      typediep = dwarf_formref_die (attrp, typediep);
-      tag = DWARF_TAG_OR_RETURN (typediep);
-    }
-
-  return tag;
-}
-
 /* Get a type die corresponding to DIE.  Peel CV qualifiers off
    it.  */
 static inline int
@@ -84,7 +67,10 @@ dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result)
   if (dwarf_formref_die (attr, result) == NULL)
     return -1;
 
-  return dwarf_peel_type (result, attr);
+  if (dwarf_peel_type (result, result) != 0)
+    return -1;
+
+  return DWARF_TAG_OR_RETURN (result);
 }
 
 #endif	/* libebl_CPU.h */
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index f40ad25..2a4f1cd 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,13 @@
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_peel_type.c.
+	* dwarf_aggregate_size.c (get_type): Use dwarf_peel_type.
+	(aggregate_size): Likewise. Add old and new version.
+	* dwarf_peel_type.c: New file.
+	* libdw.h (dwarf_peel_type): New function declaration.
+	* libdwP.h (dwarf_peel_type): New internal declaration.
+	* libdw.map (ELFUTILS_0.161): New section.
+
 2014-10-05  Mark Wielaard  <mjw@redhat.com>
 
 	* dwarf.h: Add DW_AT_GNU_deleted.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 2e42a37..859af4d 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -87,7 +87,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
 		  dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \
 		  dwarf_getlocation_die.c dwarf_getlocation_attr.c \
 		  dwarf_getalt.c dwarf_setalt.c dwarf_cu_getdwarf.c \
-		  dwarf_cu_die.c
+		  dwarf_cu_die.c dwarf_peel_type.c
 
 if MAINTAINER_MODE
 BUILT_SOURCES = $(srcdir)/known-dwarf.h
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index 5d23541..1666e24 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -37,8 +37,13 @@
 static Dwarf_Die *
 get_type (Dwarf_Die *die, Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
 {
-  return INTUSE(dwarf_formref_die)
+  Dwarf_Die *type = INTUSE(dwarf_formref_die)
     (INTUSE(dwarf_attr_integrate) (die, DW_AT_type, attr_mem), type_mem);
+
+  if (INTUSE(dwarf_peel_type) (type, type) != 0)
+    return NULL;
+
+  return type;
 }
 
 static int
@@ -198,7 +203,6 @@ aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
 
   switch (INTUSE(dwarf_tag) (die))
     {
-    case DW_TAG_typedef:
     case DW_TAG_subrange_type:
       return aggregate_size (get_type (die, &attr_mem, type_mem),
 			     size, type_mem); /* Tail call.  */
@@ -225,6 +229,12 @@ dwarf_aggregate_size (die, size)
      Dwarf_Word *size;
 {
   Dwarf_Die type_mem;
+
+  if (INTUSE (dwarf_peel_type) (die, die) != 0)
+    return -1;
+
   return aggregate_size (die, size, &type_mem);
 }
 INTDEF (dwarf_aggregate_size)
+OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
+NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161)
diff --git a/libdw/dwarf_peel_type.c b/libdw/dwarf_peel_type.c
new file mode 100644
index 0000000..a110bc5
--- /dev/null
+++ b/libdw/dwarf_peel_type.c
@@ -0,0 +1,74 @@
+/* Peel type aliases and qualifier tags from a type DIE.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <string.h>
+
+
+int
+dwarf_peel_type (die, result)
+     Dwarf_Die *die;
+     Dwarf_Die *result;
+{
+  int tag;
+
+  /* Ignore previous errors.  */
+  if (die == NULL)
+    return -1;
+
+  *result = *die;
+  tag = INTUSE (dwarf_tag) (result);
+  while (tag == DW_TAG_typedef
+	 || tag == DW_TAG_const_type
+	 || tag == DW_TAG_volatile_type
+	 || tag == DW_TAG_restrict_type)
+    {
+      Dwarf_Attribute attr_mem;
+      Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (die, DW_AT_type,
+							     &attr_mem);
+      if (attr == NULL)
+	return 1;
+
+      result = INTUSE (dwarf_formref_die) (attr, result);
+      if (result == NULL)
+	return -1;
+
+      tag = INTUSE (dwarf_tag) (result);
+    }
+
+  if (tag == DW_TAG_invalid)
+    return -1;
+
+  return 0;
+}
+INTDEF(dwarf_peel_type)
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 196d54a..248265e 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -398,6 +398,17 @@ extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result)
 extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result)
      __nonnull_attribute__ (2);
 
+/* For type aliases (typedef) and qualifier (const, volatile,
+   restrict) tags follow the DW_AT_type attribute (recursively) and
+   return the underlying base, user-defined, reference or pointer
+   type.  Returns 0 when RESULT contains a base, user-defined,
+   reference or pointer type (possibly equal to the given DIE).
+   Returns 1 when RESULT contains a type alias or qualifier that
+   couldn't be peeled further (it doesn't have a DW_TAG_type
+   attribute).  Returns -1 when an error occured.  */
+extern int dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
+    __nonnull_attribute__ (2);
+
 /* Check whether the DIE has children.  */
 extern int dwarf_haschildren (Dwarf_Die *die) __nonnull_attribute__ (1);
 
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 55bc537..0c0ea99 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -306,4 +306,14 @@ ELFUTILS_0.160 {
   global:
     dwarf_cu_getdwarf;
     dwarf_cu_die;
-} ELFUTILS_0.159;
\ No newline at end of file
+} ELFUTILS_0.159;
+
+ELFUTILS_0.161 {
+  global:
+    dwarf_peel_type;
+
+    # Replaced ELFUTILS_0.144 version.  Both versions point to the
+    # same implementation, but users of the new symbol version can
+    # presume that it uses dwarf_peel_type.
+    dwarf_aggregate_size;
+} ELFUTILS_0.160;
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index ce8a83d..9a903a3 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -690,6 +690,7 @@ INTDECL (dwarf_lowpc)
 INTDECL (dwarf_nextcu)
 INTDECL (dwarf_next_unit)
 INTDECL (dwarf_offdie)
+INTDECL (dwarf_peel_type)
 INTDECL (dwarf_ranges)
 INTDECL (dwarf_setalt)
 INTDECL (dwarf_siblingof)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 6b76248..5c06d23 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* run-aggregate-size.sh: Add testfile-sizes3.o test case.
+	* testfile-sizes3.o.bz2: New test file.
+	* Makefile.am (EXTRA_DIST): Add testfile-sizes3.o.bz2.
+
 2014-10-02  Mark Wielaard  <mjw@redhat.com>
 
 	* run-deleted.sh: Unset VALGRIND_CMD before running deleted.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1c4b2b1..09909d2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -275,7 +275,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2 \
 	     run-deleted.sh run-linkmap-cut.sh linkmap-cut-lib.so.bz2 \
 	     linkmap-cut.bz2 linkmap-cut.core.bz2 \
-	     run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2
+	     run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \
+	     testfile-sizes3.o.bz2
 
 if USE_VALGRIND
 valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no'
diff --git a/tests/run-aggregate-size.sh b/tests/run-aggregate-size.sh
index 7d812a5..42b0742 100755
--- a/tests/run-aggregate-size.sh
+++ b/tests/run-aggregate-size.sh
@@ -38,7 +38,31 @@
 # gcc -g -c -o testfile-sizes1.o sizes.c
 # clang -g -c -o testfile-sizes2.o sizes.c
 
-testfiles testfile-sizes1.o testfile-sizes2.o
+# const char c;
+# volatile int i;
+# const volatile long l;
+#
+# void * restrict v;
+#
+# struct s
+# {
+#   const char *a;
+#   volatile int i;
+# } s;
+#
+# const char ca[16];
+# volatile int ia[32];
+# const volatile void * const volatile restrict va[64];
+# struct s sa[8];
+#
+# typedef const int foo;
+# typedef volatile foo bar;
+# foo f;
+# bar b;
+#
+# gcc -std=c99 -g -c -o testfile-sizes3.o sizes.c
+
+testfiles testfile-sizes1.o testfile-sizes2.o testfile-sizes3.o
 
 testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes1.o <<\EOF
 c size 1
@@ -64,4 +88,18 @@ va size 512
 sa size 128
 EOF
 
+testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes3.o <<\EOF
+c size 1
+i size 4
+l size 8
+v size 8
+s size 16
+ca size 16
+ia size 128
+va size 512
+sa size 128
+f size 4
+b size 4
+EOF
+
 exit 0
diff --git a/tests/testfile-sizes3.o.bz2 b/tests/testfile-sizes3.o.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..7fa6a8a529676bc8324d383c8d11f86c66ef453c
GIT binary patch
literal 1147
zcmV->1cduST4*^jL0KkKSxZ~zf&c_3|NsC0|L^bT_ka8SS{VQT-|)ggfXE^V2tr{{
zfPe%fFbvQGsyqn-n<EVnnrMl=Dm_mW@=w%{DWSbd>NI+XsA;u5Kn*nY9-4z>Lror_
z1JrFJL-eE6^hSh2YGI~{l5I58Q%_UUX{Jp8000000000000068OeO$Km;eOC3;+NC
zm=geu002w?00IU~CIC#B00hJg0001(699|=089V?0Fe<0o{}3)Q#55BQ+lVUX_HKW
z>S>{%4X83S7?_Me4K&f|84pt<^+tzP)-#f|y7q30foPkXqYxWfgEY8a>(~ESWfS6-
z(a)Ni+=gF-x(6*8ds7=!_fcc2kOBPJBU<GRQ?0tC?^CN&|5C!&5Nxl<*@ihk@!8vP6N
zb~9?QZ$X^t;U!#h5Gk76G$6+a)RjA#4E{7O(J7KWD9`F?U-H)H-g)ZA26UR~0D>Tw
z#ZeF;oL~!mc$lCHaf(a)Drt4cMyxPV_n1%SYA{*@Uz8m{Xo77Mc1ipRx|I%Gs-^K(S#
zz~LeuggzfHUyp-V(Bybt)#5L0rk*Fcl4m_=YRW}g1D3!>b4XIsTc#4pVGLTXT1b{C
zY;B`mlF~hPlCrSbNQO5skS=2lszO~R9%C1M(a)JC<r;>p&g7!T8HvC6bBViRaun7(O9
zMH*Q?m_SQ4nGFCoAne2jUmhiaU4g<%SiRPgJxp*QJ!Z6V-=k*4?&l$Mq#Nd}>3J!t
zfx`XPsYr$eHCW5YOOW$;<Uu(Mp?6|G-W*-ru}Ghjw5>|$B(a)q}qM(GTYNG+|LJ({_8
zb?fQ(KL3N(l{N!Fuwt=`l~6!h_jQGp+&2DQfA3p2e_{{Wqh*T+0t305Wg<};8-x;t
zy1Eb$FcdZ6tgC~fs4Li$X=7Hm$kLz{Vyi0BR^Tv8VMh)byfdjST0soqw3Uq0%@siW
zhg)D{cfrYaV$Ry29j-}_4KTE4FuSx2gziv|o=8Q_V$X13V#y?Tx__-HW3poW6C$fd
z(a)R9=!CQBj`C4z1vY#q@>WGYL(A=#;?K`$6H79)_yACnT8a*1<2g3nIX(a)5n|ABB$^!
z2F#TNRAR^FJ!$x(a)vp$$~3RP9v;)X!xUCK>tjRyltEBDzZBH@|);M+R^*Ec4{I0-W4
zgB{bwG2sl~4o$|I-(a)tg-b+`N9^GeVf(a)32um(kr174#XSZnKXtArwj{}267M#JLjb?
zBEnP>Sz`~{TP{nXOoJaxH!a1OYD%q#3i;{k(pI3vICDllLdrL&<q$UwX54S9jwIN(
zLr(a)Cl+-iX>A+{t8{qoj}gu_}I)ytfkiqQ~5BcQzLqo_fwvE6!VfF5U-qN=(h5<Hk}
z?>IlgqS=W8etiOryOLoxgk~01!GmL1C>KHinx!gA5J!N5gTbgIL$nc6oK%e13>g$>
z2FNzDZWI9%SIuBR+mE)BL>%;jojDHxDS-I|yTEbKl*(HQYg(19(a)laZxtTkWzypjKl
Nxgwk>NF}ZF!2m-C{KEhM

literal 0
HcmV?d00001

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-11-08 13:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-10 21:30 [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size Josh Stone
  -- strict thread matches above, loose matches on Subject: below --
2014-11-08 13:18 Mark Wielaard
2014-11-05 16:02 Petr Machata
2014-11-05 13:29 Mark Wielaard
2014-10-30 11:47 Mark Wielaard
2014-10-10 21:45 Roland McGrath
2014-10-10 18:42 Roland McGrath
2014-10-06 20:29 Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).