From 547972539ecbe8668e89d891d86cef10f0302fd5 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 27 Apr 2012 13:00:50 +0200 Subject: [PATCH] dwarf_highpc: Handle DW_AT_high_pc being a constant offset from DW_AT_low_pc. --- NEWS | 4 ++ libdw/ChangeLog | 5 ++ libdw/dwarf_highpc.c | 29 +++++++++-- tests/ChangeLog | 8 +++ tests/Makefile.am | 8 +-- tests/low_high_pc.c | 114 +++++++++++++++++++++++++++++++++++++++++ tests/run-low_high_pc.sh | 42 +++++++++++++++ tests/testfile_low_high_pc.bz2 | Bin 0 -> 2812 bytes 8 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 tests/low_high_pc.c create mode 100755 tests/run-low_high_pc.sh create mode 100755 tests/testfile_low_high_pc.bz2 diff --git a/NEWS b/NEWS index aa660a8..d41f045 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 0.154 + +libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc constant form. + Version 0.153 libdw: Support reading .zdebug_* DWARF sections compressed via zlib. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index f96c0d1..3ff83e4 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2012-04-27 Mark Wielaard + + * libdw/dwarf_highpc.c (dwarf_highpc): Handle DW_AT_high_pc being + a constant offset from DW_AT_low_pc. + 2012-03-19 Tom Tromey * libdw_findcu.c (findcu_cb): Move earlier. diff --git a/libdw/dwarf_highpc.c b/libdw/dwarf_highpc.c index c88e072..4e7c3f6 100644 --- a/libdw/dwarf_highpc.c +++ b/libdw/dwarf_highpc.c @@ -1,5 +1,5 @@ /* Return high PC attribute of DIE. - Copyright (C) 2003, 2005 Red Hat, Inc. + Copyright (C) 2003, 2005, 2012 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2003. @@ -61,10 +61,29 @@ dwarf_highpc (die, return_addr) Dwarf_Die *die; Dwarf_Addr *return_addr; { - Dwarf_Attribute attr_mem; + Dwarf_Attribute attr_high_mem; + Dwarf_Attribute *attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc, + &attr_high_mem); + if (attr_high == NULL) + return -1; - return INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_high_pc, - &attr_mem), - return_addr); + if (attr_high->form == DW_FORM_addr) + return INTUSE(dwarf_formaddr) (attr_high, return_addr); + + /* DWARF 4 allows high_pc to be a constant offset from low_pc. */ + Dwarf_Attribute attr_low_mem; + if (INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_low_pc, + &attr_low_mem), + return_addr) == 0) + { + Dwarf_Word uval; + if (INTUSE(dwarf_formudata) (attr_high, &uval) == 0) + { + *return_addr += uval; + return 0; + } + __libdw_seterrno (DWARF_E_NO_ADDR); + } + return -1; } INTDEF(dwarf_highpc) diff --git a/tests/ChangeLog b/tests/ChangeLog index ffe61d5..abc7340 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,11 @@ +2012-04-27 Mark Wielaard + + * Makefile.am (TESTS): Add run-low_high_pc.sh + (EXTRA_DIST): Add run-low_high_pc.sh and testfile_low_high_pc.bz2 + (noinst_PROGRAMS): Add low_high_pc. + (low_high_pc_LDADD): New variable. + * low_high_pc.c: New test. + 2012-04-26 Mark Wielaard * Makefile.am (EXTRA_DIST): Remove run-show-ciefde.sh. diff --git a/tests/Makefile.am b/tests/Makefile.am index 835cc7a..61247e4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,7 +58,7 @@ noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ dwfl-addr-sect dwfl-bug-report early-offscn \ dwfl-bug-getmodules dwarf-getmacros addrcfi \ test-flag-nobits dwarf-getstring rerequest_tag \ - alldts md5-sha1-test typeiter + alldts md5-sha1-test typeiter low_high_pc asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ asm-tst6 asm-tst7 asm-tst8 asm-tst9 @@ -87,7 +87,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-early-offscn.sh run-dwarf-getmacros.sh \ run-test-flag-nobits.sh run-prelink-addr-test.sh \ run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \ - run-readelf-d.sh run-unstrip-n.sh + run-readelf-d.sh run-unstrip-n.sh run-low_high_pc.sh if !STANDALONE noinst_PROGRAMS += msg_tst md5-sha1-test @@ -164,7 +164,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ testfile56.bz2 testfile57.bz2 testfile58.bz2 \ run-typeiter.sh testfile59.bz2 \ run-readelf-d.sh testlib_dynseg.so.bz2 \ - run-unstrip-n.sh testcore-rtlib.bz2 + run-unstrip-n.sh testcore-rtlib.bz2 \ + run-low_high_pc.sh testfile_low_high_pc.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ @@ -262,6 +263,7 @@ rerequest_tag_LDADD = $(libdw) $(libmudflap) alldts_LDADD = $(libebl) $(libelf) $(libmudflap) md5_sha1_test_LDADD = $(libeu) typeiter_LDADD = $(libdw) $(libelf) $(libmudflap) +low_high_pc_LDADD = $(libdw) $(libelf) $(libmudflap) if GCOV check: check-am coverage diff --git a/tests/low_high_pc.c b/tests/low_high_pc.c new file mode 100644 index 0000000..3054046 --- /dev/null +++ b/tests/low_high_pc.c @@ -0,0 +1,114 @@ +/* Test program for dwarf_lowpc and dwarf_highpc + Copyright (C) 2012 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils 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; version 2 of the License. + + Red Hat 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 a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct args +{ + Dwfl *dwfl; + Dwarf_Die *cu; + Dwarf_Addr dwbias; + char **argv; + const char *file; +}; + +static struct args *args; + +static void +fail(Dwarf_Off off, const char *name, const char *msg) +{ + printf("%s: [%lx] '%s' %s\n", args->file, off, name, msg); + exit(-1); +} + +static int +handle_die (Dwarf_Die *die, void *arg) +{ + args = arg; + Dwarf_Off off = dwarf_dieoffset (die); + + const char *name = dwarf_diename (die); + if (name == NULL) + fail (off, "", "die without a name"); + + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = 0; + if (dwarf_lowpc (die, &lowpc) != 0 && dwarf_hasattr (die, DW_AT_low_pc)) + fail (off, name, "has DW_AT_low_pc but dwarf_lowpc fails"); + if (dwarf_highpc (die, &highpc) != 0 && dwarf_hasattr (die, DW_AT_high_pc)) + fail (off, name, "has DW_AT_high_pc but dwarf_highpc fails"); + + if (dwarf_hasattr (die, DW_AT_low_pc) + && dwarf_hasattr (die, DW_AT_high_pc) + && highpc <= lowpc) + { + printf("lowpc: %lx, highpc: %lx\n", lowpc, highpc); + fail (off, name, "highpc <= lowpc"); + } + + return 0; +} + + +int +main (int argc, char *argv[]) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + struct args a = { .dwfl = NULL, .cu = NULL }; + + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, + &a.dwfl); + assert (a.dwfl != NULL); + a.argv = &argv[remaining]; + + int result = 0; + + while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL) + { + a.file = dwarf_diename (a.cu); + handle_die (a.cu, &a); + dwarf_getfuncs (a.cu, &handle_die, &a, 0); + } + + dwfl_end (a.dwfl); + + return result; +} diff --git a/tests/run-low_high_pc.sh b/tests/run-low_high_pc.sh new file mode 100755 index 0000000..8d891f1 --- /dev/null +++ b/tests/run-low_high_pc.sh @@ -0,0 +1,42 @@ +#! /bin/sh +# Copyright (C) 2005 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils 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; version 2 of the License. +# +# Red Hat 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 a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/test-subr.sh + +# int +# main (int argc, char **argv) +# { +# return 0; +# } +# gcc -g -o main main.c +testfiles testfile_low_high_pc + +testrun ./low_high_pc -e ./testfile_low_high_pc +testrun ./low_high_pc -e ./low_high_pc +testrun ./low_high_pc -e ../src/strip +testrun ./low_high_pc -e ../src/strip.o +testrun ./low_high_pc -e ../libelf/libelf.so + +exit 0 diff --git a/tests/testfile_low_high_pc.bz2 b/tests/testfile_low_high_pc.bz2 new file mode 100755 index 0000000000000000000000000000000000000000..f20814aa7ec716b3a661c3e0f6519b60a1124519 GIT binary patch literal 2812 zcmV9d{+_n)f@6Zw&~MFiE{l88Vojq3JaBJv9w9 zVrqJ5^hSX_27x?+Him|n)X5Cg(|VKCz(#0#fiNQjLNve)1k)NL4F=R2no4;T{XH~> zhN=1iN2#XDZBJ3@8UO+60000D4FCWD0iXZ?00000000Bj13~~()Y5vG(oZDHHlxa7 z14BSG7@7dc4H^v|q3Ie1hol&qXatX`lemGynmupG!|chn4EQlgsTQR)?*9RmQ$B?55HA4?BFf5$dO@;QBX+7GZwoooklXosff`_6-hSz zF<6PGerYueE73xTcFKwrBN+q$2T+eytgOr5Wk;a8WJp%Yg}dP4HcQ2cN!aZ{4%{gW zawv(j{zUUGqIeLnoSx1gVHPHY73G&Z8Oal4B5<0H9rF?7SZQ}p>fTZKbW;nfxShat z@V9lkOUoLLQ(>GiFZQ)c0Eki;1R+qQ7%^HS)~P?|PJi6$>UGc{7ZcjSSht65trXCZ zP{ftZ4HwxIWUR_={+^tr7JXGn)l3Ie!6Y%&y+WXzX&G#o1YQ>iL{`AJTCc z)lhz0`%#Ou5m?vbsfKGb17PrjMtUT6CaHj1g*^((Nwh*L=4MTR*lL;xX)&>+g5v=Y z#hhsY$F!1=!6~r-xV8oR3A9b5grhd17&Mrh91x+6h5Jal`nn$xIi|$g2Evwz7z?Rl zQfpaMBqh8wB5V>%JirmsG#%SP;WV_&12*plfm~usG-;qhk#HEuL_GVrz*R9S8L8mt zM4q9LiXsvP?1cb1G z0bnwOYC}aIDfP>stHv91NwjUv5@^~v1LoW6q0<1|X^2wm;=#(y=YhaV^TUdO%e{j$ z{!{>42DA|gES^rwY9*Mv+fy0jwJd0kIqNT3J_$7&A*|U#b zb6x+@CX6)%P08V;$QEcqqKO~lku)>(%WTB-1?SGONMOO2?#QM9S^p*J^AA2NM!}6lWH>Y=cOY{hERpp^XNI7pxv2J>+fh#n>_j zFG0wW?Y?W~?o`@?z|GBLC&$z*g(zm&azTLrES-?~I_#{6k2ffG6AW9x+P(`iun-5> z_%A>X5PpSxuY#dk)mubhZVwcV6c%7LZTGa34pXk$SYpk?2WD9FwDqh{7~GrjOAZY5 z1OUMJvvo;Ozz!=L_h^^^={_(ry!kFDU1B0iRI&-kFd|$sLRf?Or)@yURkIAjMM)sT z1q-*9#*+uUz~GER2_Eca&`X(SYEXg=1V?caM-B|o5lBmijp;5QE#ObV^{01_Ek-yI zucaE0*93NAyWY@Bt}<&3kvG_3P%}`R!!)~zmGCkY9iR@$5stJ@B^yX@b&Sd= zKoDexn^Hvuh5E6evN#qt`-DTj_TdpN~qbn5^;WBT{Kr^p3g{=vh1w2 zG%_r;BP!=a7tj_{fe5ULAYko~%HpyJDFpyxrHgSV03cD>g>Pk9%tM^Bf!Xa)LwG_|} zu@^GD0IowBnZ3y|1-a71u>1tLDn!U-E$M@F&X!AN5>W^s2~^TuMK5~Q3(Y=cG^-=S7W zebW;E4%vH|yOkDMm*XcpciRjcT7S{BNiqWC?XXA zEv3g;uo$Cl^Tr(!Y8ph}k7K9ZKYrn{u?CbqSsMAs@KKHtvPobv(}e6eAp%$jgoqSi z?xwJ2-H35PkaWm|9o9I+8A;CwZHRKN6e5cYYn@0l-Xzgr2LixUQ?7stWg1%Aj*j`E zp8)RKc=Fhy^6%z^R#8);Xs3VPY{9OXy(?pRm^g8zjX6F#Vus6cTq38ZJ6aSI7ESbx z+i{5bb6dl87HxEkl+o|XIb&kvEtY#p21R-?H^)!87~@M~TFhP19pEu<21g-Z@_<+> zubm9EMuK0CBiIAV7cdFEpO=!S2X5GWBkJ< zr#mGW6AZ;tuY)?=(4!FM3luoe8hgxLLSRyZA)pt}6xf`MFVf_hTj7Sf>mNK!hUlo1 zXQt