From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 54297 invoked by alias); 26 Jul 2017 22:08:27 -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 49295 invoked by uid 89); 26 Jul 2017 22:08:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.2 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,URI_NOVOWEL autolearn=ham version=3.3.2 spammy= X-Spam-Status: No, score=-25.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,URI_NOVOWEL 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; Wed, 26 Jul 2017 22:08:21 +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 2078E302748B; Thu, 27 Jul 2017 00:08:19 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 1C55F413CD07; Thu, 27 Jul 2017 00:08:19 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH 5/9] libdw: Add dwarf_default_lower_bound. Date: Wed, 26 Jul 2017 22:08:00 -0000 Message-Id: <1501106866-5846-6-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1501106866-5846-1-git-send-email-mark@klomp.org> References: <1501106866-5846-1-git-send-email-mark@klomp.org> X-IsSubscribed: yes X-SW-Source: 2017-q3/txt/msg00051.txt.bz2 Add dwarf_default_lower_bound to get the default lower bound for a language when not given as attribute for an subrange type. Implementation extracted from dwarf_aggregate_size. Add a test to check all known language codes are handled. Signed-off-by: Mark Wielaard --- ChangeLog | 4 ++ NEWS | 1 + libdw/ChangeLog | 11 +++++ libdw/Makefile.am | 4 +- libdw/dwarf_aggregate_size.c | 54 ++--------------------- libdw/dwarf_default_lower_bound.c | 91 +++++++++++++++++++++++++++++++++++++++ libdw/dwarf_error.c | 1 + libdw/libdw.h | 6 +++ libdw/libdw.map | 1 + libdw/libdwP.h | 4 +- tests/ChangeLog | 7 +++ tests/Makefile.am | 5 ++- tests/dwarf_default_lower_bound.c | 83 +++++++++++++++++++++++++++++++++++ 13 files changed, 217 insertions(+), 55 deletions(-) create mode 100644 libdw/dwarf_default_lower_bound.c create mode 100644 tests/dwarf_default_lower_bound.c diff --git a/ChangeLog b/ChangeLog index d133061..25944f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-07-26 Mark Wielaard + + * NEWS: Mention new dwarf_default_lower_bound function. + 2017-07-25 Mark Wielaard * NEWS: Mention new DWARF5 attributes, tags, character encodings diff --git a/NEWS b/NEWS index 2039cfe..5bf0a4d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Version 0.170 libdw: Added new DWARF5 attribute, tag, character encodings constants and language codes to dwarf.h. + New function dwarf_default_lower_bound. strip: Add -R, --remove-section=SECTION and --keep-section=SECTION. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 39a9c1d..ee7dc92 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,5 +1,16 @@ 2017-07-26 Mark Wielaard + * dwarf_default_lower_bound.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_default_lower_bound.c. + * dwarf_aggregate_size.c (array_size): Use dwarf_default_lower_bound. + * dwarf_error.c (errmsgs): Add DWARF_E_UNKNOWN_LANGUAGE. + * libdw.h: Add dwarf_default_lower_bound. + * libdw.map (ELFUTILS_0.170): Add dwarf_default_lower_bound. + * libdwP.h: Add DWARF_E_UNKNOWN_LANGUAGE and + dwarf_default_lower_bound INTDECL. + +2017-07-26 Mark Wielaard + * dwarf.h: Add DW_LANG_OpenCL, DW_LANG_Modula3, DW_LANG_C_plus_plus_03, DW_LANG_OCaml, DW_LANG_Rust, DW_LANG_Swift, DW_LANG_Julia, DW_LANG_Dylan, DW_LANG_RenderScript, DW_LANG_BLISS. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index ad031b1..ff8c291 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 2002-2010, 2012, 2014 Red Hat, Inc. +## Copyright (C) 2002-2010, 2012, 2014, 2016 Red Hat, Inc. ## This file is part of elfutils. ## ## This file is free software; you can redistribute it and/or modify @@ -89,7 +89,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_peel_type.c + dwarf_cu_die.c dwarf_peel_type.c dwarf_default_lower_bound.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 0472a9b..838468d 100644 --- a/libdw/dwarf_aggregate_size.c +++ b/libdw/dwarf_aggregate_size.c @@ -95,57 +95,11 @@ array_size (Dwarf_Die *die, Dwarf_Word *size, } else { - /* Determine default lower bound from language, - as per "4.12 Subrange Type Entries". */ Dwarf_Die cu = CUDIE (die->cu); - switch (INTUSE(dwarf_srclang) (&cu)) - { - case DW_LANG_C: - case DW_LANG_C89: - case DW_LANG_C99: - case DW_LANG_C11: - case DW_LANG_C_plus_plus: - case DW_LANG_C_plus_plus_03: - case DW_LANG_C_plus_plus_11: - case DW_LANG_C_plus_plus_14: - case DW_LANG_ObjC: - case DW_LANG_ObjC_plus_plus: - case DW_LANG_Java: - case DW_LANG_D: - case DW_LANG_Python: - case DW_LANG_UPC: - case DW_LANG_OpenCL: - case DW_LANG_Go: - case DW_LANG_Haskell: - case DW_LANG_OCaml: - case DW_LANG_Rust: - case DW_LANG_Swift: - case DW_LANG_Dylan: - case DW_LANG_RenderScript: - case DW_LANG_BLISS: - lower = 0; - break; - - case DW_LANG_Ada83: - case DW_LANG_Ada95: - case DW_LANG_Cobol74: - case DW_LANG_Cobol85: - case DW_LANG_Fortran77: - case DW_LANG_Fortran90: - case DW_LANG_Fortran95: - case DW_LANG_Fortran03: - case DW_LANG_Fortran08: - case DW_LANG_Pascal83: - case DW_LANG_Modula2: - case DW_LANG_Modula3: - case DW_LANG_PLI: - case DW_LANG_Julia: - lower = 1; - break; - - default: - return -1; - } + int lang = INTUSE(dwarf_srclang) (&cu); + if (lang == -1 + || INTUSE(dwarf_default_lower_bound) (lang, &lower) != 0) + return -1; } if (unlikely (lower > upper)) return -1; diff --git a/libdw/dwarf_default_lower_bound.c b/libdw/dwarf_default_lower_bound.c new file mode 100644 index 0000000..a33a343 --- /dev/null +++ b/libdw/dwarf_default_lower_bound.c @@ -0,0 +1,91 @@ +/* Get the default subrange lower bound for a given language. + Copyright (C) 2016 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 +#include "libdwP.h" + +/* Determine default lower bound from language, as per the DWARF5 + "Subrange Type Entries" table. */ +int +dwarf_default_lower_bound (int lang, Dwarf_Sword *result) +{ + switch (lang) + { + case DW_LANG_C: + case DW_LANG_C89: + case DW_LANG_C99: + case DW_LANG_C11: + case DW_LANG_C_plus_plus: + case DW_LANG_C_plus_plus_03: + case DW_LANG_C_plus_plus_11: + case DW_LANG_C_plus_plus_14: + case DW_LANG_ObjC: + case DW_LANG_ObjC_plus_plus: + case DW_LANG_Java: + case DW_LANG_D: + case DW_LANG_Python: + case DW_LANG_UPC: + case DW_LANG_OpenCL: + case DW_LANG_Go: + case DW_LANG_Haskell: + case DW_LANG_OCaml: + case DW_LANG_Rust: + case DW_LANG_Swift: + case DW_LANG_Dylan: + case DW_LANG_RenderScript: + case DW_LANG_BLISS: + *result = 0; + return 0; + + case DW_LANG_Ada83: + case DW_LANG_Ada95: + case DW_LANG_Cobol74: + case DW_LANG_Cobol85: + case DW_LANG_Fortran77: + case DW_LANG_Fortran90: + case DW_LANG_Fortran95: + case DW_LANG_Fortran03: + case DW_LANG_Fortran08: + case DW_LANG_Pascal83: + case DW_LANG_Modula2: + case DW_LANG_Modula3: + case DW_LANG_PLI: + case DW_LANG_Julia: + *result = 1; + return 0; + + default: + __libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE); + return -1; + } +} +INTDEF (dwarf_default_lower_bound) diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c index 66fdc81..939ec04 100644 --- a/libdw/dwarf_error.c +++ b/libdw/dwarf_error.c @@ -95,6 +95,7 @@ static const char *errmsgs[] = [DWARF_E_NO_ALT_DEBUGLINK] = N_("no alternative debug link found"), [DWARF_E_INVALID_OPCODE] = N_("invalid opcode"), [DWARF_E_NOT_CUDIE] = N_("not a CU (unit) DIE"), + [DWARF_E_UNKNOWN_LANGUAGE] = N_("unknown language code") }; #define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0])) diff --git a/libdw/libdw.h b/libdw/libdw.h index 4903b55..49c4ebb 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -733,6 +733,12 @@ extern int dwarf_getlocation_attr (Dwarf_Attribute *attr, For DW_TAG_array_type it can apply much more complex rules. */ extern int dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size); +/* Given a language code, as returned by dwarf_srclan, get the default + lower bound for a subrange type without a lower bound attribute. + Returns zero on success or -1 on failure when the given language + wasn't recognized. */ +extern int dwarf_default_lower_bound (int lang, Dwarf_Sword *result) + __nonnull_attribute__ (2); /* Return scope DIEs containing PC address. Sets *SCOPES to a malloc'd array of Dwarf_Die structures, diff --git a/libdw/libdw.map b/libdw/libdw.map index 44e096a..1430705 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -341,5 +341,6 @@ ELFUTILS_0.167 { ELFUTILS_0.170 { global: + dwarf_default_lower_bound; dwarf_line_file; } ELFUTILS_0.167; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 5d095a7..6ad322c 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -1,5 +1,5 @@ /* Internal definitions for libdwarf. - Copyright (C) 2002-2011, 2013-2015 Red Hat, Inc. + Copyright (C) 2002-2011, 2013-2016 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2002. @@ -130,6 +130,7 @@ enum DWARF_E_NO_ALT_DEBUGLINK, DWARF_E_INVALID_OPCODE, DWARF_E_NOT_CUDIE, + DWARF_E_UNKNOWN_LANGUAGE, }; @@ -764,6 +765,7 @@ INTDECL (dwarf_attr_integrate) INTDECL (dwarf_begin) INTDECL (dwarf_begin_elf) INTDECL (dwarf_child) +INTDECL (dwarf_default_lower_bound) INTDECL (dwarf_dieoffset) INTDECL (dwarf_diename) INTDECL (dwarf_end) diff --git a/tests/ChangeLog b/tests/ChangeLog index 519f25a..fa3f94e 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,10 @@ +2017-07-26 Mark Wielaard + + * dwarf_default_lower_bound.c: New test. + * Makefile.am (check_PROGRAMS): Add dwarf_default_lower_bound. + (TESTS): Likewise. + (dwarf_default_lower_bound_LDADD): New variable. + 2017-07-21 Mark Wielaard * get-lines.c (main): Add dwarf_line_file test. diff --git a/tests/Makefile.am b/tests/Makefile.am index 407c051..3735084 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -55,7 +55,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ getsrc_die strptr newdata elfstrtab dwfl-proc-attach \ elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \ elfgetzdata elfputzdata zstrptr emptyfile vendorelf \ - fillfile + fillfile dwarf_default_lower_bound asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ asm-tst6 asm-tst7 asm-tst8 asm-tst9 @@ -135,7 +135,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-elfgetzdata.sh run-elfputzdata.sh run-zstrptr.sh \ run-compress-test.sh \ run-readelf-zdebug.sh run-readelf-zdebug-rel.sh \ - emptyfile vendorelf fillfile + emptyfile vendorelf fillfile dwarf_default_lower_bound if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -505,6 +505,7 @@ zstrptr_LDADD = $(libelf) emptyfile_LDADD = $(libelf) vendorelf_LDADD = $(libelf) fillfile_LDADD = $(libelf) +dwarf_default_lower_bound_LDADD = $(libdw) # We want to test the libelf header against the system elf.h header. # Don't include any -I CPPFLAGS. diff --git a/tests/dwarf_default_lower_bound.c b/tests/dwarf_default_lower_bound.c new file mode 100644 index 0000000..d57424f --- /dev/null +++ b/tests/dwarf_default_lower_bound.c @@ -0,0 +1,83 @@ +/* Test all DW_LANG constants are handled by dwarf_default_lower_bound. + + Copyright (C) 2016 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 the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 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 this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(dw) +#include "../libdw/known-dwarf.h" + +#include +#include +#include + +static void +test_lang (const char *name, int lang) +{ + Dwarf_Sword low; + int res = dwarf_default_lower_bound (lang, &low); + + /* Assembler is special, it doesn't really have arrays. */ + if (lang == DW_LANG_Mips_Assembler) + { + if (res == 0) + { + printf ("%s shouldn't have a known lower bound\n", name); + exit (-1); + } + printf ("%s: \n", name); + return; + } + + if (res != 0) + { + printf ("dwarf_default_lower_bound failed (%d) for %s\n", res, name); + exit (-1); + } + + /* All currently known lower bounds are either zero or one, but + they don't have to. Update test once one is a different value. */ + if (low != 0 && low != 1) + { + printf ("unexpected lower bound %" PRId64 " for %s\n", low, name); + exit (-1); + } + + printf ("%s: %" PRId64 "\n", name, low); +} + +int +main (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) +{ + Dwarf_Sword low; + /* Bad language code must fail. */ + if (dwarf_default_lower_bound (-1, &low) == 0) + { + printf ("Bad lang code -1 succeeded (%" PRId64 ")\n", low); + exit (-1); + } + + /* Test all known language codes. */ +#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) test_lang (#NAME, CODE); + DWARF_ALL_KNOWN_DW_LANG +#undef DWARF_ONE_KNOWN_DW_LANG + + return 0; +} -- 1.8.3.1