From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 97847 invoked by alias); 18 May 2018 10:58:51 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 97818 invoked by uid 89); 18 May 2018 10:58:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=2004, asz, stddefh, stddef.h X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 May 2018 10:58:47 +0000 Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 3D537302BB04; Fri, 18 May 2018 12:58:44 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 119CE4000707; Fri, 18 May 2018 12:58:44 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH] libdw: Handle split dwarf debuglines. Date: Fri, 18 May 2018 10:58:00 -0000 Message-Id: <1526641119-31816-1-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2018-q2/txt/msg00057.txt.bz2 Split DWARF .dwo files do contain a .debug_line section, but only with the file table, there is no actual line program. Also split DWARF CU DIEs don't have a DW_AT_stmt_list attribute. To get at the file (and dir) table for a split unit DIE take just the files from the .debug_line section (at offset zero). To get the full line table use the skeleton DIE (which does have a DW_AT_stmt_list). Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 9 +++++++ libdw/dwarf_getsrcfiles.c | 50 ++++++++++++++++++++++++++++------- libdw/dwarf_getsrclines.c | 25 ++++++++++++++++++ libdw/libdw_findcu.c | 1 + tests/ChangeLog | 6 +++++ tests/run-get-files.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 9 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 0a0728b..e067827 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,12 @@ +2018-05-18 Mark Wielaard + + * libdw_findcu.c (__libdw_intern_next_unit): Init files to NULL. + * dwarf_getsrclines.c (dwarf_getsrclines): Handle split units by + taking the line table from the skeleton. + * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Handle split units by + only taking the files from .debug_line offset zero (if it exists), + otherwise fall back to the skeleton. + 2018-05-17 Mark Wielaard * dwarf_begin_elf.c (__libdw_debugdir): New function. diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c index 5af6f68..12fdabf 100644 --- a/libdw/dwarf_getsrcfiles.c +++ b/libdw/dwarf_getsrcfiles.c @@ -1,7 +1,6 @@ /* Return source file information of CU. - Copyright (C) 2004, 2005, 2013, 2015 Red Hat, Inc. + Copyright (C) 2004, 2005, 2013, 2015, 2018 Red Hat, Inc. This file is part of elfutils. - Written by Ulrich Drepper , 2004. This file is free software; you can redistribute it and/or modify it under the terms of either @@ -51,14 +50,47 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles) /* Get the information if it is not already known. */ struct Dwarf_CU *const cu = cudie->cu; - if (cu->lines == NULL) + if (cu->files == NULL) { - Dwarf_Lines *lines; - size_t nlines; - - /* Let the more generic function do the work. It'll create more - data but that will be needed in an real program anyway. */ - res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines); + /* For split units there might be a simple file table (without lines). + If not, use the one from the skeleton. */ + if (cu->unit_type == DW_UT_split_compile + || cu->unit_type == DW_UT_split_type) + { + /* We tried, assume we fail... */ + cu->files = (void *) -1; + + /* See if there is a .debug_line section, for split CUs + the table is at offset zero. */ + if (cu->dbg->sectiondata[IDX_debug_line] != NULL) + { + /* We are only interested in the files, the lines will + always come from the skeleton. */ + res = __libdw_getsrclines (cu->dbg, 0, + __libdw_getcompdir (cudie), + cu->address_size, NULL, + &cu->files); + } + else + { + Dwarf_CU *skel = __libdw_find_split_unit (cu); + if (skel != NULL) + { + Dwarf_Die skeldie = CUDIE (skel); + res = INTUSE(dwarf_getsrcfiles) (&skeldie, files, nfiles); + cu->files = skel->files; + } + } + } + else + { + Dwarf_Lines *lines; + size_t nlines; + + /* Let the more generic function do the work. It'll create more + data but that will be needed in an real program anyway. */ + res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines); + } } else if (cu->files != (void *) -1l) /* We already have the information. */ diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 2f966ab..2bf3098 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -1147,6 +1147,31 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) struct Dwarf_CU *const cu = cudie->cu; if (cu->lines == NULL) { + /* For split units always pick the lines from the skeleton. */ + if (cu->unit_type == DW_UT_split_compile + || cu->unit_type == DW_UT_split_type) + { + /* We tries, assume we fail... */ + cu->lines = (void *) -1l; + + Dwarf_CU *skel = __libdw_find_split_unit (cu); + if (skel != NULL) + { + Dwarf_Die skeldie = CUDIE (skel); + int res = INTUSE(dwarf_getsrclines) (&skeldie, lines, nlines); + if (res == 0) + { + cu->lines = skel->lines; + *lines = cu->lines; + *nlines = cu->lines->nlines; + } + return res; + } + + __libdw_seterrno (DWARF_E_NO_DEBUG_LINE); + return -1; + } + /* Failsafe mode: no data found. */ cu->lines = (void *) -1l; cu->files = (void *) -1l; diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index d6975f3..d22ddae 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -114,6 +114,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->subdie_offset = subdie_offset; Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41); newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; + newp->files = NULL; newp->lines = NULL; newp->locs = NULL; newp->split = (Dwarf_CU *) -1; diff --git a/tests/ChangeLog b/tests/ChangeLog index 05e8f26..0370fbc 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2018-05-18 Mark Wielaard + + * run-get-files.sh: Add testcases for testfile-splitdwarf-4, + testfile-hello4.dwo, testfile-world4.dwo and testfile-splitdwarf-5, + testfile-hello5.dwo, testfile-world5.dwo. + 2018-05-17 Mark Wielaard * Makefile.am (check_PROGRAMS): Add attr-integrate-skel. diff --git a/tests/run-get-files.sh b/tests/run-get-files.sh index a2f2373..6f90be7 100755 --- a/tests/run-get-files.sh +++ b/tests/run-get-files.sh @@ -64,4 +64,70 @@ cuhl = 11, o = 267, asz = 4, osz = 4, ncu = 2680 file[1] = "/shoggoth/drepper/m.c" EOF +# see tests/testfile-dwarf-45.source +testfiles testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo +testfiles testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo + +testrun_compare ${abs_builddir}/get-files testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo <<\EOF +cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 52 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include" + file[0] = "???" + file[1] = "/home/mark/src/elfutils/tests/hello.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h" +cuhl = 11, o = 26, asz = 8, osz = 4, ncu = 104 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/usr/include" + file[0] = "???" + file[1] = "/home/mark/src/elfutils/tests/world.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/usr/include/stdlib.h" +cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 414 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include" + file[0] = "???" + file[1] = "/home/mark/src/elfutils/tests/hello.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h" +cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 331 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/usr/include" + file[0] = "???" + file[1] = "/home/mark/src/elfutils/tests/world.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/usr/include/stdlib.h" +EOF + +testrun_compare ${abs_builddir}/get-files testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo <<\EOF +cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 53 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include" + file[0] = "/home/mark/src/elfutils/tests/hello.c" + file[1] = "/home/mark/src/elfutils/tests/hello.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h" +cuhl = 20, o = 21, asz = 8, osz = 4, ncu = 106 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/usr/include" + file[0] = "/home/mark/src/elfutils/tests/world.c" + file[1] = "/home/mark/src/elfutils/tests/world.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/usr/include/stdlib.h" +cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 386 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include" + file[0] = "/home/mark/src/elfutils/tests/hello.c" + file[1] = "/home/mark/src/elfutils/tests/hello.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h" +cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 296 + dirs[0] = "/home/mark/src/elfutils/tests" + dirs[1] = "/usr/include" + file[0] = "/home/mark/src/elfutils/tests/world.c" + file[1] = "/home/mark/src/elfutils/tests/world.c" + file[2] = "/home/mark/src/elfutils/tests/hello.h" + file[3] = "/usr/include/stdlib.h" +EOF + exit 0 -- 1.8.3.1