From: Mark Wielaard <mjw@redhat.com>
To: elfutils-devel@lists.fedorahosted.org
Subject: [PATCH] libdw: Add dwarf_peel_type. Use it in dwarf_aggregate_size.
Date: Mon, 06 Oct 2014 22:29:20 +0200 [thread overview]
Message-ID: <1412627360-24629-1-git-send-email-mjw@redhat.com> (raw)
[-- 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
next reply other threads:[~2014-10-06 20:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-06 20:29 Mark Wielaard [this message]
2014-10-10 18:42 Roland McGrath
2014-10-10 21:30 Josh Stone
2014-10-10 21:45 Roland McGrath
2014-10-30 11:47 Mark Wielaard
2014-11-05 13:29 Mark Wielaard
2014-11-05 16:02 Petr Machata
2014-11-08 13:18 Mark Wielaard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1412627360-24629-1-git-send-email-mjw@redhat.com \
--to=mjw@redhat.com \
--cc=elfutils-devel@lists.fedorahosted.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).