From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-0010f301.pphosted.com (mx0b-0010f301.pphosted.com [148.163.153.244]) by sourceware.org (Postfix) with ESMTPS id 35F0D3858405 for ; Fri, 10 Sep 2021 15:49:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 35F0D3858405 Received: from pps.filterd (m0102858.ppops.net [127.0.0.1]) by mx0b-0010f301.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18A9UjMM021374 for ; Fri, 10 Sep 2021 10:49:33 -0500 Received: from mx1.mail.rice.edu (smtp2.mail.rice.edu [128.42.201.100]) by mx0b-0010f301.pphosted.com with ESMTP id 3aytp50rr3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 10 Sep 2021 10:49:32 -0500 Received: from mx1.mail.rice.edu (localhost [127.0.0.1]) by mx1.mail.rice.edu (Postfix) with ESMTP id 7894641D203 for ; Fri, 10 Sep 2021 10:49:32 -0500 (CDT) Received: from localhost (localhost [127.0.0.1]) by mx1.mail.rice.edu (Postfix) with ESMTP id 76B4041D200; Fri, 10 Sep 2021 10:49:32 -0500 (CDT) X-Virus-Scanned: by amavis-2.12.1 at mx1.mail.rice.edu, auth channel Received: from mx1.mail.rice.edu ([127.0.0.1]) by localhost (mx1.mail.rice.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 5wnSAPVz02SZ; Fri, 10 Sep 2021 10:49:26 -0500 (CDT) Received: from [192.168.50.202] (c-98-200-175-18.hsd1.tx.comcast.net [98.200.175.18]) (using TLSv1.2 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: johnmc@rice.edu) by mx1.mail.rice.edu (Postfix) with ESMTPSA id 18A4A2014E7; Fri, 10 Sep 2021 10:49:25 -0500 (CDT) From: John Mellor-Crummey Message-Id: <37B899F3-FD5F-4F7B-9F1B-BE63CF84F554@rice.edu> Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\)) Subject: [PATCH] read inlining info in an NVIDIA extended line map (was: Extension ...) Date: Fri, 10 Sep 2021 10:49:24 -0500 In-Reply-To: <7C166312-4876-444F-9B85-C7E30C8F4959@rice.edu> Cc: John Mellor-Crummey , Xiaozhu Meng To: elfutils-devel@sourceware.org References: <7C166312-4876-444F-9B85-C7E30C8F4959@rice.edu> X-Mailer: Apple Mail (2.3608.120.23.2.4) X-Proofpoint-ORIG-GUID: Xz521u_M5FjAvGg3zg3zqOLJzgQJSGo2 X-Proofpoint-GUID: Xz521u_M5FjAvGg3zg3zqOLJzgQJSGo2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.391,FMLib:17.0.607.475 definitions=2021-09-10_06,2021-09-09_01,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 malwarescore=0 suspectscore=0 phishscore=0 adultscore=0 clxscore=1015 mlxlogscore=999 lowpriorityscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2109030001 definitions=main-2109100091 X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, KAM_LOTSOFHASH, KAM_SHORT, MANY_SPAN_IN_TEXT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Sep 2021 15:49:44 -0000 My previous patch submission seems to have been overlooked as buildbot = issues consumed several days this week. However, discussion in the = mailing list now seems to have moved on beyond my submission and I would = like my patch considered. Here, I echo my previous submission, except I = improved my submission by including the prefix [PATCH] in the subject = and I included the patch in the message body rather than as an = attachment. Regarding the DWARF proposal by Cary Coutant for two-level linemaps: I = now believe that NVIDIA=E2=80=99s implementation is consistent with that = proposal although NVIDIA uses a DWARF extended opcode for inlined calls = whereas Cary=E2=80=99s proposal uses DW_LNS_inlined_call (a standard = opcode), NVIDIA=E2=80=99s implementation uses DW_LNE_inlined_call (an = extended opcode). A note about the source code for the test case reading the extended = linemap entries using libdw: this code was copied from another test that = used dwarf_next_lines and extended with code that reads the new context = and functionname fields of a line table entry. -- John Mellor-Crummey Professor Dept of Computer Science Rice University email: johnmc@rice.edu phone: 713-348-5179 > On Sep 5, 2021, at 7:07 PM, John Mellor-Crummey = wrote: >=20 > As of CUDA 11.2, NVIDIA added extensions to the line map section > of CUDA binaries to represent inlined functions. These extensions > include >=20 > - two new fields in a line table row to represent inline=20 > information: context, and functionname, >=20 > - two new DWARF extended opcodes: DW_LNE_inlined_call,=20 > DW_LNE_set_function_name, >=20 > - an additional word in the line table header that indicates=20 > the offset in the .debug_str function where the function=20 > names for this line table begin, and >=20 > - two new functions in the libdw API: dwarf_linecontext and=20 > dwarf_linefunctionname, which return the new line table fields. >=20 > A line table row for an inlined function contains a non-zero > "context" value. The =E2=80=9Ccontext=E2=80=9D field indicates the = index of the > line table row that serves as the call site for an inlined > context. >=20 > The "functionname" field in a line table row is only meaningful > if the "context" field of the row is non-zero. A meaningful > "functionname" field contains an index into the .debug_str > section relative to the base offset established in the line table > header; the position in the .debug_str section indicates the name > of the inlined function. >=20 > These extensions resemble the proposed DWARF extensions > (http://dwarfstd.org/ShowIssue.php?issue=3D140906.1) by Cary > Coutant, but are not identical. >=20 > This patch adds integrates support for handling NVIDIA's extended > line maps into elfutil's libdw library and the readelf command > line utility. >=20 > Since this support is a non-standard extension to DWARF, all code > that implements the extensions is implemented between markers =20 > /* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ and=20 > /* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */. >=20 > The definition below >=20 > #define NVIDIA_LINEMAP_INLINING_EXTENSIONS 1 >=20 > is added to elfutils/version.h, which enables a client of elfutils=20 > to test whether the NVIDIA line map extensions are present.=20 >=20 > Note: The support for NVIDIA extended line maps adds two integer > fields (context and functionname) to struct Dwarf_Line_s, which > makes the structure about 30% larger. >=20 > The patch includes a binary testfile_nvidia_linemap.bz2 that > contains an NVIDIA extended linemap along with two tests that > read the line map. >=20 > - A test script run-nvidia-extended-linemap-readelf.sh=20 > checks the output of readelf on the new test binary to=20 > validate its dump of the line op codes containing context=20 > and functionname entries. >=20 > - A test program tests/nvidia_extended_linemap_libdw.c reads=20 > the extended line map with dwarf_next_lines and dumps the=20 > context and functionname fields of the line map where they=20 > are relevant, i.e. the value of context is non-zero. A test=20 > script run-nvidia-extended-linemap-libdw.sh runs this test=20 > and validates its output. >=20 > A patch with the new functionality described above is attached. > -- > John Mellor-Crummey Professor > Dept of Computer Science Rice University > email: johnmc@rice.edu phone: 713-348-5179 =46rom 32e6b3530677bcbb595ba9010d49feef03314bd4 Mon Sep 17 00:00:00 2001 From: John M Mellor-Crummey Date: Fri, 3 Sep 2021 16:13:40 -0500 Subject: [PATCH] Read inlining info in NVIDIA extended line map Signed-off-by: John M Mellor-Crummey --- ChangeLog | 4 + config/version.h.in | 4 + libdw/Makefile.am | 1 + libdw/dwarf.h | 4 + libdw/dwarf_getsrclines.c | 52 ++++++- libdw/dwarf_linecontext.c | 47 ++++++ libdw/dwarf_linefunctionname.c | 47 ++++++ libdw/libdw.h | 12 ++ libdw/libdw.map | 2 + libdw/libdwP.h | 4 + src/readelf.c | 46 ++++++ tests/Makefile.am | 3 + tests/nvidia_extended_linemap_libdw.c | 153 +++++++++++++++++++ tests/run-nvidia-extended-linemap-libdw.sh | 41 +++++ tests/run-nvidia-extended-linemap-readelf.sh | 114 ++++++++++++++ tests/testfile_nvidia_linemap.bz2 | Bin 0 -> 2365 bytes 16 files changed, 533 insertions(+), 1 deletion(-) create mode 100644 libdw/dwarf_linecontext.c create mode 100644 libdw/dwarf_linefunctionname.c create mode 100644 tests/nvidia_extended_linemap_libdw.c create mode 100755 tests/run-nvidia-extended-linemap-libdw.sh create mode 100755 tests/run-nvidia-extended-linemap-readelf.sh create mode 100644 tests/testfile_nvidia_linemap.bz2 diff --git a/ChangeLog b/ChangeLog index 6255fe61..d4b89f9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2021-09-03 John Mellor-Crummey + + * NEWS: Read inlining info in NVIDIA extended line map + 2021-08-10 Adrian Ratiu =20 * configure.ac (AC_CACHE_CHECK): Rework std=3Dgnu99 check to = allow clang. diff --git a/config/version.h.in b/config/version.h.in index 34e62c3b..8b30d144 100644 --- a/config/version.h.in +++ b/config/version.h.in @@ -35,4 +35,8 @@ #define _ELFUTILS_PREREQ(major, minor) \ (_ELFUTILS_VERSION >=3D ((major) * 1000 + (minor))) =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ +#define NVIDIA_LINEMAP_INLINING_EXTENSIONS 1 +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + #endif /* elfutils/version.h */ diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 6b7834af..4fda33bd 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -63,6 +63,7 @@ libdw_a_SOURCES =3D dwarf_begin.c dwarf_begin_elf.c = dwarf_end.c dwarf_getelf.c \ dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ dwarf_linecol.c dwarf_linebeginstatement.c \ dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_linecontext.c dwarf_linefunctionname.c \ dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ dwarf_lineisa.c dwarf_linediscriminator.c \ dwarf_lineop_index.c dwarf_line_file.c \ diff --git a/libdw/dwarf.h b/libdw/dwarf.h index 19a4be96..2faf852a 100644 --- a/libdw/dwarf.h +++ b/libdw/dwarf.h @@ -844,6 +844,10 @@ enum DW_LNE_set_discriminator =3D 4, =20 DW_LNE_lo_user =3D 128, + /* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + DW_LNE_inlined_call =3D 144, + DW_LNE_set_function_name =3D 145, + /* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ DW_LNE_hi_user =3D 255 }; =20 diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index d6a581ad..d7907d4d 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -93,6 +93,10 @@ struct line_state struct linelist *linelist; size_t nlinelist; unsigned int end_sequence; +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + unsigned int context; + unsigned int function_name; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ }; =20 static inline void @@ -139,6 +143,10 @@ add_new_line (struct line_state *state, struct = linelist *new_line) SET (epilogue_begin); SET (isa); SET (discriminator); +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + SET (context); + SET (function_name); +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ =20 #undef SET =20 @@ -165,6 +173,13 @@ read_srclines (Dwarf *dbg, #define MAX_STACK_FILES (MAX_STACK_ALLOC / 4) #define MAX_STACK_DIRS (MAX_STACK_ALLOC / 16) =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + /* reduce the MAX_STACK_LINES when using NVIDIA linemap inlining = extensions, which + increase the size of the line structure by two unsigned int */ +#undef MAX_STACK_LINES +#define MAX_STACK_LINES (MAX_STACK_ALLOC / 2) +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + /* Initial statement program state (except for stmt_list, see below). = */ struct line_state state =3D { @@ -180,7 +195,11 @@ read_srclines (Dwarf *dbg, .prologue_end =3D false, .epilogue_begin =3D false, .isa =3D 0, - .discriminator =3D 0 + .discriminator =3D 0, +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + .context =3D 0, + .function_name =3D 0 +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ }; =20 /* The dirs normally go on the stack, but if there are too many @@ -648,6 +667,14 @@ read_srclines (Dwarf *dbg, } } =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + unsigned int debug_str_offset __attribute__((unused)) =3D 0; + if (unlikely (linep < header_start + header_length)) { + /* CUBINs contain an unsigned 4-byte offset */ + debug_str_offset =3D read_4ubyte_unaligned_inc (dbg, linep); + } +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + /* Consistency check. */ if (unlikely (linep !=3D header_start + header_length)) { @@ -753,6 +780,10 @@ read_srclines (Dwarf *dbg, state.epilogue_begin =3D false; state.isa =3D 0; state.discriminator =3D 0; +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + state.context =3D 0; + state.function_name =3D 0; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ break; =20 case DW_LNE_set_address: @@ -831,6 +862,25 @@ read_srclines (Dwarf *dbg, get_uleb128 (state.discriminator, linep, lineendp); break; =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + case DW_LNE_inlined_call: + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + get_uleb128 (state.context, linep, lineendp); + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + get_uleb128 (state.function_name, linep, lineendp); + state.function_name +=3D debug_str_offset; + break; + + case DW_LNE_set_function_name: + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + get_uleb128 (state.function_name, linep, lineendp); + state.function_name +=3D debug_str_offset; + break; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + default: /* Unknown, ignore it. */ if (unlikely ((size_t) (lineendp - (linep - 1)) < len)) diff --git a/libdw/dwarf_linecontext.c b/libdw/dwarf_linecontext.c new file mode 100644 index 00000000..f1c78dfd --- /dev/null +++ b/libdw/dwarf_linecontext.c @@ -0,0 +1,47 @@ +/* Return context in line. + This file is part of elfutils. + Written by John Mellor-Crummey , 2021. + + 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" + + +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ +int +dwarf_linecontext (Dwarf_Line *line, unsigned int *contextp) +{ + if (line =3D=3D NULL) + return -1; + + *contextp =3D line->context; + + return 0; +} +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ diff --git a/libdw/dwarf_linefunctionname.c = b/libdw/dwarf_linefunctionname.c new file mode 100644 index 00000000..a7027135 --- /dev/null +++ b/libdw/dwarf_linefunctionname.c @@ -0,0 +1,47 @@ +/* Return function name in line. + This file is part of elfutils. + Written by John Mellor-Crummey , 2021. + + 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" + + +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ +int +dwarf_linefunctionname (Dwarf_Line *line, unsigned int *functionnamep) +{ + if (line =3D=3D NULL) + return -1; + + *functionnamep =3D line->function_name; + + return 0; +} +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ diff --git a/libdw/libdw.h b/libdw/libdw.h index 77174d28..730f9338 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -701,6 +701,18 @@ extern int dwarf_linediscriminator (Dwarf_Line = *line, unsigned int *discp) extern const char *dwarf_linesrc (Dwarf_Line *line, Dwarf_Word *mtime, Dwarf_Word = *length); =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ +/* NVIDIA extension: Return inline context in this record. A non-zero = context + value represents an inline context */ +extern int dwarf_linecontext (Dwarf_Line *line, unsigned int = *contextp); + +/* NVIDIA extension: Return function name in this record. When context = is + non-zero, the value of function name is an offset into the = .debug_str section, + which contains a character string that specifies the name of an = inlined + function. */ +extern int dwarf_linefunctionname (Dwarf_Line *line, unsigned int = *functionnamep); +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + /* Return file information. The returned string is NULL when an error occurred, or the file path. The file path is either = absolute or relative to the compilation directory. See dwarf_decl_file. */ diff --git a/libdw/libdw.map b/libdw/libdw.map index 8ab0a2a0..2505cd46 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -67,8 +67,10 @@ ELFUTILS_0.122 { dwarf_linebeginstatement; dwarf_lineblock; dwarf_linecol; + dwarf_linecontext; dwarf_lineendsequence; dwarf_lineepiloguebegin; + dwarf_linefunctionname; dwarf_lineno; dwarf_lineprologueend; dwarf_linesrc; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 7174ea93..d8fa7e7e 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -291,6 +291,10 @@ struct Dwarf_Line_s unsigned int op_index:8; unsigned int isa:8; unsigned int discriminator:24; +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + unsigned int context; + unsigned int function_name; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ }; =20 struct Dwarf_Lines_s diff --git a/src/readelf.c b/src/readelf.c index 8191bde2..050f2592 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -8481,6 +8481,9 @@ print_debug_line_section (Dwfl_Module *dwflmod, = Ebl *ebl, GElf_Ehdr *ehdr, goto invalid_data; header_length =3D read_8ubyte_unaligned_inc (dbg, linep); } +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + const unsigned char *header_start =3D linep; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ =20 /* Next the minimum instruction length. */ if ((size_t) (lineendp - linep) < 1) @@ -8765,6 +8768,14 @@ print_debug_line_section (Dwfl_Module *dwflmod, = Ebl *ebl, GElf_Ehdr *ehdr, ++linep; } =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + unsigned int debug_str_offset __attribute__((unused)) =3D 0; + if (unlikely (linep < header_start + header_length)) { + /* CUBINs contain an unsigned 4-byte offset */ + debug_str_offset =3D read_4ubyte_unaligned_inc (dbg, linep); + } +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + if (linep =3D=3D lineendp) { puts (_("\nNo line number statements.")); @@ -8913,6 +8924,41 @@ print_debug_line_section (Dwfl_Module *dwflmod, = Ebl *ebl, GElf_Ehdr *ehdr, printf (_(" set discriminator to %u\n"), u128); break; =20 +/* Begin NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + case DW_LNE_inlined_call: + { + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + + unsigned int context; + get_uleb128 (context, linep, lineendp); + + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + + unsigned int function_name; + get_uleb128 (function_name, linep, lineendp); + function_name +=3D debug_str_offset; + + printf (_(" inlined context %u, function name 0x%x = \n"), + context, function_name); + break; + } + + case DW_LNE_set_function_name: + { + if (unlikely (linep >=3D lineendp)) + goto invalid_data; + + unsigned int function_name; + get_uleb128 (function_name, linep, lineendp); + function_name +=3D debug_str_offset; + + printf (_(" set function name %u\n"), = function_name); + } + break; +/* End NVIDIA_LINEMAP_INLINING_EXTENSIONS */ + default: /* Unknown, ignore it. */ puts (_(" unknown opcode")); diff --git a/tests/Makefile.am b/tests/Makefile.am index c586422e..263d6bc5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -61,6 +61,7 @@ check_PROGRAMS =3D arextract arsymtest newfile saridx = scnnames sectiondump \ dwelf_elf_e_machine_string \ getphdrnum leb128 read_unaligned \ msg_tst system-elf-libelf-test \ + nvidia_extended_linemap_libdw \ $(asm_TESTS) =20 asm_TESTS =3D asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ @@ -189,6 +190,7 @@ TESTS =3D run-arextract.sh run-arsymtest.sh = run-ar.sh newfile test-nlist \ leb128 read_unaligned \ msg_tst system-elf-libelf-test \ $(asm_TESTS) run-disasm-bpf.sh = run-low_high_pc-dw-form-indirect.sh \ + run-nvidia-extended-linemap-libdw.sh = run-nvidia-extended-linemap-readelf.sh \ run-readelf-dw-form-indirect.sh run-strip-largealign.sh =20 if !BIARCH @@ -725,6 +727,7 @@ dwelf_elf_e_machine_string_LDADD =3D $(libelf) = $(libdw) getphdrnum_LDADD =3D $(libelf) $(libdw) leb128_LDADD =3D $(libelf) $(libdw) read_unaligned_LDADD =3D $(libelf) $(libdw) +nvidia_extended_linemap_libdw_LDADD =3D $(libelf) $(libdw) =20 # We want to test the libelf header against the system elf.h header. # Don't include any -I CPPFLAGS. Except when we install our own elf.h. diff --git a/tests/nvidia_extended_linemap_libdw.c = b/tests/nvidia_extended_linemap_libdw.c new file mode 100644 index 00000000..9f1e5efd --- /dev/null +++ b/tests/nvidia_extended_linemap_libdw.c @@ -0,0 +1,153 @@ +/* Inspect nvidia extended linemap with dwarf_next_lines. + Copyright (C) 2002, 2004, 2018 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 +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include + + +int +main (int argc, char *argv[]) +{ + int result =3D 0; + int cnt; + + for (cnt =3D 1; cnt < argc; ++cnt) + { + int fd =3D open (argv[cnt], O_RDONLY); + + Dwarf *dbg =3D dwarf_begin (fd, DWARF_C_READ); + if (dbg =3D=3D NULL) + { + printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1)); + close (fd); + continue; + } + + Dwarf_Off off; + Dwarf_Off next_off =3D 0; + Dwarf_CU *cu =3D NULL; + Dwarf_Lines *lb; + size_t nlb; + int res; + while ((res =3D dwarf_next_lines (dbg, off =3D next_off, = &next_off, &cu, + NULL, NULL, &lb, &nlb)) =3D=3D 0) + { + printf ("off =3D %" PRIu64 "\n", off); + printf (" %zu lines\n", nlb); + + for (size_t i =3D 0; i < nlb; ++i) + { + Dwarf_Line *l =3D dwarf_onesrcline (lb, i); + if (l =3D=3D NULL) + { + printf ("%s: cannot get individual line\n", = argv[cnt]); + result =3D 1; + break; + } + + Dwarf_Addr addr; + if (dwarf_lineaddr (l, &addr) !=3D 0) + addr =3D 0; + const char *file =3D dwarf_linesrc (l, NULL, NULL); + int line; + if (dwarf_lineno (l, &line) !=3D 0) + line =3D 0; + + printf ("%" PRIx64 ": %s:%d:", (uint64_t) addr, + file ?: "???", line); + + /* Getting the file path through the Dwarf_Files should + result in the same path. */ + Dwarf_Files *files; + size_t idx; + if (dwarf_line_file (l, &files, &idx) !=3D 0) + { + printf ("%s: cannot get file from line (%zd): %s\n", + argv[cnt], i, dwarf_errmsg (-1)); + result =3D 1; + break; + } + const char *path =3D dwarf_filesrc (files, idx, NULL, = NULL); + if ((path =3D=3D NULL && file !=3D NULL) + || (path !=3D NULL && file =3D=3D NULL) + || (strcmp (file, path) !=3D 0)) + { + printf ("%s: line %zd srcline (%s) !=3D file srcline = (%s)\n", + argv[cnt], i, file ?: "???", path ?: "???"); + result =3D 1; + break; + } + + int column; + if (dwarf_linecol (l, &column) !=3D 0) + column =3D 0; + if (column >=3D 0) + printf ("%d:", column); + + unsigned int context; + if (dwarf_linecontext (l, &context) !=3D 0) + context =3D 0; + unsigned int functionname; + if (dwarf_linefunctionname (l, &functionname) !=3D 0) + functionname =3D 0; + if (context > 0) { + printf (" context:%u, functionname:%u,", context, = functionname); + } + + bool is_stmt; + if (dwarf_linebeginstatement (l, &is_stmt) !=3D 0) + is_stmt =3D false; + bool end_sequence; + if (dwarf_lineendsequence (l, &end_sequence) !=3D 0) + end_sequence =3D false; + bool basic_block; + if (dwarf_lineblock (l, &basic_block) !=3D 0) + basic_block =3D false; + bool prologue_end; + if (dwarf_lineprologueend (l, &prologue_end) !=3D 0) + prologue_end =3D false; + bool epilogue_begin; + if (dwarf_lineepiloguebegin (l, &epilogue_begin) !=3D 0) + epilogue_begin =3D false; + printf (" is_stmt:%s, end_seq:%s, bb:%s, prologue:%s, = epilogue:%s\n", + is_stmt ? "yes" : "no", end_sequence ? "yes" : = "no", + basic_block ? "yes" : "no", prologue_end ? "yes" = : "no", + epilogue_begin ? "yes" : "no"); + } + } + + if (res < 0) + { + printf ("dwarf_next_lines failed: %s\n", dwarf_errmsg (-1)); + result =3D 1; + } + + dwarf_end (dbg); + close (fd); + } + + return result; +} diff --git a/tests/run-nvidia-extended-linemap-libdw.sh = b/tests/run-nvidia-extended-linemap-libdw.sh new file mode 100755 index 00000000..b0386b49 --- /dev/null +++ b/tests/run-nvidia-extended-linemap-libdw.sh @@ -0,0 +1,41 @@ +# Copyright (C) 2011 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 . + +. $srcdir/test-subr.sh + +testfiles testfile_nvidia_linemap +testrun_compare ${abs_top_builddir}/tests/nvidia_extended_linemap_libdw = testfile_nvidia_linemap << EOF +off =3D 0 + 18 lines +0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:25:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +10: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:26:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +40: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:27:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +90: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:25:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +a0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:28:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +100: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:28:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +100: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:8:0: = context:6, functionname:0, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +150: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:9:0: = context:6, functionname:0, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +1e0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:31:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +1e0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/bar.h:6:0: = context:9, functionname:4, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +1e0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:8:0: = context:10, functionname:0, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +220: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:9:0: = context:10, functionname:0, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +2b0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/bar.h:7:0: = context:9, functionname:4, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +2f0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/bar.h:8:0: = context:9, functionname:4, is_stmt:yes, end_seq:no, bb:no, prologue:no, = epilogue:no +2f0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:18:0:= context:14, functionname:8, is_stmt:yes, end_seq:no, bb:no, = prologue:no, epilogue:no +330: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:19:0:= context:14, functionname:8, is_stmt:yes, end_seq:no, bb:no, = prologue:no, epilogue:no +3c0: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:33:0:= is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no +480: = /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4/main.cu:33:0:= is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no +EOF diff --git a/tests/run-nvidia-extended-linemap-readelf.sh = b/tests/run-nvidia-extended-linemap-readelf.sh new file mode 100755 index 00000000..6ad96027 --- /dev/null +++ b/tests/run-nvidia-extended-linemap-readelf.sh @@ -0,0 +1,114 @@ +# Copyright (C) 2011 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 . + +. $srcdir/test-subr.sh + +testfiles testfile_nvidia_linemap +testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=3Dline = testfile_nvidia_linemap << EOF + +DWARF section [ 5] '.debug_line' at offset 0x3e0: + +Table at offset 0: + + Length: 253 + DWARF version: 2 + Prologue length: 111 + Address size: 8 + Segment selector size: 0 + Min instruction length: 1 + Max operations per instruction: 1 + Initial value if 'is_stmt': 1 + Line base: -5 + Line range: 14 + Opcode base: 10 + +Opcodes: + [1] 0 arguments + [2] 1 argument + [3] 1 argument + [4] 1 argument + [5] 1 argument + [6] 0 arguments + [7] 0 arguments + [8] 0 arguments + [9] 1 argument + +Directory table: + /home/johnmc/hpctoolkit-gpu-samples/nvidia_extended_linemap4 + +File name table: + Entry Dir Time Size Name + 1 1 1626104146 1819 main.cu + 2 1 1626104111 211 bar.h + +Line number statements: + [ 79] extended opcode 2: set address to 0 + [ 84] set file to 1 + [ 86] advance line by constant 24 to 25 + [ 88] copy + [ 89] special opcode 240: address+16 =3D 0x10 , line+1 = =3D 26 + [ 8a] advance line by constant 1 to 27 + [ 8c] advance address by 48 to 0x40 + [ 8e] copy + [ 8f] advance line by constant -2 to 25 + [ 91] advance address by 80 to 0x90 + [ 94] copy + [ 95] special opcode 242: address+16 =3D 0xa0 , line+3 = =3D 28 + [ 96] advance address by 96 to 0x100 + [ 99] copy + [ 9a] extended opcode 144: inlined context 6, function name 0x0=20 + [ 9f] advance line by constant -20 to 8 + [ a1] copy + [ a2] advance line by constant 1 to 9 + [ a4] advance address by 80 to 0x150 + [ a7] copy + [ a8] extended opcode 144: inlined context 0, function name 0x0=20 + [ ad] advance line by constant 22 to 31 + [ af] advance address by 144 to 0x1e0 + [ b2] copy + [ b3] set file to 2 + [ b5] extended opcode 144: inlined context 9, function name 0x4=20 + [ ba] advance line by constant -25 to 6 + [ bc] copy + [ bd] set file to 1 + [ bf] extended opcode 144: inlined context 10, function name 0x0=20= + [ c4] advance line by constant 2 to 8 + [ c6] copy + [ c7] advance line by constant 1 to 9 + [ c9] advance address by 64 to 0x220 + [ cc] copy + [ cd] set file to 2 + [ cf] extended opcode 144: inlined context 9, function name 0x4=20 + [ d4] advance line by constant -2 to 7 + [ d6] advance address by 144 to 0x2b0 + [ d9] copy + [ da] advance line by constant 1 to 8 + [ dc] advance address by 64 to 0x2f0 + [ df] copy + [ e0] set file to 1 + [ e2] extended opcode 144: inlined context 14, function name 0x8=20= + [ e7] advance line by constant 10 to 18 + [ e9] copy + [ ea] advance line by constant 1 to 19 + [ ec] advance address by 64 to 0x330 + [ ef] copy + [ f0] extended opcode 144: inlined context 0, function name 0x0=20 + [ f5] advance line by constant 14 to 33 + [ f7] advance address by 144 to 0x3c0 + [ fa] copy + [ fb] advance address by 192 to 0x480 + [ fe] extended opcode 1: end of sequence +EOF diff --git a/tests/testfile_nvidia_linemap.bz2 = b/tests/testfile_nvidia_linemap.bz2 new file mode 100644 index = 0000000000000000000000000000000000000000..8a6d09fbd1419af2b4664e8751207be4= 70198f1a GIT binary patch literal 2365 zcmV-D3BvY5T4*^jL0KkKSq)>6PXG%lfB*mg|L^|i|Nqm@%YXm>|9|bF;0gptplMZb z+z@oxek$MzA3=3DLe*sZ4QFf%trk<(lJVeQ+CXEdl4WbN< z003wJ222QOG|4JO$`Q^Ookzl7$XsrKr|R55rS!>07C#HCYdx~lTt}N z38AT?G}BEz6Gx~S0Av6%G&D2~0017KWB>pLfCE4P28bFNG}BB>fu@E=3DhD|gy8euXR zhCpD9Moj?FV2nlyri=3Dj$0F0Vs(Sk(*1jt54hEjf{$kR~t(lp+b(p@T+?W=3DXfGcS&L5UbU0?35a#xs8L!r-U)TF1&F!__dKhBSQp!#+wj$%m9uMNR-G!K_M%dqZ6H; zp6s^6LtA42tC>wzChpmB6xue3L}H1b!5}H>R`jsiDJG5(on{65{32{>NRWayf(z@`1E`3y{ zl~q+m1VF!oZ8R)6HEO=3DU!CjHKL=3Di#lMp8Ugu|_5N>}!I}P<2H9jm?W|S`&9IL7fYl&9&Tajy_+U zco?v~b4#nESGuIQ`WznwnVcDcvISVY32sJ@;zMlYbDE<_Ci5dU5WJ7A^d;1t&%hFdjAKBEu4x*h0Wpf#4;~SW1h|NlaA3mRdio<% zGpjR0sd)xQTDw99PZxme&R|Hv~Sh-6jvSs*KAN5Z798xL3$; z9FnOe=3D%tyNnVINO5fKqInrWo~+BvML@!#9pbEQiVVg!noOb1AemW7{KqN380XnRY1 z6{JWGivo+!W+h-4Y3?|6%5MW0g;{{xNZkBE)Ja^Fk-a=3DDk zS=3DwXMwrouPmhh`=3D=3D%Vz67fDh|NyHUm+g!3v8g!M10QsMnf&`Qk+^IDn5Z;=3DPj1~a5= zH&O@Dx5OLVo51JwnP)1TKRjw}r3i|mBC4vaL`EVgtVLB-h=3D{~hRw5{4IBBKH!Y!!n8(v!LfgK&f~C6?3$*akx+tT+~` zQ&mt=3DO;aXEkO2drE@PBN-FLcr75GzJg+W0&@WT#_C_bl!Qmkb@|P;)P6=3DsVtW;lDLBoVZy4hQ58{8Mk=3DbRAgk!m5)flbxZQ3X+O!1lp@o(X z+SMs00cDV_Ba9V5-r^D{G#CoWD#*P+kpPw8M6zZih>HSCTG3%@-dffX$!=3DA)MiVAu zjx63v@7iqgAu&330$@?#DN z6NEditP%rEZN^JA8Y?;mfGz=3Da@`QwllSz_F08}3)mY~3kP&Ps_ZMmM0c!-Q49`B4# zcb+A-d|*WH1GzczT?Nf5cK!b{F_9@3pgiJJ3pWL7W>gA4 zGiDm}BpCOl$LYMDSzZy{NiuK^^pSeEbtH;V1z?N>)ah6m1~G-bIK(87XT3qK5)l9x z40mqd)(~-IuM57Vl3(pymwh1aNiBL67qdt&_v%@YFH69NQHiccgh3-{yq!_dYu|g@ z=3D@*8TomE+8s9{vLJ*R@(ZQtwkpx|qDhM_ZY0%9&mHga|(YR7p3b|5p@TdqM_Eg+-s zLL!iMrX_|_A~gsaL?&2rselIk+iLV;pl>wLF0}Gs9l=3DWS)!Yq_pXg3`#*M}(Q-g2@ z1`~`<3%;7Tx%_a8VyAZl!6_V$UBw`=3D4iMR4eXP@L*K7((7gR*|jKtwYBx*=3D67Nb8((Hm10 zTeLcBi18~G1vRWQDD}RujxL{FF1l1;K}-aDVK9GC32vRua)mg)2*#^e6+Jh`NDdNs zn#lrvt*a9C4j5hys&rMN&Pg;`(RCy8V3aTH7)tkQALtOK1(%p_BZdf^uW4^<3GX)mdW&zZuC%MyCDnGxGg7 j?