From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============8533398983912820332==" MIME-Version: 1.0 From: Mark Wielaard 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 Message-ID: <1412627360-24629-1-git-send-email-mjw@redhat.com> --===============8533398983912820332== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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 --- 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 + + * NEWS: New section 0.161. Add dwarf_peel_type. + 2014-08-25 Mark Wielaard = * 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 + + * libebl_CPU.h (dwarf_peel_type): Removed. + (dwarf_peeled_die_type): Use libdw dwarf_peel_type. + 2014-07-18 Kyle McMartin Mark Wielaard = 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 *) attribu= te_hidden; if (_die =3D=3D 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 =3D DWARF_TAG_OR_RETURN (typediep); - while (tag =3D=3D DW_TAG_typedef - || tag =3D=3D DW_TAG_const_type || tag =3D=3D DW_TAG_volatile_type - || tag =3D=3D DW_TAG_restrict_type) - { - attrp =3D dwarf_attr_integrate (typediep, DW_AT_type, attrp); - typediep =3D dwarf_formref_die (attrp, typediep); - tag =3D 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) =3D=3D NULL) return -1; = - return dwarf_peel_type (result, attr); + if (dwarf_peel_type (result, result) !=3D 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 + + * 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 = * 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 =3D 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 =3D $(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 =3D INTUSE(dwarf_formref_die) (INTUSE(dwarf_attr_integrate) (die, DW_AT_type, attr_mem), type_mem); + + if (INTUSE(dwarf_peel_type) (type, type) !=3D 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) !=3D 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include +#include + + +int +dwarf_peel_type (die, result) + Dwarf_Die *die; + Dwarf_Die *result; +{ + int tag; + + /* Ignore previous errors. */ + if (die =3D=3D NULL) + return -1; + + *result =3D *die; + tag =3D INTUSE (dwarf_tag) (result); + while (tag =3D=3D DW_TAG_typedef + || tag =3D=3D DW_TAG_const_type + || tag =3D=3D DW_TAG_volatile_type + || tag =3D=3D DW_TAG_restrict_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr =3D INTUSE (dwarf_attr_integrate) (die, DW_AT_= type, + &attr_mem); + if (attr =3D=3D NULL) + return 1; + + result =3D INTUSE (dwarf_formref_die) (attr, result); + if (result =3D=3D NULL) + return -1; + + tag =3D INTUSE (dwarf_tag) (result); + } + + if (tag =3D=3D 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 *res= ult) 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 + + * 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 = * 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 =3D 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=3D'valgrind -q --error-exitcode=3D1 --run-libc-freeres=3Dno' 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=3Dc99 -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..7fa6a8a529676bc8324d383c8d1= 1f86c66ef453c GIT binary patch literal 1147 zcmV->1cduST4*^jL0KkKSxZ~zf&c_3|NsC0|L^bT_ka8SS{VQT-|)ggfXE^V2tr{{ zfPe%fFbvQGsyqn-nNI+XsA;u5Kn*nY9-4z>Lror_ z1JrFJL-eE6^hSh2YGI~{l5I58Q%_UUX{Jp8000000000000068OeO$Km;eOC3;+NC zm=3Dgeu002w?00IU~CIC#B00hJg0001(699|=3D089V?0Fe<0o{}3)Q#55BQ+lVUX_HKW z>S>{%4X83S7?_Me4K&f|84pt<^+tzP)-#f|y7q30foPkXqYxWfgEY8a>(~ESWfS6- z(a)Ni+=3DgF-x(6*8ds7=3D!_fcc2kOBPJBUTw z#ZeF;oL~!mc$lCHaf(a)Drt4cMyxPV_n1%SYA{*@Uz8m{Xo77Mc1ipRx|I%Gs-^K(S# zz~LeuggzfHUyp-V(Bybt)#5L0rk*Fcl4m_=3DYRW}g1D3!>b4XIsTc#4pVGLTXT1b{C zY;B`mlF~hPlCrSbNQO5skS=3D2lszO~R9%C1M(a)JCp&g7!T8HvC6bBViRaun7(O9 zMH*Q?m_SQ4nGFCoAne2jUmhiaU4g<%SiRPgJxp*QJ!Z6V-=3Dk*4?&l$Mq#Nd}>3J!t zfx`XPsYr$eHCW5YOOW$;|$B(a)q}qM(GTYNG+|LJ({_8 zb?fQ(KL3N(l{N!Fuwt=3D`l~6!h_jQGp+&2DQfA3p2e_{{Wqh*T+0t305Wg<};8-x;t zy1Eb$FcdZ6tgC~fs4Li$X=3D7Hm$kLz{Vyi0BR^Tv8VMh)byfdjST0soqw3Uq0%@siW zhg)D{cfrYaV$Ry29j-}_4KTE4FuSx2gziv|o=3D8Q_V$X13V#y?Tx__-HW3poW6C$fd z(a)R9=3D!CQBj`C4z1vY#q@>WGYL(A=3D#;?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&A+{t8{qoj}gu_}I)ytfkiqQ~5BcQzLqo_fwvE6!VfF5U-qN=3D(h5IlgqS=3DW8etiOryOLoxgk~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 --===============8533398983912820332==--