public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support
@ 2024-02-26 19:32 Omar Sandoval
  2024-02-26 19:32 ` [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file Omar Sandoval
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Omar Sandoval @ 2024-02-26 19:32 UTC (permalink / raw)
  To: elfutils-devel

From: Omar Sandoval <osandov@fb.com>

Hi,

This is version 3 of my patch series adding support for DWARF package
files to libdw and the elfutils tools. Version 2 is here [1], and
version 1 is [here]. This version fixes handling of line number
information.

Patches 1 and 2 are new in this version. Patch 1 fixes dwarf_decl_file
for split DWARF (not just DWP). Patch 2 is primarly a refactor to
prepare for patch 3, but I also stumbled across a theoretical bug that
it fixes.

Patch 3 is the last piece of core DWP support. It was updated in this
version to handle DWP files in dwarf_getsrcfiles and dwarf_next_lines
and run the declfiles, get-lines, next-lines, get-files, and next-files
tests on DWP files.

Patch 4 is unchanged from version 2. It adds support and tests for an
LLVM extension to the dwp format. The "extension" is ugly because of an
oversight in the design of the format that LLVM had to make the best of,
but unfortunately it's necessary for a lot of our use cases.

Thanks!

Omar

1: https://sourceware.org/pipermail/elfutils-devel/2023q4/006718.html
2: https://sourceware.org/pipermail/elfutils-devel/2023q3/006410.html

Omar Sandoval (4):
  libdw: Handle split DWARF in dwarf_decl_file
  libdw: Refactor dwarf_next_lines and fix skipped CU
  libdw: Apply DWARF package file section offsets where appropriate
  libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file
    indexes

 libdw/dwarf_cu_dwp_section_info.c             |  147 +-
 libdw/dwarf_decl_file.c                       |   30 +-
 libdw/dwarf_end.c                             |   15 +-
 libdw/dwarf_getlocation.c                     |    6 +
 libdw/dwarf_getmacros.c                       |   26 +-
 libdw/dwarf_getsrcfiles.c                     |   17 +-
 libdw/dwarf_next_lines.c                      |   80 +-
 libdw/libdwP.h                                |   45 +-
 tests/.gitignore                              |    1 +
 tests/Makefile.am                             |   13 +-
 tests/declfiles.c                             |   90 ++
 tests/run-all-dwarf-ranges.sh                 |  114 ++
 tests/run-declfiles.sh                        |  323 ++++
 tests/run-dwarf-getmacros.sh                  | 1412 +++++++++++++++++
 tests/run-get-files.sh                        |  115 ++
 tests/run-get-lines.sh                        |  244 +++
 tests/run-get-units-split.sh                  |   18 +
 tests/run-large-elf-file.sh                   |  174 ++
 tests/run-next-files.sh                       |  100 ++
 tests/run-next-lines.sh                       |  242 +++
 tests/run-varlocs.sh                          |  112 ++
 tests/testfile-dwp-4-cu-index-overflow.bz2    |  Bin 0 -> 4490 bytes
 .../testfile-dwp-4-cu-index-overflow.dwp.bz2  |  Bin 0 -> 5584 bytes
 tests/testfile-dwp-5-cu-index-overflow.bz2    |  Bin 0 -> 4544 bytes
 .../testfile-dwp-5-cu-index-overflow.dwp.bz2  |  Bin 0 -> 5790 bytes
 tests/testfile-dwp-cu-index-overflow.source   |   86 +
 26 files changed, 3313 insertions(+), 97 deletions(-)
 create mode 100644 tests/declfiles.c
 create mode 100755 tests/run-declfiles.sh
 create mode 100755 tests/testfile-dwp-4-cu-index-overflow.bz2
 create mode 100644 tests/testfile-dwp-4-cu-index-overflow.dwp.bz2
 create mode 100755 tests/testfile-dwp-5-cu-index-overflow.bz2
 create mode 100644 tests/testfile-dwp-5-cu-index-overflow.dwp.bz2
 create mode 100644 tests/testfile-dwp-cu-index-overflow.source

-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file
  2024-02-26 19:32 [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support Omar Sandoval
@ 2024-02-26 19:32 ` Omar Sandoval
  2024-02-29 22:08   ` Mark Wielaard
  2024-02-26 19:32 ` [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU Omar Sandoval
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Omar Sandoval @ 2024-02-26 19:32 UTC (permalink / raw)
  To: elfutils-devel

From: Omar Sandoval <osandov@fb.com>

Calling dwarf_decl_file on a split DWARF DIE fails this assertion:

  dwarf_decl_file.c:72: dwarf_decl_file: Assertion `cu->files != NULL && cu->files != (void *) -1l' failed.

This is because dwarf_decl_file calls dwarf_getsrclines to populate
cu->files.  For normal units, cu->files is cached by dwarf_getsrclines
when it parses the line number information.  However, for split units,
the line number information is parsed for the skeleton unit, then copied
to the split unit's cu->lines.  Split units have their own file name
table, so cu->files is not copied.

The obvious solution is to use dwarf_getsrcfiles instead of relying on
implicit caching.

Also add a test case for dwarf_decl_file.

	* libdw/dwarf_decl_file.c (dwarf_decl_file): Use
	dwarf_getsrcfiles instead of dwarf_getsrclines.
	* tests/Makefile.am (check_PROGRAMS): Add declfiles.
	(TESTS): Add run-declfiles.sh.
	(EXTRA_DIST): Add run-declfiles.sh.
	(declfiles_LDADD): New variable.
	* tests/declfiles.c: New test.
	* tests/run-declfiles.sh: New test.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 libdw/dwarf_decl_file.c |  30 ++----
 tests/.gitignore        |   1 +
 tests/Makefile.am       |   8 +-
 tests/declfiles.c       |  90 ++++++++++++++++
 tests/run-declfiles.sh  | 233 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 335 insertions(+), 27 deletions(-)
 create mode 100644 tests/declfiles.c
 create mode 100755 tests/run-declfiles.sh

diff --git a/libdw/dwarf_decl_file.c b/libdw/dwarf_decl_file.c
index 7dde4af0..1b91a4e9 100644
--- a/libdw/dwarf_decl_file.c
+++ b/libdw/dwarf_decl_file.c
@@ -48,35 +48,17 @@ dwarf_decl_file (Dwarf_Die *die)
 			       &idx) != 0)
     return NULL;
 
-  /* Get the array of source files for the CU.  */
-  struct Dwarf_CU *cu = attr_mem.cu;
-  if (cu->lines == NULL)
-    {
-      Dwarf_Lines *lines;
-      size_t nlines;
+  Dwarf_Files *files;
+  size_t nfiles;
+  if (INTUSE(dwarf_getsrcfiles) (&CUDIE (attr_mem.cu), &files, &nfiles) != 0)
+    return NULL;
 
-      /* Let the more generic function do the work.  It'll create more
-	 data but that will be needed in an real program anyway.  */
-      (void) INTUSE(dwarf_getsrclines) (&CUDIE (cu), &lines, &nlines);
-      assert (cu->lines != NULL);
-    }
-
-  if (cu->lines == (void *) -1l)
-    {
-      /* If DW_AT_decl_file was present, there should be file information
-	available.  */
-      __libdw_seterrno (DWARF_E_INVALID_DWARF);
-      return NULL;
-    }
-
-  assert (cu->files != NULL && cu->files != (void *) -1l);
-
-  if (idx >= cu->files->nfiles)
+  if (idx >= nfiles)
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return NULL;
     }
 
-  return cu->files->info[idx].name;
+  return files->info[idx].name;
 }
 OLD_VERSION (dwarf_decl_file, ELFUTILS_0.122)
diff --git a/tests/.gitignore b/tests/.gitignore
index d38f0f9e..0289959d 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -32,6 +32,7 @@
 /debugaltlink
 /debuginfod_build_id_find
 /debuglink
+/declfiles
 /deleted
 /dwarf-die-addr-die
 /dwarf-getmacros
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d7c53144..3f80c451 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -63,7 +63,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  getphdrnum leb128 read_unaligned \
 		  msg_tst system-elf-libelf-test system-elf-gelf-test \
 		  nvidia_extended_linemap_libdw elf-print-reloc-syms \
-		  cu-dwp-section-info \
+		  cu-dwp-section-info declfiles \
 		  $(asm_TESTS)
 
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
@@ -213,7 +213,8 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
 	$(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 \
-	run-readelf-Dd.sh run-dwfl-core-noncontig.sh run-cu-dwp-section-info.sh
+	run-readelf-Dd.sh run-dwfl-core-noncontig.sh run-cu-dwp-section-info.sh \
+	run-declfiles.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -640,7 +641,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 	     testfile-dwp-4.bz2 testfile-dwp-4.dwp.bz2 \
 	     testfile-dwp-4-strict.bz2 testfile-dwp-4-strict.dwp.bz2 \
 	     testfile-dwp-5.bz2 testfile-dwp-5.dwp.bz2 testfile-dwp.source \
-	     run-cu-dwp-section-info.sh
+	     run-cu-dwp-section-info.sh run-declfiles.sh
 
 
 if USE_VALGRIND
@@ -818,6 +819,7 @@ read_unaligned_LDADD = $(libelf) $(libdw)
 nvidia_extended_linemap_libdw_LDADD = $(libelf) $(libdw)
 elf_print_reloc_syms_LDADD = $(libelf)
 cu_dwp_section_info_LDADD = $(libdw)
+declfiles_LDADD = $(libdw)
 
 # We want to test the libelf headers against the system elf.h header.
 # Don't include any -I CPPFLAGS. Except when we install our own elf.h.
diff --git a/tests/declfiles.c b/tests/declfiles.c
new file mode 100644
index 00000000..0842d637
--- /dev/null
+++ b/tests/declfiles.c
@@ -0,0 +1,90 @@
+/* Test program for dwarf_decl_file
+   Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <dwarf.h>
+#include ELFUTILS_HEADER(dw)
+
+static void
+walk_tree (Dwarf_Die *dwarf_die, int indent)
+{
+  Dwarf_Die die = *dwarf_die;
+  do
+    {
+      int child_indent = indent;
+      const char *file = dwarf_decl_file (&die);
+      if (file != NULL)
+	{
+	  printf("%*s", indent, "");
+	  const char *name = dwarf_diename (&die) ?: "???";
+	  int line, column;
+	  if (dwarf_decl_line (&die, &line) == 0)
+	    {
+	      if (dwarf_decl_column (&die, &column) == 0)
+		printf ("%s@%s:%d:%d\n", name, file, line, column);
+	      else
+		printf ("%s@%s:%d\n", name, file, line);
+	    }
+	  else
+	    printf ("%s@%s\n", name, file);
+	  child_indent++;
+	}
+
+      Dwarf_Die child;
+      if (dwarf_child (&die, &child) == 0)
+	walk_tree (&child, child_indent);
+    }
+  while (dwarf_siblingof (&die, &die) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; i++)
+    {
+      printf ("file: %s\n", argv[i]);
+      int fd = open (argv[i], O_RDONLY);
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1));
+	  return -1;
+	}
+
+      Dwarf_CU *cu = NULL;
+      Dwarf_Die cudie, subdie;
+      uint8_t unit_type;
+      while (dwarf_get_units (dbg, cu, &cu, NULL, &unit_type, &cudie, &subdie)
+	     == 0)
+	{
+	  Dwarf_Die *die = unit_type == DW_UT_skeleton ? &subdie : &cudie;
+	  printf (" cu: %s\n", dwarf_diename (die) ?: "???");
+	  walk_tree (die, 2);
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/tests/run-declfiles.sh b/tests/run-declfiles.sh
new file mode 100755
index 00000000..faba7078
--- /dev/null
+++ b/tests/run-declfiles.sh
@@ -0,0 +1,233 @@
+#! /bin/sh
+# Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
+# 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 <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# see tests/testfile-dwarf-45.source
+testfiles testfile-dwarf-4 testfile-dwarf-5
+testfiles testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo
+testfiles testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo
+
+testrun_compare ${abs_builddir}/declfiles testfile-dwarf-4 << EOF
+file: testfile-dwarf-4
+ cu: hello.c
+  wchar_t@/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h:328:24
+  m@/var/tmp/hello/hello.h:1:12
+  m@/var/tmp/hello/hello.c:5:5
+  foo@/var/tmp/hello/hello.c:20:1
+   f@/var/tmp/hello/hello.c:20:14
+  baz@/var/tmp/hello/hello.c:8:5
+   x@/var/tmp/hello/hello.c:8:14
+   r@/var/tmp/hello/hello.c:10:7
+  frob@/var/tmp/hello/hello.h:5:1
+   a@/var/tmp/hello/hello.h:5:11
+   b@/var/tmp/hello/hello.h:5:18
+   c@/var/tmp/hello/hello.h:7:7
+  foo@/var/tmp/hello/hello.c:20:1
+   f@/var/tmp/hello/hello.c:20:14
+   frob@/var/tmp/hello/hello.h:5:1
+    b@/var/tmp/hello/hello.h:5:18
+    a@/var/tmp/hello/hello.h:5:11
+    c@/var/tmp/hello/hello.h:7:7
+    baz@/var/tmp/hello/hello.c:8:5
+     x@/var/tmp/hello/hello.c:8:14
+     r@/var/tmp/hello/hello.c:10:7
+   foo@/var/tmp/hello/hello.c:20:1
+    f@/var/tmp/hello/hello.c:20:14
+    main@/var/tmp/hello/hello.c:4:12
+  baz@/var/tmp/hello/hello.c:8:5
+   x@/var/tmp/hello/hello.c:8:14
+   r@/var/tmp/hello/hello.c:10:7
+   foo@/var/tmp/hello/hello.c:20:1
+  main@/var/tmp/hello/hello.c:4:12
+ cu: world.c
+  m@/var/tmp/hello/hello.h:1:12
+  main@/var/tmp/hello/world.c:14:1
+   argc@/var/tmp/hello/world.c:14:11
+   argv@/var/tmp/hello/world.c:14:30
+   n@/var/tmp/hello/world.c:16:15
+   calc@/var/tmp/hello/world.c:5:1
+   exit@/usr/include/stdlib.h:542:13
+  calc@/var/tmp/hello/world.c:5:1
+   word@/var/tmp/hello/world.c:5:19
+   frob@/var/tmp/hello/hello.h:5:1
+    b@/var/tmp/hello/hello.h:5:18
+    a@/var/tmp/hello/hello.h:5:11
+    c@/var/tmp/hello/hello.h:7:7
+    baz@/var/tmp/hello/hello.h:2:12
+  frob@/var/tmp/hello/hello.h:5:1
+   a@/var/tmp/hello/hello.h:5:11
+   b@/var/tmp/hello/hello.h:5:18
+   c@/var/tmp/hello/hello.h:7:7
+  exit@/usr/include/stdlib.h:542:13
+  baz@/var/tmp/hello/hello.h:2:12
+EOF
+
+testrun_compare ${abs_builddir}/declfiles testfile-dwarf-5 << EOF
+file: testfile-dwarf-5
+ cu: hello.c
+  wchar_t@/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h:328:24
+  m@/var/tmp/hello/hello.h:1:12
+  m@/var/tmp/hello/hello.c:5:5
+  foo@/var/tmp/hello/hello.c:20:1
+   f@/var/tmp/hello/hello.c:20:14
+  baz@/var/tmp/hello/hello.c:8:5
+   x@/var/tmp/hello/hello.c:8:14
+   r@/var/tmp/hello/hello.c:10:7
+  frob@/var/tmp/hello/hello.h:5:1
+   a@/var/tmp/hello/hello.h:5:11
+   b@/var/tmp/hello/hello.h:5:18
+   c@/var/tmp/hello/hello.h:7:7
+  foo@/var/tmp/hello/hello.c:20:1
+   f@/var/tmp/hello/hello.c:20:14
+   frob@/var/tmp/hello/hello.h:5:1
+    b@/var/tmp/hello/hello.h:5:18
+    a@/var/tmp/hello/hello.h:5:11
+    c@/var/tmp/hello/hello.h:7:7
+    baz@/var/tmp/hello/hello.c:8:5
+     x@/var/tmp/hello/hello.c:8:14
+     r@/var/tmp/hello/hello.c:10:7
+   foo@/var/tmp/hello/hello.c:20:1
+    f@/var/tmp/hello/hello.c:20:14
+  baz@/var/tmp/hello/hello.c:8:5
+   x@/var/tmp/hello/hello.c:8:14
+   r@/var/tmp/hello/hello.c:10:7
+  main@/var/tmp/hello/hello.c:4:12
+ cu: world.c
+  m@/var/tmp/hello/hello.h:1:12
+  main@/var/tmp/hello/world.c:14:1
+   argc@/var/tmp/hello/world.c:14:11
+   argv@/var/tmp/hello/world.c:14:30
+   n@/var/tmp/hello/world.c:16:15
+  calc@/var/tmp/hello/world.c:5:1
+   word@/var/tmp/hello/world.c:5:19
+   frob@/var/tmp/hello/hello.h:5:1
+    b@/var/tmp/hello/hello.h:5:18
+    a@/var/tmp/hello/hello.h:5:11
+    c@/var/tmp/hello/hello.h:7:7
+  frob@/var/tmp/hello/hello.h:5:1
+   a@/var/tmp/hello/hello.h:5:11
+   b@/var/tmp/hello/hello.h:5:18
+   c@/var/tmp/hello/hello.h:7:7
+  exit@/usr/include/stdlib.h:542:13
+  baz@/var/tmp/hello/hello.h:2:12
+EOF
+
+testrun_compare ${abs_builddir}/declfiles testfile-splitdwarf-4 << EOF
+file: testfile-splitdwarf-4
+ cu: hello.c
+  wchar_t@/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h:328:24
+  m@/home/mark/src/elfutils/tests/hello.h:1:12
+  m@/home/mark/src/elfutils/tests/hello.c:5:5
+  foo@/home/mark/src/elfutils/tests/hello.c:20:1
+   f@/home/mark/src/elfutils/tests/hello.c:20:14
+  baz@/home/mark/src/elfutils/tests/hello.c:8:5
+   x@/home/mark/src/elfutils/tests/hello.c:8:14
+   r@/home/mark/src/elfutils/tests/hello.c:10:7
+  frob@/home/mark/src/elfutils/tests/hello.h:5:1
+   a@/home/mark/src/elfutils/tests/hello.h:5:11
+   b@/home/mark/src/elfutils/tests/hello.h:5:18
+   c@/home/mark/src/elfutils/tests/hello.h:7:7
+  foo@/home/mark/src/elfutils/tests/hello.c:20:1
+   f@/home/mark/src/elfutils/tests/hello.c:20:14
+   frob@/home/mark/src/elfutils/tests/hello.h:5:1
+    b@/home/mark/src/elfutils/tests/hello.h:5:18
+    a@/home/mark/src/elfutils/tests/hello.h:5:11
+    c@/home/mark/src/elfutils/tests/hello.h:7:7
+    baz@/home/mark/src/elfutils/tests/hello.c:8:5
+     x@/home/mark/src/elfutils/tests/hello.c:8:14
+     r@/home/mark/src/elfutils/tests/hello.c:10:7
+   foo@/home/mark/src/elfutils/tests/hello.c:20:1
+    f@/home/mark/src/elfutils/tests/hello.c:20:14
+    main@/home/mark/src/elfutils/tests/hello.c:4:12
+  baz@/home/mark/src/elfutils/tests/hello.c:8:5
+   x@/home/mark/src/elfutils/tests/hello.c:8:14
+   r@/home/mark/src/elfutils/tests/hello.c:10:7
+   foo@/home/mark/src/elfutils/tests/hello.c:20:1
+  main@/home/mark/src/elfutils/tests/hello.c:4:12
+ cu: world.c
+  m@/home/mark/src/elfutils/tests/hello.h:1:12
+  main@/home/mark/src/elfutils/tests/world.c:14:1
+   argc@/home/mark/src/elfutils/tests/world.c:14:11
+   argv@/home/mark/src/elfutils/tests/world.c:14:30
+   n@/home/mark/src/elfutils/tests/world.c:16:15
+   calc@/home/mark/src/elfutils/tests/world.c:5:1
+   exit@/usr/include/stdlib.h:542:13
+  calc@/home/mark/src/elfutils/tests/world.c:5:1
+   word@/home/mark/src/elfutils/tests/world.c:5:19
+   frob@/home/mark/src/elfutils/tests/hello.h:5:1
+    b@/home/mark/src/elfutils/tests/hello.h:5:18
+    a@/home/mark/src/elfutils/tests/hello.h:5:11
+    c@/home/mark/src/elfutils/tests/hello.h:7:7
+    baz@/home/mark/src/elfutils/tests/hello.h:2:12
+  frob@/home/mark/src/elfutils/tests/hello.h:5:1
+   a@/home/mark/src/elfutils/tests/hello.h:5:11
+   b@/home/mark/src/elfutils/tests/hello.h:5:18
+   c@/home/mark/src/elfutils/tests/hello.h:7:7
+  exit@/usr/include/stdlib.h:542:13
+  baz@/home/mark/src/elfutils/tests/hello.h:2:12
+EOF
+
+testrun_compare ${abs_builddir}/declfiles testfile-splitdwarf-5 << EOF
+file: testfile-splitdwarf-5
+ cu: hello.c
+  wchar_t@/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h:328:24
+  m@/home/mark/src/elfutils/tests/hello.h:1:12
+  m@/home/mark/src/elfutils/tests/hello.c:5:5
+  foo@/home/mark/src/elfutils/tests/hello.c:20:1
+   f@/home/mark/src/elfutils/tests/hello.c:20:14
+  baz@/home/mark/src/elfutils/tests/hello.c:8:5
+   x@/home/mark/src/elfutils/tests/hello.c:8:14
+   r@/home/mark/src/elfutils/tests/hello.c:10:7
+  frob@/home/mark/src/elfutils/tests/hello.h:5:1
+   a@/home/mark/src/elfutils/tests/hello.h:5:11
+   b@/home/mark/src/elfutils/tests/hello.h:5:18
+   c@/home/mark/src/elfutils/tests/hello.h:7:7
+  foo@/home/mark/src/elfutils/tests/hello.c:20:1
+   f@/home/mark/src/elfutils/tests/hello.c:20:14
+   frob@/home/mark/src/elfutils/tests/hello.h:5:1
+    b@/home/mark/src/elfutils/tests/hello.h:5:18
+    a@/home/mark/src/elfutils/tests/hello.h:5:11
+    c@/home/mark/src/elfutils/tests/hello.h:7:7
+    baz@/home/mark/src/elfutils/tests/hello.c:8:5
+     x@/home/mark/src/elfutils/tests/hello.c:8:14
+     r@/home/mark/src/elfutils/tests/hello.c:10:7
+   foo@/home/mark/src/elfutils/tests/hello.c:20:1
+    f@/home/mark/src/elfutils/tests/hello.c:20:14
+  baz@/home/mark/src/elfutils/tests/hello.c:8:5
+   x@/home/mark/src/elfutils/tests/hello.c:8:14
+   r@/home/mark/src/elfutils/tests/hello.c:10:7
+  main@/home/mark/src/elfutils/tests/hello.c:4:12
+ cu: world.c
+  m@/home/mark/src/elfutils/tests/hello.h:1:12
+  main@/home/mark/src/elfutils/tests/world.c:14:1
+   argc@/home/mark/src/elfutils/tests/world.c:14:11
+   argv@/home/mark/src/elfutils/tests/world.c:14:30
+   n@/home/mark/src/elfutils/tests/world.c:16:15
+  calc@/home/mark/src/elfutils/tests/world.c:5:1
+   word@/home/mark/src/elfutils/tests/world.c:5:19
+   frob@/home/mark/src/elfutils/tests/hello.h:5:1
+    b@/home/mark/src/elfutils/tests/hello.h:5:18
+    a@/home/mark/src/elfutils/tests/hello.h:5:11
+    c@/home/mark/src/elfutils/tests/hello.h:7:7
+  frob@/home/mark/src/elfutils/tests/hello.h:5:1
+   a@/home/mark/src/elfutils/tests/hello.h:5:11
+   b@/home/mark/src/elfutils/tests/hello.h:5:18
+   c@/home/mark/src/elfutils/tests/hello.h:7:7
+  exit@/usr/include/stdlib.h:542:13
+  baz@/home/mark/src/elfutils/tests/hello.h:2:12
+EOF
-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU
  2024-02-26 19:32 [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support Omar Sandoval
  2024-02-26 19:32 ` [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file Omar Sandoval
@ 2024-02-26 19:32 ` Omar Sandoval
  2024-02-29 22:59   ` Mark Wielaard
  2024-02-26 19:32 ` [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate Omar Sandoval
  2024-02-26 19:32 ` [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes Omar Sandoval
  3 siblings, 1 reply; 11+ messages in thread
From: Omar Sandoval @ 2024-02-26 19:32 UTC (permalink / raw)
  To: elfutils-devel

From: Omar Sandoval <osandov@fb.com>

dwarf_next_lines has two loops over CUs: one from the CU after the given
CU to the end, and one from the first CU up to _but not including_ the
given CU.  This means that the given CU is never checked.

This is unlikely to matter in practice since CUs usually correspond 1:1
with line number tables in the same order, but let's fix it anyways.
Refactoring it to one loop fixes the problem and simplifies the next
change to support DWARF package files.

	* libdw/dwarf_next_lines.c (dwarf_next_lines): Refactor loops
	over CUs into one loop.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 libdw/dwarf_next_lines.c | 75 +++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 44 deletions(-)

diff --git a/libdw/dwarf_next_lines.c b/libdw/dwarf_next_lines.c
index 74854ecd..6a9fe361 100644
--- a/libdw/dwarf_next_lines.c
+++ b/libdw/dwarf_next_lines.c
@@ -95,62 +95,49 @@ dwarf_next_lines (Dwarf *dbg, Dwarf_Off off,
     {
       /* We need to find the matching CU to get the comp_dir.  Use the
 	 given CU as hint where to start searching.  Normally it will
-	 be the next CU that has a statement list. */
+	 be the next CU that has a statement list.  If the CUs are in a
+	 different order from the line tables, then we do a linear
+	 search.  */
       Dwarf_CU *given_cu = *cu;
       Dwarf_CU *next_cu = given_cu;
-      bool found = false;
-      while (INTUSE(dwarf_get_units) (dbg, next_cu, &next_cu, NULL, NULL,
-				      &cudie, NULL) == 0)
+      bool restarted = false;
+      while (1)
 	{
+	  if (restarted && next_cu == given_cu)
+	    {
+	      /* We checked all of the CUs and there was no match.  */
+	      *cu = NULL;
+	      break;
+	    }
+	  if (INTUSE(dwarf_get_units) (dbg, next_cu, &next_cu, NULL, NULL,
+				       &cudie, NULL) != 0)
+	    {
+	      /* We didn't find the matching CU after the starting point.
+	         Check the CUs up to the starting point.  */
+	      next_cu = NULL;
+	      restarted = true;
+	      continue;
+	    }
+
+	  Dwarf_Word stmt_off = 0;
 	  if (dwarf_hasattr (&cudie, DW_AT_stmt_list))
 	    {
 	      Dwarf_Attribute attr;
-	      Dwarf_Word stmt_off;
 	      if (dwarf_formudata (dwarf_attr (&cudie, DW_AT_stmt_list, &attr),
-				   &stmt_off) == 0
-		  && stmt_off == off)
-		{
-		  found = true;
-		  break;
-		}
+				   &stmt_off) != 0)
+		continue;
 	    }
-	  else if (off == 0
-		   && (next_cu->unit_type == DW_UT_split_compile
-		       || next_cu->unit_type == DW_UT_split_type))
+	  /* Split units have an implicit offset of 0.  */
+	  else if (next_cu->unit_type != DW_UT_split_compile
+		   && next_cu->unit_type != DW_UT_split_type)
+	    continue;
+
+	  if (stmt_off == off)
 	    {
-	      /* For split units (in .dwo files) there is only one table
-		 at offset zero (containing just the files, no lines).  */
-	      found = true;
+	      *cu = next_cu;
 	      break;
 	    }
 	}
-
-      if (!found && given_cu != NULL)
-	{
-	  /* The CUs might be in a different order from the line
-	     tables. Need to do a linear search (but stop at the given
-	     CU, since we already searched those.  */
-	  next_cu = NULL;
-	  while (INTUSE(dwarf_get_units) (dbg, next_cu, &next_cu, NULL, NULL,
-					  &cudie, NULL) == 0
-		 && next_cu != given_cu)
-	    {
-	      Dwarf_Attribute attr;
-	      Dwarf_Word stmt_off;
-	      if (dwarf_formudata (dwarf_attr (&cudie, DW_AT_stmt_list, &attr),
-				   &stmt_off) == 0
-		  && stmt_off == off)
-		{
-		  found = true;
-		  break;
-		}
-	    }
-	}
-
-      if (found)
-	*cu = next_cu;
-      else
-	*cu = NULL;
     }
   else
     *cu = NULL;
-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate
  2024-02-26 19:32 [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support Omar Sandoval
  2024-02-26 19:32 ` [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file Omar Sandoval
  2024-02-26 19:32 ` [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU Omar Sandoval
@ 2024-02-26 19:32 ` Omar Sandoval
  2024-02-29 23:49   ` Mark Wielaard
  2024-02-26 19:32 ` [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes Omar Sandoval
  3 siblings, 1 reply; 11+ messages in thread
From: Omar Sandoval @ 2024-02-26 19:32 UTC (permalink / raw)
  To: elfutils-devel

From: Omar Sandoval <osandov@fb.com>

The final piece of DWARF package file support is that offsets have to be
interpreted relative to the section offset from the package index.
.debug_abbrev.dwo is already covered, so sprinkle around calls to
dwarf_cu_dwp_section_info for the remaining sections: .debug_line.dwo,
.debug_loclists.dwo/.debug_loc.dwo, .debug_str_offsets.dwo,
.debug_macro.dwo/.debug_macinfo.dwo, and .debug_rnglists.dwo.  With all
of that in place, we can finally test various libdw functions on dwp
files.

	* libdw/dwarf_getlocation.c (initial_offset): Call
	dwarf_cu_dwp_section_info and add offset to start_offset.
	* libdw/dwarf_getmacros.c (get_macinfo_table): Call
	dwarf_cu_dwp_section_info and add offset to line_offset.
	(get_offset_from): Call dwarf_cu_dwp_section_info and add offset
	to *retp.
	* libdw/dwarf_getsrcfiles.c (dwarf_getsrcfiles): Call
	dwarf_cu_dwp_section_info and pass offset to
        __libdw_getsrclines.
	* libdw/dwarf_next_lines.c (dwarf_next_lines): Call
	dwarf_cu_dwp_section_info and add offset to stmt_off.
	* libdw/libdwP.h (str_offsets_base_off): Call
	dwarf_cu_dwp_section_info and add offset.
	(__libdw_cu_ranges_base): Ditto.
	(__libdw_cu_locs_base): Ditto.
	* tests/run-all-dwarf-ranges.sh: Check testfile-dwp-5 and
	testfile-dwp-4.
	* tests/run-declfiles.sh: Ditto.
	* tests/run-get-lines.sh: Ditto.
	* tests/run-next-lines.sh: Ditto.
	* tests/run-varlocs.sh: Ditto.
	* tests/run-get-files.sh: Check testfile-dwp-5,
	testfile-dwp-5.dwp, testfile-dwp-4, and testfile-dwp-4.dwp
	* tests/run-next-files.sh: Ditto.
	* tests/run-dwarf-getmacros.sh: Check testfile-dwp-5 and
	testfile-dwp-4-strict.
	* tests/run-get-units-split.sh: Ditto.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 libdw/dwarf_getlocation.c     |    6 +
 libdw/dwarf_getmacros.c       |   26 +-
 libdw/dwarf_getsrcfiles.c     |   17 +-
 libdw/dwarf_next_lines.c      |    5 +
 libdw/libdwP.h                |   42 +-
 tests/run-all-dwarf-ranges.sh |  114 +++
 tests/run-declfiles.sh        |   90 +++
 tests/run-dwarf-getmacros.sh  | 1412 +++++++++++++++++++++++++++++++++
 tests/run-get-files.sh        |  115 +++
 tests/run-get-lines.sh        |  244 ++++++
 tests/run-get-units-split.sh  |   18 +
 tests/run-next-files.sh       |  100 +++
 tests/run-next-lines.sh       |  242 ++++++
 tests/run-varlocs.sh          |  112 +++
 14 files changed, 2522 insertions(+), 21 deletions(-)

diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 553fdc98..37b32fc1 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -812,6 +812,12 @@ initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
 			    : DWARF_E_NO_DEBUG_LOCLISTS),
 			    NULL, &start_offset) == NULL)
 	return -1;
+
+      Dwarf_Off loc_off;
+      if (INTUSE(dwarf_cu_dwp_section_info) (attr->cu, DW_SECT_LOCLISTS,
+					     &loc_off, NULL) != 0)
+	return -1;
+      start_offset += loc_off;
     }
 
   *offset = start_offset;
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index a3a78884..2667eb45 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -47,7 +47,15 @@ get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp)
     return -1;
 
   /* Offset into the corresponding section.  */
-  return INTUSE(dwarf_formudata) (&attr, retp);
+  if (INTUSE(dwarf_formudata) (&attr, retp) != 0)
+    return -1;
+
+  Dwarf_Off offset;
+  if (INTUSE(dwarf_cu_dwp_section_info) (die->cu, DW_SECT_MACRO, &offset, NULL)
+      != 0)
+    return -1;
+  *retp += offset;
+  return 0;
 }
 
 static int
@@ -131,6 +139,14 @@ get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
   else if (cudie->cu->unit_type == DW_UT_split_compile
 	   && dbg->sectiondata[IDX_debug_line] != NULL)
     line_offset = 0;
+  if (line_offset != (Dwarf_Off) -1)
+    {
+      Dwarf_Off dwp_offset;
+      if (INTUSE(dwarf_cu_dwp_section_info) (cudie->cu, DW_SECT_LINE,
+					     &dwp_offset, NULL) != 0)
+	return NULL;
+      line_offset += dwp_offset;
+    }
 
   Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
 					     macinfo_data_size, 1);
@@ -188,6 +204,14 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
 	if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
 	  return NULL;
     }
+  if (line_offset != (Dwarf_Off) -1 && cudie != NULL)
+    {
+      Dwarf_Off dwp_offset;
+      if (INTUSE(dwarf_cu_dwp_section_info) (cudie->cu, DW_SECT_LINE,
+					     &dwp_offset, NULL) != 0)
+	return NULL;
+      line_offset += dwp_offset;
+    }
 
   uint8_t address_size;
   if (cudie != NULL)
diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
index 12fdabf2..cd2e5b5a 100644
--- a/libdw/dwarf_getsrcfiles.c
+++ b/libdw/dwarf_getsrcfiles.c
@@ -64,12 +64,17 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
 	     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);
+	      Dwarf_Off dwp_off;
+	      if (INTUSE(dwarf_cu_dwp_section_info) (cu, DW_SECT_LINE,
+						     &dwp_off, NULL) == 0)
+		{
+		  /* We are only interested in the files, the lines will
+		     always come from the skeleton.  */
+		  res = __libdw_getsrclines (cu->dbg, dwp_off,
+					     __libdw_getcompdir (cudie),
+					     cu->address_size, NULL,
+					     &cu->files);
+		}
 	    }
 	  else
 	    {
diff --git a/libdw/dwarf_next_lines.c b/libdw/dwarf_next_lines.c
index 6a9fe361..a96bd73e 100644
--- a/libdw/dwarf_next_lines.c
+++ b/libdw/dwarf_next_lines.c
@@ -132,6 +132,11 @@ dwarf_next_lines (Dwarf *dbg, Dwarf_Off off,
 		   && next_cu->unit_type != DW_UT_split_type)
 	    continue;
 
+	  Dwarf_Off dwp_off;
+	  if (INTUSE(dwarf_cu_dwp_section_info) (next_cu, DW_SECT_LINE,
+						 &dwp_off, NULL) == 0)
+	    stmt_off += dwp_off;
+
 	  if (stmt_off == off)
 	    {
 	      *cu = next_cu;
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 75e0283b..1a0a4df3 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -1152,25 +1152,30 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 	cu = first_cu;
     }
 
+  Dwarf_Off off = 0;
   if (cu != NULL)
     {
       if (cu->str_off_base == (Dwarf_Off) -1)
 	{
+	  Dwarf_Off dwp_offset;
+	  if (dwarf_cu_dwp_section_info (cu, DW_SECT_STR_OFFSETS, &dwp_offset,
+					 NULL) == 0)
+	    off = dwp_offset;
 	  Dwarf_Die cu_die = CUDIE(cu);
 	  Dwarf_Attribute attr;
 	  if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL)
 	    {
-	      Dwarf_Word off;
-	      if (dwarf_formudata (&attr, &off) == 0)
+	      Dwarf_Word base;
+	      if (dwarf_formudata (&attr, &base) == 0)
 		{
-		  cu->str_off_base = off;
+		  cu->str_off_base = off + base;
 		  return cu->str_off_base;
 		}
 	    }
 	  /* For older DWARF simply assume zero (no header).  */
 	  if (cu->version < 5)
 	    {
-	      cu->str_off_base = 0;
+	      cu->str_off_base = off;
 	      return cu->str_off_base;
 	    }
 
@@ -1183,7 +1188,6 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 
   /* No str_offsets_base attribute, we have to assume "zero".
      But there could be a header first.  */
-  Dwarf_Off off = 0;
   if (dbg == NULL)
     goto no_header;
 
@@ -1225,7 +1229,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
   /* padding */
   read_2ubyte_unaligned_inc (dbg, readp);
 
-  off = (Dwarf_Off) (readp - start);
+  off += (Dwarf_Off) (readp - start);
 
  no_header:
   if (cu != NULL)
@@ -1263,18 +1267,23 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
 	}
       else
 	{
+	  Dwarf_Off dwp_offset;
+	  if (dwarf_cu_dwp_section_info (cu, DW_SECT_RNGLISTS, &dwp_offset,
+					 NULL) == 0)
+	    offset = dwp_offset;
+
 	  if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
 	    {
 	      Dwarf_Word off;
 	      if (dwarf_formudata (&attr, &off) == 0)
-		offset = off;
+		offset += off;
 	    }
 
 	  /* There wasn't an rnglists_base, if the Dwarf does have a
 	     .debug_rnglists section, then it might be we need the
 	     base after the first header. */
 	  Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
-	  if (offset == 0 && data != NULL)
+	  if (offset == dwp_offset && data != NULL)
 	    {
 	      Dwarf *dbg = cu->dbg;
 	      const unsigned char *readp = data->d_buf;
@@ -1320,8 +1329,8 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
 	      if (unit_length - 8 < needed)
 		goto no_header;
 
-	      offset = (Dwarf_Off) (offset_array_start
-				    - (unsigned char *) data->d_buf);
+	      offset += (Dwarf_Off) (offset_array_start
+				     - (unsigned char *) data->d_buf);
 	    }
 	}
     no_header:
@@ -1339,20 +1348,25 @@ __libdw_cu_locs_base (Dwarf_CU *cu)
   if (cu->locs_base == (Dwarf_Off) -1)
     {
       Dwarf_Off offset = 0;
+      Dwarf_Off dwp_offset;
+      if (dwarf_cu_dwp_section_info (cu, DW_SECT_LOCLISTS, &dwp_offset, NULL)
+	  == 0)
+	offset = dwp_offset;
+
       Dwarf_Die cu_die = CUDIE(cu);
       Dwarf_Attribute attr;
       if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
 	{
 	  Dwarf_Word off;
 	  if (dwarf_formudata (&attr, &off) == 0)
-	    offset = off;
+	    offset += off;
 	}
 
       /* There wasn't an loclists_base, if the Dwarf does have a
 	 .debug_loclists section, then it might be we need the
 	 base after the first header. */
       Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
-      if (offset == 0 && data != NULL)
+      if (offset == dwp_offset && data != NULL)
 	{
 	  Dwarf *dbg = cu->dbg;
 	  const unsigned char *readp = data->d_buf;
@@ -1398,8 +1412,8 @@ __libdw_cu_locs_base (Dwarf_CU *cu)
 	  if (unit_length - 8 < needed)
 	    goto no_header;
 
-	  offset = (Dwarf_Off) (offset_array_start
-				- (unsigned char *) data->d_buf);
+	  offset += (Dwarf_Off) (offset_array_start
+				 - (unsigned char *) data->d_buf);
 	}
 
     no_header:
diff --git a/tests/run-all-dwarf-ranges.sh b/tests/run-all-dwarf-ranges.sh
index cefb4231..61141cfa 100755
--- a/tests/run-all-dwarf-ranges.sh
+++ b/tests/run-all-dwarf-ranges.sh
@@ -126,4 +126,118 @@ die: no_subject (2e)
 
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/all-dwarf-ranges testfile-dwp-5 << EOF
+die: foo.cc (11)
+ 401190..401200
+
+die: foo (2e)
+ 4011c0..401200
+
+die: x_x (1d)
+ 4011cb..4011eb
+ 4011f8..401200
+
+die: <unknown> (b)
+ 4011cb..4011eb
+ 4011f8..401200
+
+die: x_x (2e)
+ 401190..4011bd
+
+die: <unknown> (b)
+ 401190..401190
+ 401192..4011bb
+
+die: bar.cc (11)
+ 401200..40121b
+
+die: bar (2e)
+ 401200..40121b
+
+die: main.cc (11)
+ 401020..4010a0
+
+die: main (2e)
+ 401020..4010a0
+
+die: fibonacci (1d)
+ 401030..401032
+ 401036..401060
+ 401099..4010a0
+
+die: fibonacci (1d)
+ 40103a..401060
+ 401099..4010a0
+
+die: <unknown> (b)
+ 40103a..401060
+ 401099..4010a0
+
+die: <unknown> (b)
+ 40103a..401044
+ 401050..401060
+
+die: <unknown> (b)
+ 401050..401053
+ 401056..401059
+
+EOF
+
+testrun_compare ${abs_builddir}/all-dwarf-ranges testfile-dwp-4 << EOF
+die: foo.cc (11)
+ 401190..401200
+
+die: foo (2e)
+ 4011c0..401200
+
+die: x_x (1d)
+ 4011cb..4011eb
+ 4011f8..401200
+
+die: <unknown> (b)
+ 4011cb..4011eb
+ 4011f8..401200
+
+die: x_x (2e)
+ 401190..4011bd
+
+die: bar.cc (11)
+ 401200..40121b
+
+die: bar (2e)
+ 401200..40121b
+
+die: main.cc (11)
+ 401020..4010a0
+
+die: main (2e)
+ 401020..4010a0
+
+die: fibonacci (1d)
+ 401030..401032
+ 401036..401060
+ 401099..4010a0
+
+die: fibonacci (1d)
+ 40103a..401060
+ 401099..4010a0
+
+die: <unknown> (b)
+ 40103a..401060
+ 401099..4010a0
+
+die: <unknown> (b)
+ 40103a..401044
+ 401050..401060
+
+die: <unknown> (b)
+ 401050..401053
+ 401056..401059
+
+EOF
+
 exit 0
diff --git a/tests/run-declfiles.sh b/tests/run-declfiles.sh
index faba7078..5aa1b970 100755
--- a/tests/run-declfiles.sh
+++ b/tests/run-declfiles.sh
@@ -231,3 +231,93 @@ file: testfile-splitdwarf-5
   exit@/usr/include/stdlib.h:542:13
   baz@/home/mark/src/elfutils/tests/hello.h:2:12
 EOF
+
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/declfiles testfile-dwp-5 << EOF
+file: testfile-dwp-5
+ cu: foo.cc
+  foo@/home/osandov/src/elfutils/tests/foobar.h:4:7
+  foo@/home/osandov/src/elfutils/tests/foo.cc:14:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:16:7
+   x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+    x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+    i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+  x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+   i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+  x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+   i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+ cu: bar.cc
+  bar@/home/osandov/src/elfutils/tests/foobar.h:10:8
+  bar@/home/osandov/src/elfutils/tests/bar.cc:6:1
+ cu: main.cc
+  foo@/home/osandov/src/elfutils/tests/foobar.h:4:7
+  bar@/home/osandov/src/elfutils/tests/foobar.h:10:8
+  main@/home/osandov/src/elfutils/tests/main.cc:6:1
+   argc@/home/osandov/src/elfutils/tests/main.cc:6:6
+   argv@/home/osandov/src/elfutils/tests/main.cc:6:6
+   myfoo@/home/osandov/src/elfutils/tests/main.cc:8:14
+   mybar@/home/osandov/src/elfutils/tests/main.cc:9:14
+   fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+    n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+    fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+     n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+     a@/home/osandov/src/elfutils/tests/foobar.h:23:12
+     b@/home/osandov/src/elfutils/tests/foobar.h:24:12
+     i@/home/osandov/src/elfutils/tests/foobar.h:25:25
+     tmp@/home/osandov/src/elfutils/tests/foobar.h:27:9
+  fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+   n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+   a@/home/osandov/src/elfutils/tests/foobar.h:23:12
+   b@/home/osandov/src/elfutils/tests/foobar.h:24:12
+   i@/home/osandov/src/elfutils/tests/foobar.h:25:25
+   tmp@/home/osandov/src/elfutils/tests/foobar.h:27:9
+EOF
+
+testrun_compare ${abs_builddir}/declfiles testfile-dwp-4 << EOF
+file: testfile-dwp-4
+ cu: foo.cc
+  foo@/home/osandov/src/elfutils/tests/foobar.h:4:7
+  foo@/home/osandov/src/elfutils/tests/foo.cc:14:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:16:7
+   x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+    x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+    i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+  x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+   i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+  x_x@/home/osandov/src/elfutils/tests/foo.cc:6:1
+   x@/home/osandov/src/elfutils/tests/foo.cc:6:10
+   i@/home/osandov/src/elfutils/tests/foo.cc:8:12
+ cu: bar.cc
+  bar@/home/osandov/src/elfutils/tests/foobar.h:10:8
+  bar@/home/osandov/src/elfutils/tests/bar.cc:6:1
+ cu: main.cc
+  foo@/home/osandov/src/elfutils/tests/foobar.h:4:7
+  bar@/home/osandov/src/elfutils/tests/foobar.h:10:8
+  main@/home/osandov/src/elfutils/tests/main.cc:6:1
+   argc@/home/osandov/src/elfutils/tests/main.cc:6:6
+   argv@/home/osandov/src/elfutils/tests/main.cc:6:6
+   myfoo@/home/osandov/src/elfutils/tests/main.cc:8:14
+   mybar@/home/osandov/src/elfutils/tests/main.cc:9:14
+   fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+    n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+    fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+     n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+     a@/home/osandov/src/elfutils/tests/foobar.h:23:12
+     b@/home/osandov/src/elfutils/tests/foobar.h:24:12
+     i@/home/osandov/src/elfutils/tests/foobar.h:25:25
+     tmp@/home/osandov/src/elfutils/tests/foobar.h:27:9
+   foo@/home/osandov/src/elfutils/tests/foobar.h:4:7
+   bar@/home/osandov/src/elfutils/tests/foobar.h:10:8
+  fibonacci@/home/osandov/src/elfutils/tests/foobar.h:17:1
+   n@/home/osandov/src/elfutils/tests/foobar.h:17:25
+   a@/home/osandov/src/elfutils/tests/foobar.h:23:12
+   b@/home/osandov/src/elfutils/tests/foobar.h:24:12
+   i@/home/osandov/src/elfutils/tests/foobar.h:25:25
+   tmp@/home/osandov/src/elfutils/tests/foobar.h:27:9
+EOF
diff --git a/tests/run-dwarf-getmacros.sh b/tests/run-dwarf-getmacros.sh
index 0a488fa3..220c2426 100755
--- a/tests/run-dwarf-getmacros.sh
+++ b/tests/run-dwarf-getmacros.sh
@@ -707,4 +707,1416 @@ file /home/petr/proj/elfutils/master/elfutils/x.c
 /file
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4-strict testfile-dwp-4-strict.dwp
+
+# Not testfile-dwp-4 because it's unclear what to do about
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99319.
+for file in testfile-dwp-5 testfile-dwp-4-strict; do
+	testrun_compare ${abs_builddir}/dwarf-getmacros "$file" '' '' << EOF
+CU foo.cc
+__STDC__ 1
+__cplusplus 201703L
+__STDC_UTF_16__ 1
+__STDC_UTF_32__ 1
+__STDC_HOSTED__ 1
+__GNUC__ 14
+__GNUC_MINOR__ 0
+__GNUC_PATCHLEVEL__ 0
+__VERSION__ "14.0.0 20230920 (experimental)"
+__ATOMIC_RELAXED 0
+__ATOMIC_SEQ_CST 5
+__ATOMIC_ACQUIRE 2
+__ATOMIC_RELEASE 3
+__ATOMIC_ACQ_REL 4
+__ATOMIC_CONSUME 1
+__OPTIMIZE__ 1
+__FINITE_MATH_ONLY__ 0
+_LP64 1
+__LP64__ 1
+__SIZEOF_INT__ 4
+__SIZEOF_LONG__ 8
+__SIZEOF_LONG_LONG__ 8
+__SIZEOF_SHORT__ 2
+__SIZEOF_FLOAT__ 4
+__SIZEOF_DOUBLE__ 8
+__SIZEOF_LONG_DOUBLE__ 16
+__SIZEOF_SIZE_T__ 8
+__CHAR_BIT__ 8
+__BIGGEST_ALIGNMENT__ 16
+__ORDER_LITTLE_ENDIAN__ 1234
+__ORDER_BIG_ENDIAN__ 4321
+__ORDER_PDP_ENDIAN__ 3412
+__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+__FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
+__SIZEOF_POINTER__ 8
+__GNUC_EXECUTION_CHARSET_NAME "UTF-8"
+__GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
+__GNUG__ 14
+__SIZE_TYPE__ long unsigned int
+__PTRDIFF_TYPE__ long int
+__WCHAR_TYPE__ int
+__WINT_TYPE__ unsigned int
+__INTMAX_TYPE__ long int
+__UINTMAX_TYPE__ long unsigned int
+__CHAR16_TYPE__ short unsigned int
+__CHAR32_TYPE__ unsigned int
+__SIG_ATOMIC_TYPE__ int
+__INT8_TYPE__ signed char
+__INT16_TYPE__ short int
+__INT32_TYPE__ int
+__INT64_TYPE__ long int
+__UINT8_TYPE__ unsigned char
+__UINT16_TYPE__ short unsigned int
+__UINT32_TYPE__ unsigned int
+__UINT64_TYPE__ long unsigned int
+__INT_LEAST8_TYPE__ signed char
+__INT_LEAST16_TYPE__ short int
+__INT_LEAST32_TYPE__ int
+__INT_LEAST64_TYPE__ long int
+__UINT_LEAST8_TYPE__ unsigned char
+__UINT_LEAST16_TYPE__ short unsigned int
+__UINT_LEAST32_TYPE__ unsigned int
+__UINT_LEAST64_TYPE__ long unsigned int
+__INT_FAST8_TYPE__ signed char
+__INT_FAST16_TYPE__ long int
+__INT_FAST32_TYPE__ long int
+__INT_FAST64_TYPE__ long int
+__UINT_FAST8_TYPE__ unsigned char
+__UINT_FAST16_TYPE__ long unsigned int
+__UINT_FAST32_TYPE__ long unsigned int
+__UINT_FAST64_TYPE__ long unsigned int
+__INTPTR_TYPE__ long int
+__UINTPTR_TYPE__ long unsigned int
+__GXX_WEAK__ 1
+__DEPRECATED 1
+__GXX_RTTI 1
+__cpp_rtti 199711L
+__GXX_EXPERIMENTAL_CXX0X__ 1
+__cpp_binary_literals 201304L
+__cpp_hex_float 201603L
+__cpp_runtime_arrays 198712L
+__cpp_raw_strings 200710L
+__cpp_unicode_literals 200710L
+__cpp_user_defined_literals 200809L
+__cpp_lambdas 200907L
+__cpp_decltype 200707L
+__cpp_attributes 200809L
+__cpp_rvalue_reference 200610L
+__cpp_rvalue_references 200610L
+__cpp_variadic_templates 200704L
+__cpp_initializer_lists 200806L
+__cpp_delegating_constructors 200604L
+__cpp_nsdmi 200809L
+__cpp_inheriting_constructors 201511L
+__cpp_ref_qualifiers 200710L
+__cpp_alias_templates 200704L
+__cpp_return_type_deduction 201304L
+__cpp_init_captures 201304L
+__cpp_generic_lambdas 201304L
+__cpp_decltype_auto 201304L
+__cpp_aggregate_nsdmi 201304L
+__cpp_variable_templates 201304L
+__cpp_digit_separators 201309L
+__cpp_unicode_characters 201411L
+__cpp_static_assert 201411L
+__cpp_namespace_attributes 201411L
+__cpp_enumerator_attributes 201411L
+__cpp_nested_namespace_definitions 201411L
+__cpp_fold_expressions 201603L
+__cpp_nontype_template_args 201411L
+__cpp_range_based_for 201603L
+__cpp_constexpr 201603L
+__cpp_if_constexpr 201606L
+__cpp_capture_star_this 201603L
+__cpp_inline_variables 201606L
+__cpp_aggregate_bases 201603L
+__cpp_deduction_guides 201703L
+__cpp_noexcept_function_type 201510L
+__cpp_template_auto 201606L
+__cpp_structured_bindings 201606L
+__cpp_variadic_using 201611L
+__cpp_guaranteed_copy_elision 201606L
+__cpp_nontype_template_parameter_auto 201606L
+__cpp_sized_deallocation 201309L
+__cpp_aligned_new 201606L
+__STDCPP_DEFAULT_NEW_ALIGNMENT__ 16
+__cpp_template_template_args 201611L
+__cpp_threadsafe_static_init 200806L
+__STDCPP_THREADS__ 1
+__EXCEPTIONS 1
+__cpp_exceptions 199711L
+__GXX_ABI_VERSION 1019
+__SCHAR_MAX__ 0x7f
+__SHRT_MAX__ 0x7fff
+__INT_MAX__ 0x7fffffff
+__LONG_MAX__ 0x7fffffffffffffffL
+__LONG_LONG_MAX__ 0x7fffffffffffffffLL
+__WCHAR_MAX__ 0x7fffffff
+__WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+__WINT_MAX__ 0xffffffffU
+__WINT_MIN__ 0U
+__PTRDIFF_MAX__ 0x7fffffffffffffffL
+__SIZE_MAX__ 0xffffffffffffffffUL
+__SCHAR_WIDTH__ 8
+__SHRT_WIDTH__ 16
+__INT_WIDTH__ 32
+__LONG_WIDTH__ 64
+__LONG_LONG_WIDTH__ 64
+__WCHAR_WIDTH__ 32
+__WINT_WIDTH__ 32
+__PTRDIFF_WIDTH__ 64
+__SIZE_WIDTH__ 64
+__GLIBCXX_TYPE_INT_N_0 __int128
+__GLIBCXX_BITSIZE_INT_N_0 128
+__INTMAX_MAX__ 0x7fffffffffffffffL
+__INTMAX_C(c) c ## L
+__UINTMAX_MAX__ 0xffffffffffffffffUL
+__UINTMAX_C(c) c ## UL
+__INTMAX_WIDTH__ 64
+__SIG_ATOMIC_MAX__ 0x7fffffff
+__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+__SIG_ATOMIC_WIDTH__ 32
+__INT8_MAX__ 0x7f
+__INT16_MAX__ 0x7fff
+__INT32_MAX__ 0x7fffffff
+__INT64_MAX__ 0x7fffffffffffffffL
+__UINT8_MAX__ 0xff
+__UINT16_MAX__ 0xffff
+__UINT32_MAX__ 0xffffffffU
+__UINT64_MAX__ 0xffffffffffffffffUL
+__INT_LEAST8_MAX__ 0x7f
+__INT8_C(c) c
+__INT_LEAST8_WIDTH__ 8
+__INT_LEAST16_MAX__ 0x7fff
+__INT16_C(c) c
+__INT_LEAST16_WIDTH__ 16
+__INT_LEAST32_MAX__ 0x7fffffff
+__INT32_C(c) c
+__INT_LEAST32_WIDTH__ 32
+__INT_LEAST64_MAX__ 0x7fffffffffffffffL
+__INT64_C(c) c ## L
+__INT_LEAST64_WIDTH__ 64
+__UINT_LEAST8_MAX__ 0xff
+__UINT8_C(c) c
+__UINT_LEAST16_MAX__ 0xffff
+__UINT16_C(c) c
+__UINT_LEAST32_MAX__ 0xffffffffU
+__UINT32_C(c) c ## U
+__UINT_LEAST64_MAX__ 0xffffffffffffffffUL
+__UINT64_C(c) c ## UL
+__INT_FAST8_MAX__ 0x7f
+__INT_FAST8_WIDTH__ 8
+__INT_FAST16_MAX__ 0x7fffffffffffffffL
+__INT_FAST16_WIDTH__ 64
+__INT_FAST32_MAX__ 0x7fffffffffffffffL
+__INT_FAST32_WIDTH__ 64
+__INT_FAST64_MAX__ 0x7fffffffffffffffL
+__INT_FAST64_WIDTH__ 64
+__UINT_FAST8_MAX__ 0xff
+__UINT_FAST16_MAX__ 0xffffffffffffffffUL
+__UINT_FAST32_MAX__ 0xffffffffffffffffUL
+__UINT_FAST64_MAX__ 0xffffffffffffffffUL
+__INTPTR_MAX__ 0x7fffffffffffffffL
+__INTPTR_WIDTH__ 64
+__UINTPTR_MAX__ 0xffffffffffffffffUL
+__GCC_IEC_559 2
+__GCC_IEC_559_COMPLEX 2
+__FLT_EVAL_METHOD__ 0
+__FLT_EVAL_METHOD_TS_18661_3__ 0
+__DEC_EVAL_METHOD__ 2
+__FLT_RADIX__ 2
+__FLT_MANT_DIG__ 24
+__FLT_DIG__ 6
+__FLT_MIN_EXP__ (-125)
+__FLT_MIN_10_EXP__ (-37)
+__FLT_MAX_EXP__ 128
+__FLT_MAX_10_EXP__ 38
+__FLT_DECIMAL_DIG__ 9
+__FLT_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_MIN__ 1.17549435082228750796873653722224568e-38F
+__FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
+__FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
+__FLT_HAS_DENORM__ 1
+__FLT_HAS_INFINITY__ 1
+__FLT_HAS_QUIET_NAN__ 1
+__FLT_IS_IEC_60559__ 1
+__DBL_MANT_DIG__ 53
+__DBL_DIG__ 15
+__DBL_MIN_EXP__ (-1021)
+__DBL_MIN_10_EXP__ (-307)
+__DBL_MAX_EXP__ 1024
+__DBL_MAX_10_EXP__ 308
+__DBL_DECIMAL_DIG__ 17
+__DBL_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_NORM_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_MIN__ double(2.22507385850720138309023271733240406e-308L)
+__DBL_EPSILON__ double(2.22044604925031308084726333618164062e-16L)
+__DBL_DENORM_MIN__ double(4.94065645841246544176568792868221372e-324L)
+__DBL_HAS_DENORM__ 1
+__DBL_HAS_INFINITY__ 1
+__DBL_HAS_QUIET_NAN__ 1
+__DBL_IS_IEC_60559__ 1
+__LDBL_MANT_DIG__ 64
+__LDBL_DIG__ 18
+__LDBL_MIN_EXP__ (-16381)
+__LDBL_MIN_10_EXP__ (-4931)
+__LDBL_MAX_EXP__ 16384
+__LDBL_MAX_10_EXP__ 4932
+__DECIMAL_DIG__ 21
+__LDBL_DECIMAL_DIG__ 21
+__LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+__LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
+__LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
+__LDBL_HAS_DENORM__ 1
+__LDBL_HAS_INFINITY__ 1
+__LDBL_HAS_QUIET_NAN__ 1
+__LDBL_IS_IEC_60559__ 1
+__FLT16_MANT_DIG__ 11
+__FLT16_DIG__ 3
+__FLT16_MIN_EXP__ (-13)
+__FLT16_MIN_10_EXP__ (-4)
+__FLT16_MAX_EXP__ 16
+__FLT16_MAX_10_EXP__ 4
+__FLT16_DECIMAL_DIG__ 5
+__FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
+__FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
+__FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
+__FLT16_HAS_DENORM__ 1
+__FLT16_HAS_INFINITY__ 1
+__FLT16_HAS_QUIET_NAN__ 1
+__FLT16_IS_IEC_60559__ 1
+__FLT32_MANT_DIG__ 24
+__FLT32_DIG__ 6
+__FLT32_MIN_EXP__ (-125)
+__FLT32_MIN_10_EXP__ (-37)
+__FLT32_MAX_EXP__ 128
+__FLT32_MAX_10_EXP__ 38
+__FLT32_DECIMAL_DIG__ 9
+__FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
+__FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
+__FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
+__FLT32_HAS_DENORM__ 1
+__FLT32_HAS_INFINITY__ 1
+__FLT32_HAS_QUIET_NAN__ 1
+__FLT32_IS_IEC_60559__ 1
+__FLT64_MANT_DIG__ 53
+__FLT64_DIG__ 15
+__FLT64_MIN_EXP__ (-1021)
+__FLT64_MIN_10_EXP__ (-307)
+__FLT64_MAX_EXP__ 1024
+__FLT64_MAX_10_EXP__ 308
+__FLT64_DECIMAL_DIG__ 17
+__FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
+__FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
+__FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
+__FLT64_HAS_DENORM__ 1
+__FLT64_HAS_INFINITY__ 1
+__FLT64_HAS_QUIET_NAN__ 1
+__FLT64_IS_IEC_60559__ 1
+__FLT128_MANT_DIG__ 113
+__FLT128_DIG__ 33
+__FLT128_MIN_EXP__ (-16381)
+__FLT128_MIN_10_EXP__ (-4931)
+__FLT128_MAX_EXP__ 16384
+__FLT128_MAX_10_EXP__ 4932
+__FLT128_DECIMAL_DIG__ 36
+__FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
+__FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
+__FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
+__FLT128_HAS_DENORM__ 1
+__FLT128_HAS_INFINITY__ 1
+__FLT128_HAS_QUIET_NAN__ 1
+__FLT128_IS_IEC_60559__ 1
+__FLT32X_MANT_DIG__ 53
+__FLT32X_DIG__ 15
+__FLT32X_MIN_EXP__ (-1021)
+__FLT32X_MIN_10_EXP__ (-307)
+__FLT32X_MAX_EXP__ 1024
+__FLT32X_MAX_10_EXP__ 308
+__FLT32X_DECIMAL_DIG__ 17
+__FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
+__FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
+__FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
+__FLT32X_HAS_DENORM__ 1
+__FLT32X_HAS_INFINITY__ 1
+__FLT32X_HAS_QUIET_NAN__ 1
+__FLT32X_IS_IEC_60559__ 1
+__FLT64X_MANT_DIG__ 64
+__FLT64X_DIG__ 18
+__FLT64X_MIN_EXP__ (-16381)
+__FLT64X_MIN_10_EXP__ (-4931)
+__FLT64X_MAX_EXP__ 16384
+__FLT64X_MAX_10_EXP__ 4932
+__FLT64X_DECIMAL_DIG__ 21
+__FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
+__FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
+__FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
+__FLT64X_HAS_DENORM__ 1
+__FLT64X_HAS_INFINITY__ 1
+__FLT64X_HAS_QUIET_NAN__ 1
+__FLT64X_IS_IEC_60559__ 1
+__BFLT16_MANT_DIG__ 8
+__BFLT16_DIG__ 2
+__BFLT16_MIN_EXP__ (-125)
+__BFLT16_MIN_10_EXP__ (-37)
+__BFLT16_MAX_EXP__ 128
+__BFLT16_MAX_10_EXP__ 38
+__BFLT16_DECIMAL_DIG__ 4
+__BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
+__BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
+__BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
+__BFLT16_HAS_DENORM__ 1
+__BFLT16_HAS_INFINITY__ 1
+__BFLT16_HAS_QUIET_NAN__ 1
+__BFLT16_IS_IEC_60559__ 0
+__DEC32_MANT_DIG__ 7
+__DEC32_MIN_EXP__ (-94)
+__DEC32_MAX_EXP__ 97
+__DEC32_MIN__ 1E-95DF
+__DEC32_MAX__ 9.999999E96DF
+__DEC32_EPSILON__ 1E-6DF
+__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+__DEC64_MANT_DIG__ 16
+__DEC64_MIN_EXP__ (-382)
+__DEC64_MAX_EXP__ 385
+__DEC64_MIN__ 1E-383DD
+__DEC64_MAX__ 9.999999999999999E384DD
+__DEC64_EPSILON__ 1E-15DD
+__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+__DEC128_MANT_DIG__ 34
+__DEC128_MIN_EXP__ (-6142)
+__DEC128_MAX_EXP__ 6145
+__DEC128_MIN__ 1E-6143DL
+__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+__DEC128_EPSILON__ 1E-33DL
+__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+__REGISTER_PREFIX__ 
+__USER_LABEL_PREFIX__ 
+__GNUC_STDC_INLINE__ 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+__GCC_ATOMIC_BOOL_LOCK_FREE 2
+__GCC_ATOMIC_CHAR_LOCK_FREE 2
+__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+__GCC_ATOMIC_SHORT_LOCK_FREE 2
+__GCC_ATOMIC_INT_LOCK_FREE 2
+__GCC_ATOMIC_LONG_LOCK_FREE 2
+__GCC_ATOMIC_LLONG_LOCK_FREE 2
+__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+__GCC_DESTRUCTIVE_SIZE 64
+__GCC_CONSTRUCTIVE_SIZE 64
+__GCC_ATOMIC_POINTER_LOCK_FREE 2
+__HAVE_SPECULATION_SAFE_VALUE 1
+__GCC_HAVE_DWARF2_CFI_ASM 1
+__PRAGMA_REDEFINE_EXTNAME 1
+__SIZEOF_INT128__ 16
+__SIZEOF_WCHAR_T__ 4
+__SIZEOF_WINT_T__ 4
+__SIZEOF_PTRDIFF_T__ 8
+__amd64 1
+__amd64__ 1
+__x86_64 1
+__x86_64__ 1
+__SIZEOF_FLOAT80__ 16
+__SIZEOF_FLOAT128__ 16
+__ATOMIC_HLE_ACQUIRE 65536
+__ATOMIC_HLE_RELEASE 131072
+__GCC_ASM_FLAG_OUTPUTS__ 1
+__k8 1
+__k8__ 1
+__code_model_small__ 1
+__MMX__ 1
+__SSE__ 1
+__SSE2__ 1
+__FXSR__ 1
+__SSE_MATH__ 1
+__SSE2_MATH__ 1
+__MMX_WITH_SSE__ 1
+__SEG_FS 1
+__SEG_GS 1
+__gnu_linux__ 1
+__linux 1
+__linux__ 1
+linux 1
+__unix 1
+__unix__ 1
+unix 1
+__ELF__ 1
+__DECIMAL_BID_FORMAT__ 1
+_GNU_SOURCE 1
+file /home/osandov/src/elfutils/tests/foo.cc
+ file /usr/include/stdc-predef.h
+  _STDC_PREDEF_H 1
+  __STDC_IEC_559__ 1
+  __STDC_IEC_60559_BFP__ 201404L
+  __STDC_IEC_559_COMPLEX__ 1
+  __STDC_IEC_60559_COMPLEX__ 201404L
+  __STDC_ISO_10646__ 201706L
+ /file
+ file /home/osandov/src/elfutils/tests/foobar.h
+  FROB(x) ((x) ^ 0x2a2a2a2a)
+  FRY(x) ((x) * 0x100000001b3)
+ /file
+ ZERO() (1 - 1)
+/file
+CU bar.cc
+__STDC__ 1
+__cplusplus 201703L
+__STDC_UTF_16__ 1
+__STDC_UTF_32__ 1
+__STDC_HOSTED__ 1
+__GNUC__ 14
+__GNUC_MINOR__ 0
+__GNUC_PATCHLEVEL__ 0
+__VERSION__ "14.0.0 20230920 (experimental)"
+__ATOMIC_RELAXED 0
+__ATOMIC_SEQ_CST 5
+__ATOMIC_ACQUIRE 2
+__ATOMIC_RELEASE 3
+__ATOMIC_ACQ_REL 4
+__ATOMIC_CONSUME 1
+__OPTIMIZE__ 1
+__FINITE_MATH_ONLY__ 0
+_LP64 1
+__LP64__ 1
+__SIZEOF_INT__ 4
+__SIZEOF_LONG__ 8
+__SIZEOF_LONG_LONG__ 8
+__SIZEOF_SHORT__ 2
+__SIZEOF_FLOAT__ 4
+__SIZEOF_DOUBLE__ 8
+__SIZEOF_LONG_DOUBLE__ 16
+__SIZEOF_SIZE_T__ 8
+__CHAR_BIT__ 8
+__BIGGEST_ALIGNMENT__ 16
+__ORDER_LITTLE_ENDIAN__ 1234
+__ORDER_BIG_ENDIAN__ 4321
+__ORDER_PDP_ENDIAN__ 3412
+__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+__FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
+__SIZEOF_POINTER__ 8
+__GNUC_EXECUTION_CHARSET_NAME "UTF-8"
+__GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
+__GNUG__ 14
+__SIZE_TYPE__ long unsigned int
+__PTRDIFF_TYPE__ long int
+__WCHAR_TYPE__ int
+__WINT_TYPE__ unsigned int
+__INTMAX_TYPE__ long int
+__UINTMAX_TYPE__ long unsigned int
+__CHAR16_TYPE__ short unsigned int
+__CHAR32_TYPE__ unsigned int
+__SIG_ATOMIC_TYPE__ int
+__INT8_TYPE__ signed char
+__INT16_TYPE__ short int
+__INT32_TYPE__ int
+__INT64_TYPE__ long int
+__UINT8_TYPE__ unsigned char
+__UINT16_TYPE__ short unsigned int
+__UINT32_TYPE__ unsigned int
+__UINT64_TYPE__ long unsigned int
+__INT_LEAST8_TYPE__ signed char
+__INT_LEAST16_TYPE__ short int
+__INT_LEAST32_TYPE__ int
+__INT_LEAST64_TYPE__ long int
+__UINT_LEAST8_TYPE__ unsigned char
+__UINT_LEAST16_TYPE__ short unsigned int
+__UINT_LEAST32_TYPE__ unsigned int
+__UINT_LEAST64_TYPE__ long unsigned int
+__INT_FAST8_TYPE__ signed char
+__INT_FAST16_TYPE__ long int
+__INT_FAST32_TYPE__ long int
+__INT_FAST64_TYPE__ long int
+__UINT_FAST8_TYPE__ unsigned char
+__UINT_FAST16_TYPE__ long unsigned int
+__UINT_FAST32_TYPE__ long unsigned int
+__UINT_FAST64_TYPE__ long unsigned int
+__INTPTR_TYPE__ long int
+__UINTPTR_TYPE__ long unsigned int
+__GXX_WEAK__ 1
+__DEPRECATED 1
+__GXX_RTTI 1
+__cpp_rtti 199711L
+__GXX_EXPERIMENTAL_CXX0X__ 1
+__cpp_binary_literals 201304L
+__cpp_hex_float 201603L
+__cpp_runtime_arrays 198712L
+__cpp_raw_strings 200710L
+__cpp_unicode_literals 200710L
+__cpp_user_defined_literals 200809L
+__cpp_lambdas 200907L
+__cpp_decltype 200707L
+__cpp_attributes 200809L
+__cpp_rvalue_reference 200610L
+__cpp_rvalue_references 200610L
+__cpp_variadic_templates 200704L
+__cpp_initializer_lists 200806L
+__cpp_delegating_constructors 200604L
+__cpp_nsdmi 200809L
+__cpp_inheriting_constructors 201511L
+__cpp_ref_qualifiers 200710L
+__cpp_alias_templates 200704L
+__cpp_return_type_deduction 201304L
+__cpp_init_captures 201304L
+__cpp_generic_lambdas 201304L
+__cpp_decltype_auto 201304L
+__cpp_aggregate_nsdmi 201304L
+__cpp_variable_templates 201304L
+__cpp_digit_separators 201309L
+__cpp_unicode_characters 201411L
+__cpp_static_assert 201411L
+__cpp_namespace_attributes 201411L
+__cpp_enumerator_attributes 201411L
+__cpp_nested_namespace_definitions 201411L
+__cpp_fold_expressions 201603L
+__cpp_nontype_template_args 201411L
+__cpp_range_based_for 201603L
+__cpp_constexpr 201603L
+__cpp_if_constexpr 201606L
+__cpp_capture_star_this 201603L
+__cpp_inline_variables 201606L
+__cpp_aggregate_bases 201603L
+__cpp_deduction_guides 201703L
+__cpp_noexcept_function_type 201510L
+__cpp_template_auto 201606L
+__cpp_structured_bindings 201606L
+__cpp_variadic_using 201611L
+__cpp_guaranteed_copy_elision 201606L
+__cpp_nontype_template_parameter_auto 201606L
+__cpp_sized_deallocation 201309L
+__cpp_aligned_new 201606L
+__STDCPP_DEFAULT_NEW_ALIGNMENT__ 16
+__cpp_template_template_args 201611L
+__cpp_threadsafe_static_init 200806L
+__STDCPP_THREADS__ 1
+__EXCEPTIONS 1
+__cpp_exceptions 199711L
+__GXX_ABI_VERSION 1019
+__SCHAR_MAX__ 0x7f
+__SHRT_MAX__ 0x7fff
+__INT_MAX__ 0x7fffffff
+__LONG_MAX__ 0x7fffffffffffffffL
+__LONG_LONG_MAX__ 0x7fffffffffffffffLL
+__WCHAR_MAX__ 0x7fffffff
+__WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+__WINT_MAX__ 0xffffffffU
+__WINT_MIN__ 0U
+__PTRDIFF_MAX__ 0x7fffffffffffffffL
+__SIZE_MAX__ 0xffffffffffffffffUL
+__SCHAR_WIDTH__ 8
+__SHRT_WIDTH__ 16
+__INT_WIDTH__ 32
+__LONG_WIDTH__ 64
+__LONG_LONG_WIDTH__ 64
+__WCHAR_WIDTH__ 32
+__WINT_WIDTH__ 32
+__PTRDIFF_WIDTH__ 64
+__SIZE_WIDTH__ 64
+__GLIBCXX_TYPE_INT_N_0 __int128
+__GLIBCXX_BITSIZE_INT_N_0 128
+__INTMAX_MAX__ 0x7fffffffffffffffL
+__INTMAX_C(c) c ## L
+__UINTMAX_MAX__ 0xffffffffffffffffUL
+__UINTMAX_C(c) c ## UL
+__INTMAX_WIDTH__ 64
+__SIG_ATOMIC_MAX__ 0x7fffffff
+__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+__SIG_ATOMIC_WIDTH__ 32
+__INT8_MAX__ 0x7f
+__INT16_MAX__ 0x7fff
+__INT32_MAX__ 0x7fffffff
+__INT64_MAX__ 0x7fffffffffffffffL
+__UINT8_MAX__ 0xff
+__UINT16_MAX__ 0xffff
+__UINT32_MAX__ 0xffffffffU
+__UINT64_MAX__ 0xffffffffffffffffUL
+__INT_LEAST8_MAX__ 0x7f
+__INT8_C(c) c
+__INT_LEAST8_WIDTH__ 8
+__INT_LEAST16_MAX__ 0x7fff
+__INT16_C(c) c
+__INT_LEAST16_WIDTH__ 16
+__INT_LEAST32_MAX__ 0x7fffffff
+__INT32_C(c) c
+__INT_LEAST32_WIDTH__ 32
+__INT_LEAST64_MAX__ 0x7fffffffffffffffL
+__INT64_C(c) c ## L
+__INT_LEAST64_WIDTH__ 64
+__UINT_LEAST8_MAX__ 0xff
+__UINT8_C(c) c
+__UINT_LEAST16_MAX__ 0xffff
+__UINT16_C(c) c
+__UINT_LEAST32_MAX__ 0xffffffffU
+__UINT32_C(c) c ## U
+__UINT_LEAST64_MAX__ 0xffffffffffffffffUL
+__UINT64_C(c) c ## UL
+__INT_FAST8_MAX__ 0x7f
+__INT_FAST8_WIDTH__ 8
+__INT_FAST16_MAX__ 0x7fffffffffffffffL
+__INT_FAST16_WIDTH__ 64
+__INT_FAST32_MAX__ 0x7fffffffffffffffL
+__INT_FAST32_WIDTH__ 64
+__INT_FAST64_MAX__ 0x7fffffffffffffffL
+__INT_FAST64_WIDTH__ 64
+__UINT_FAST8_MAX__ 0xff
+__UINT_FAST16_MAX__ 0xffffffffffffffffUL
+__UINT_FAST32_MAX__ 0xffffffffffffffffUL
+__UINT_FAST64_MAX__ 0xffffffffffffffffUL
+__INTPTR_MAX__ 0x7fffffffffffffffL
+__INTPTR_WIDTH__ 64
+__UINTPTR_MAX__ 0xffffffffffffffffUL
+__GCC_IEC_559 2
+__GCC_IEC_559_COMPLEX 2
+__FLT_EVAL_METHOD__ 0
+__FLT_EVAL_METHOD_TS_18661_3__ 0
+__DEC_EVAL_METHOD__ 2
+__FLT_RADIX__ 2
+__FLT_MANT_DIG__ 24
+__FLT_DIG__ 6
+__FLT_MIN_EXP__ (-125)
+__FLT_MIN_10_EXP__ (-37)
+__FLT_MAX_EXP__ 128
+__FLT_MAX_10_EXP__ 38
+__FLT_DECIMAL_DIG__ 9
+__FLT_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_MIN__ 1.17549435082228750796873653722224568e-38F
+__FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
+__FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
+__FLT_HAS_DENORM__ 1
+__FLT_HAS_INFINITY__ 1
+__FLT_HAS_QUIET_NAN__ 1
+__FLT_IS_IEC_60559__ 1
+__DBL_MANT_DIG__ 53
+__DBL_DIG__ 15
+__DBL_MIN_EXP__ (-1021)
+__DBL_MIN_10_EXP__ (-307)
+__DBL_MAX_EXP__ 1024
+__DBL_MAX_10_EXP__ 308
+__DBL_DECIMAL_DIG__ 17
+__DBL_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_NORM_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_MIN__ double(2.22507385850720138309023271733240406e-308L)
+__DBL_EPSILON__ double(2.22044604925031308084726333618164062e-16L)
+__DBL_DENORM_MIN__ double(4.94065645841246544176568792868221372e-324L)
+__DBL_HAS_DENORM__ 1
+__DBL_HAS_INFINITY__ 1
+__DBL_HAS_QUIET_NAN__ 1
+__DBL_IS_IEC_60559__ 1
+__LDBL_MANT_DIG__ 64
+__LDBL_DIG__ 18
+__LDBL_MIN_EXP__ (-16381)
+__LDBL_MIN_10_EXP__ (-4931)
+__LDBL_MAX_EXP__ 16384
+__LDBL_MAX_10_EXP__ 4932
+__DECIMAL_DIG__ 21
+__LDBL_DECIMAL_DIG__ 21
+__LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+__LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
+__LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
+__LDBL_HAS_DENORM__ 1
+__LDBL_HAS_INFINITY__ 1
+__LDBL_HAS_QUIET_NAN__ 1
+__LDBL_IS_IEC_60559__ 1
+__FLT16_MANT_DIG__ 11
+__FLT16_DIG__ 3
+__FLT16_MIN_EXP__ (-13)
+__FLT16_MIN_10_EXP__ (-4)
+__FLT16_MAX_EXP__ 16
+__FLT16_MAX_10_EXP__ 4
+__FLT16_DECIMAL_DIG__ 5
+__FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
+__FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
+__FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
+__FLT16_HAS_DENORM__ 1
+__FLT16_HAS_INFINITY__ 1
+__FLT16_HAS_QUIET_NAN__ 1
+__FLT16_IS_IEC_60559__ 1
+__FLT32_MANT_DIG__ 24
+__FLT32_DIG__ 6
+__FLT32_MIN_EXP__ (-125)
+__FLT32_MIN_10_EXP__ (-37)
+__FLT32_MAX_EXP__ 128
+__FLT32_MAX_10_EXP__ 38
+__FLT32_DECIMAL_DIG__ 9
+__FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
+__FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
+__FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
+__FLT32_HAS_DENORM__ 1
+__FLT32_HAS_INFINITY__ 1
+__FLT32_HAS_QUIET_NAN__ 1
+__FLT32_IS_IEC_60559__ 1
+__FLT64_MANT_DIG__ 53
+__FLT64_DIG__ 15
+__FLT64_MIN_EXP__ (-1021)
+__FLT64_MIN_10_EXP__ (-307)
+__FLT64_MAX_EXP__ 1024
+__FLT64_MAX_10_EXP__ 308
+__FLT64_DECIMAL_DIG__ 17
+__FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
+__FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
+__FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
+__FLT64_HAS_DENORM__ 1
+__FLT64_HAS_INFINITY__ 1
+__FLT64_HAS_QUIET_NAN__ 1
+__FLT64_IS_IEC_60559__ 1
+__FLT128_MANT_DIG__ 113
+__FLT128_DIG__ 33
+__FLT128_MIN_EXP__ (-16381)
+__FLT128_MIN_10_EXP__ (-4931)
+__FLT128_MAX_EXP__ 16384
+__FLT128_MAX_10_EXP__ 4932
+__FLT128_DECIMAL_DIG__ 36
+__FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
+__FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
+__FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
+__FLT128_HAS_DENORM__ 1
+__FLT128_HAS_INFINITY__ 1
+__FLT128_HAS_QUIET_NAN__ 1
+__FLT128_IS_IEC_60559__ 1
+__FLT32X_MANT_DIG__ 53
+__FLT32X_DIG__ 15
+__FLT32X_MIN_EXP__ (-1021)
+__FLT32X_MIN_10_EXP__ (-307)
+__FLT32X_MAX_EXP__ 1024
+__FLT32X_MAX_10_EXP__ 308
+__FLT32X_DECIMAL_DIG__ 17
+__FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
+__FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
+__FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
+__FLT32X_HAS_DENORM__ 1
+__FLT32X_HAS_INFINITY__ 1
+__FLT32X_HAS_QUIET_NAN__ 1
+__FLT32X_IS_IEC_60559__ 1
+__FLT64X_MANT_DIG__ 64
+__FLT64X_DIG__ 18
+__FLT64X_MIN_EXP__ (-16381)
+__FLT64X_MIN_10_EXP__ (-4931)
+__FLT64X_MAX_EXP__ 16384
+__FLT64X_MAX_10_EXP__ 4932
+__FLT64X_DECIMAL_DIG__ 21
+__FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
+__FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
+__FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
+__FLT64X_HAS_DENORM__ 1
+__FLT64X_HAS_INFINITY__ 1
+__FLT64X_HAS_QUIET_NAN__ 1
+__FLT64X_IS_IEC_60559__ 1
+__BFLT16_MANT_DIG__ 8
+__BFLT16_DIG__ 2
+__BFLT16_MIN_EXP__ (-125)
+__BFLT16_MIN_10_EXP__ (-37)
+__BFLT16_MAX_EXP__ 128
+__BFLT16_MAX_10_EXP__ 38
+__BFLT16_DECIMAL_DIG__ 4
+__BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
+__BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
+__BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
+__BFLT16_HAS_DENORM__ 1
+__BFLT16_HAS_INFINITY__ 1
+__BFLT16_HAS_QUIET_NAN__ 1
+__BFLT16_IS_IEC_60559__ 0
+__DEC32_MANT_DIG__ 7
+__DEC32_MIN_EXP__ (-94)
+__DEC32_MAX_EXP__ 97
+__DEC32_MIN__ 1E-95DF
+__DEC32_MAX__ 9.999999E96DF
+__DEC32_EPSILON__ 1E-6DF
+__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+__DEC64_MANT_DIG__ 16
+__DEC64_MIN_EXP__ (-382)
+__DEC64_MAX_EXP__ 385
+__DEC64_MIN__ 1E-383DD
+__DEC64_MAX__ 9.999999999999999E384DD
+__DEC64_EPSILON__ 1E-15DD
+__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+__DEC128_MANT_DIG__ 34
+__DEC128_MIN_EXP__ (-6142)
+__DEC128_MAX_EXP__ 6145
+__DEC128_MIN__ 1E-6143DL
+__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+__DEC128_EPSILON__ 1E-33DL
+__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+__REGISTER_PREFIX__ 
+__USER_LABEL_PREFIX__ 
+__GNUC_STDC_INLINE__ 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+__GCC_ATOMIC_BOOL_LOCK_FREE 2
+__GCC_ATOMIC_CHAR_LOCK_FREE 2
+__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+__GCC_ATOMIC_SHORT_LOCK_FREE 2
+__GCC_ATOMIC_INT_LOCK_FREE 2
+__GCC_ATOMIC_LONG_LOCK_FREE 2
+__GCC_ATOMIC_LLONG_LOCK_FREE 2
+__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+__GCC_DESTRUCTIVE_SIZE 64
+__GCC_CONSTRUCTIVE_SIZE 64
+__GCC_ATOMIC_POINTER_LOCK_FREE 2
+__HAVE_SPECULATION_SAFE_VALUE 1
+__GCC_HAVE_DWARF2_CFI_ASM 1
+__PRAGMA_REDEFINE_EXTNAME 1
+__SIZEOF_INT128__ 16
+__SIZEOF_WCHAR_T__ 4
+__SIZEOF_WINT_T__ 4
+__SIZEOF_PTRDIFF_T__ 8
+__amd64 1
+__amd64__ 1
+__x86_64 1
+__x86_64__ 1
+__SIZEOF_FLOAT80__ 16
+__SIZEOF_FLOAT128__ 16
+__ATOMIC_HLE_ACQUIRE 65536
+__ATOMIC_HLE_RELEASE 131072
+__GCC_ASM_FLAG_OUTPUTS__ 1
+__k8 1
+__k8__ 1
+__code_model_small__ 1
+__MMX__ 1
+__SSE__ 1
+__SSE2__ 1
+__FXSR__ 1
+__SSE_MATH__ 1
+__SSE2_MATH__ 1
+__MMX_WITH_SSE__ 1
+__SEG_FS 1
+__SEG_GS 1
+__gnu_linux__ 1
+__linux 1
+__linux__ 1
+linux 1
+__unix 1
+__unix__ 1
+unix 1
+__ELF__ 1
+__DECIMAL_BID_FORMAT__ 1
+_GNU_SOURCE 1
+file /home/osandov/src/elfutils/tests/bar.cc
+ file /usr/include/stdc-predef.h
+  _STDC_PREDEF_H 1
+  __STDC_IEC_559__ 1
+  __STDC_IEC_60559_BFP__ 201404L
+  __STDC_IEC_559_COMPLEX__ 1
+  __STDC_IEC_60559_COMPLEX__ 201404L
+  __STDC_ISO_10646__ 201706L
+ /file
+ file /home/osandov/src/elfutils/tests/foobar.h
+  FROB(x) ((x) ^ 0x2a2a2a2a)
+  FRY(x) ((x) * 0x100000001b3)
+ /file
+ ONE 1
+/file
+CU main.cc
+__STDC__ 1
+__cplusplus 201703L
+__STDC_UTF_16__ 1
+__STDC_UTF_32__ 1
+__STDC_HOSTED__ 1
+__GNUC__ 14
+__GNUC_MINOR__ 0
+__GNUC_PATCHLEVEL__ 0
+__VERSION__ "14.0.0 20230920 (experimental)"
+__ATOMIC_RELAXED 0
+__ATOMIC_SEQ_CST 5
+__ATOMIC_ACQUIRE 2
+__ATOMIC_RELEASE 3
+__ATOMIC_ACQ_REL 4
+__ATOMIC_CONSUME 1
+__OPTIMIZE__ 1
+__FINITE_MATH_ONLY__ 0
+_LP64 1
+__LP64__ 1
+__SIZEOF_INT__ 4
+__SIZEOF_LONG__ 8
+__SIZEOF_LONG_LONG__ 8
+__SIZEOF_SHORT__ 2
+__SIZEOF_FLOAT__ 4
+__SIZEOF_DOUBLE__ 8
+__SIZEOF_LONG_DOUBLE__ 16
+__SIZEOF_SIZE_T__ 8
+__CHAR_BIT__ 8
+__BIGGEST_ALIGNMENT__ 16
+__ORDER_LITTLE_ENDIAN__ 1234
+__ORDER_BIG_ENDIAN__ 4321
+__ORDER_PDP_ENDIAN__ 3412
+__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+__FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
+__SIZEOF_POINTER__ 8
+__GNUC_EXECUTION_CHARSET_NAME "UTF-8"
+__GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
+__GNUG__ 14
+__SIZE_TYPE__ long unsigned int
+__PTRDIFF_TYPE__ long int
+__WCHAR_TYPE__ int
+__WINT_TYPE__ unsigned int
+__INTMAX_TYPE__ long int
+__UINTMAX_TYPE__ long unsigned int
+__CHAR16_TYPE__ short unsigned int
+__CHAR32_TYPE__ unsigned int
+__SIG_ATOMIC_TYPE__ int
+__INT8_TYPE__ signed char
+__INT16_TYPE__ short int
+__INT32_TYPE__ int
+__INT64_TYPE__ long int
+__UINT8_TYPE__ unsigned char
+__UINT16_TYPE__ short unsigned int
+__UINT32_TYPE__ unsigned int
+__UINT64_TYPE__ long unsigned int
+__INT_LEAST8_TYPE__ signed char
+__INT_LEAST16_TYPE__ short int
+__INT_LEAST32_TYPE__ int
+__INT_LEAST64_TYPE__ long int
+__UINT_LEAST8_TYPE__ unsigned char
+__UINT_LEAST16_TYPE__ short unsigned int
+__UINT_LEAST32_TYPE__ unsigned int
+__UINT_LEAST64_TYPE__ long unsigned int
+__INT_FAST8_TYPE__ signed char
+__INT_FAST16_TYPE__ long int
+__INT_FAST32_TYPE__ long int
+__INT_FAST64_TYPE__ long int
+__UINT_FAST8_TYPE__ unsigned char
+__UINT_FAST16_TYPE__ long unsigned int
+__UINT_FAST32_TYPE__ long unsigned int
+__UINT_FAST64_TYPE__ long unsigned int
+__INTPTR_TYPE__ long int
+__UINTPTR_TYPE__ long unsigned int
+__GXX_WEAK__ 1
+__DEPRECATED 1
+__GXX_RTTI 1
+__cpp_rtti 199711L
+__GXX_EXPERIMENTAL_CXX0X__ 1
+__cpp_binary_literals 201304L
+__cpp_hex_float 201603L
+__cpp_runtime_arrays 198712L
+__cpp_raw_strings 200710L
+__cpp_unicode_literals 200710L
+__cpp_user_defined_literals 200809L
+__cpp_lambdas 200907L
+__cpp_decltype 200707L
+__cpp_attributes 200809L
+__cpp_rvalue_reference 200610L
+__cpp_rvalue_references 200610L
+__cpp_variadic_templates 200704L
+__cpp_initializer_lists 200806L
+__cpp_delegating_constructors 200604L
+__cpp_nsdmi 200809L
+__cpp_inheriting_constructors 201511L
+__cpp_ref_qualifiers 200710L
+__cpp_alias_templates 200704L
+__cpp_return_type_deduction 201304L
+__cpp_init_captures 201304L
+__cpp_generic_lambdas 201304L
+__cpp_decltype_auto 201304L
+__cpp_aggregate_nsdmi 201304L
+__cpp_variable_templates 201304L
+__cpp_digit_separators 201309L
+__cpp_unicode_characters 201411L
+__cpp_static_assert 201411L
+__cpp_namespace_attributes 201411L
+__cpp_enumerator_attributes 201411L
+__cpp_nested_namespace_definitions 201411L
+__cpp_fold_expressions 201603L
+__cpp_nontype_template_args 201411L
+__cpp_range_based_for 201603L
+__cpp_constexpr 201603L
+__cpp_if_constexpr 201606L
+__cpp_capture_star_this 201603L
+__cpp_inline_variables 201606L
+__cpp_aggregate_bases 201603L
+__cpp_deduction_guides 201703L
+__cpp_noexcept_function_type 201510L
+__cpp_template_auto 201606L
+__cpp_structured_bindings 201606L
+__cpp_variadic_using 201611L
+__cpp_guaranteed_copy_elision 201606L
+__cpp_nontype_template_parameter_auto 201606L
+__cpp_sized_deallocation 201309L
+__cpp_aligned_new 201606L
+__STDCPP_DEFAULT_NEW_ALIGNMENT__ 16
+__cpp_template_template_args 201611L
+__cpp_threadsafe_static_init 200806L
+__STDCPP_THREADS__ 1
+__EXCEPTIONS 1
+__cpp_exceptions 199711L
+__GXX_ABI_VERSION 1019
+__SCHAR_MAX__ 0x7f
+__SHRT_MAX__ 0x7fff
+__INT_MAX__ 0x7fffffff
+__LONG_MAX__ 0x7fffffffffffffffL
+__LONG_LONG_MAX__ 0x7fffffffffffffffLL
+__WCHAR_MAX__ 0x7fffffff
+__WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+__WINT_MAX__ 0xffffffffU
+__WINT_MIN__ 0U
+__PTRDIFF_MAX__ 0x7fffffffffffffffL
+__SIZE_MAX__ 0xffffffffffffffffUL
+__SCHAR_WIDTH__ 8
+__SHRT_WIDTH__ 16
+__INT_WIDTH__ 32
+__LONG_WIDTH__ 64
+__LONG_LONG_WIDTH__ 64
+__WCHAR_WIDTH__ 32
+__WINT_WIDTH__ 32
+__PTRDIFF_WIDTH__ 64
+__SIZE_WIDTH__ 64
+__GLIBCXX_TYPE_INT_N_0 __int128
+__GLIBCXX_BITSIZE_INT_N_0 128
+__INTMAX_MAX__ 0x7fffffffffffffffL
+__INTMAX_C(c) c ## L
+__UINTMAX_MAX__ 0xffffffffffffffffUL
+__UINTMAX_C(c) c ## UL
+__INTMAX_WIDTH__ 64
+__SIG_ATOMIC_MAX__ 0x7fffffff
+__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+__SIG_ATOMIC_WIDTH__ 32
+__INT8_MAX__ 0x7f
+__INT16_MAX__ 0x7fff
+__INT32_MAX__ 0x7fffffff
+__INT64_MAX__ 0x7fffffffffffffffL
+__UINT8_MAX__ 0xff
+__UINT16_MAX__ 0xffff
+__UINT32_MAX__ 0xffffffffU
+__UINT64_MAX__ 0xffffffffffffffffUL
+__INT_LEAST8_MAX__ 0x7f
+__INT8_C(c) c
+__INT_LEAST8_WIDTH__ 8
+__INT_LEAST16_MAX__ 0x7fff
+__INT16_C(c) c
+__INT_LEAST16_WIDTH__ 16
+__INT_LEAST32_MAX__ 0x7fffffff
+__INT32_C(c) c
+__INT_LEAST32_WIDTH__ 32
+__INT_LEAST64_MAX__ 0x7fffffffffffffffL
+__INT64_C(c) c ## L
+__INT_LEAST64_WIDTH__ 64
+__UINT_LEAST8_MAX__ 0xff
+__UINT8_C(c) c
+__UINT_LEAST16_MAX__ 0xffff
+__UINT16_C(c) c
+__UINT_LEAST32_MAX__ 0xffffffffU
+__UINT32_C(c) c ## U
+__UINT_LEAST64_MAX__ 0xffffffffffffffffUL
+__UINT64_C(c) c ## UL
+__INT_FAST8_MAX__ 0x7f
+__INT_FAST8_WIDTH__ 8
+__INT_FAST16_MAX__ 0x7fffffffffffffffL
+__INT_FAST16_WIDTH__ 64
+__INT_FAST32_MAX__ 0x7fffffffffffffffL
+__INT_FAST32_WIDTH__ 64
+__INT_FAST64_MAX__ 0x7fffffffffffffffL
+__INT_FAST64_WIDTH__ 64
+__UINT_FAST8_MAX__ 0xff
+__UINT_FAST16_MAX__ 0xffffffffffffffffUL
+__UINT_FAST32_MAX__ 0xffffffffffffffffUL
+__UINT_FAST64_MAX__ 0xffffffffffffffffUL
+__INTPTR_MAX__ 0x7fffffffffffffffL
+__INTPTR_WIDTH__ 64
+__UINTPTR_MAX__ 0xffffffffffffffffUL
+__GCC_IEC_559 2
+__GCC_IEC_559_COMPLEX 2
+__FLT_EVAL_METHOD__ 0
+__FLT_EVAL_METHOD_TS_18661_3__ 0
+__DEC_EVAL_METHOD__ 2
+__FLT_RADIX__ 2
+__FLT_MANT_DIG__ 24
+__FLT_DIG__ 6
+__FLT_MIN_EXP__ (-125)
+__FLT_MIN_10_EXP__ (-37)
+__FLT_MAX_EXP__ 128
+__FLT_MAX_10_EXP__ 38
+__FLT_DECIMAL_DIG__ 9
+__FLT_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
+__FLT_MIN__ 1.17549435082228750796873653722224568e-38F
+__FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
+__FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
+__FLT_HAS_DENORM__ 1
+__FLT_HAS_INFINITY__ 1
+__FLT_HAS_QUIET_NAN__ 1
+__FLT_IS_IEC_60559__ 1
+__DBL_MANT_DIG__ 53
+__DBL_DIG__ 15
+__DBL_MIN_EXP__ (-1021)
+__DBL_MIN_10_EXP__ (-307)
+__DBL_MAX_EXP__ 1024
+__DBL_MAX_10_EXP__ 308
+__DBL_DECIMAL_DIG__ 17
+__DBL_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_NORM_MAX__ double(1.79769313486231570814527423731704357e+308L)
+__DBL_MIN__ double(2.22507385850720138309023271733240406e-308L)
+__DBL_EPSILON__ double(2.22044604925031308084726333618164062e-16L)
+__DBL_DENORM_MIN__ double(4.94065645841246544176568792868221372e-324L)
+__DBL_HAS_DENORM__ 1
+__DBL_HAS_INFINITY__ 1
+__DBL_HAS_QUIET_NAN__ 1
+__DBL_IS_IEC_60559__ 1
+__LDBL_MANT_DIG__ 64
+__LDBL_DIG__ 18
+__LDBL_MIN_EXP__ (-16381)
+__LDBL_MIN_10_EXP__ (-4931)
+__LDBL_MAX_EXP__ 16384
+__LDBL_MAX_10_EXP__ 4932
+__DECIMAL_DIG__ 21
+__LDBL_DECIMAL_DIG__ 21
+__LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
+__LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+__LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
+__LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
+__LDBL_HAS_DENORM__ 1
+__LDBL_HAS_INFINITY__ 1
+__LDBL_HAS_QUIET_NAN__ 1
+__LDBL_IS_IEC_60559__ 1
+__FLT16_MANT_DIG__ 11
+__FLT16_DIG__ 3
+__FLT16_MIN_EXP__ (-13)
+__FLT16_MIN_10_EXP__ (-4)
+__FLT16_MAX_EXP__ 16
+__FLT16_MAX_10_EXP__ 4
+__FLT16_DECIMAL_DIG__ 5
+__FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
+__FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
+__FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
+__FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
+__FLT16_HAS_DENORM__ 1
+__FLT16_HAS_INFINITY__ 1
+__FLT16_HAS_QUIET_NAN__ 1
+__FLT16_IS_IEC_60559__ 1
+__FLT32_MANT_DIG__ 24
+__FLT32_DIG__ 6
+__FLT32_MIN_EXP__ (-125)
+__FLT32_MIN_10_EXP__ (-37)
+__FLT32_MAX_EXP__ 128
+__FLT32_MAX_10_EXP__ 38
+__FLT32_DECIMAL_DIG__ 9
+__FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
+__FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
+__FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
+__FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
+__FLT32_HAS_DENORM__ 1
+__FLT32_HAS_INFINITY__ 1
+__FLT32_HAS_QUIET_NAN__ 1
+__FLT32_IS_IEC_60559__ 1
+__FLT64_MANT_DIG__ 53
+__FLT64_DIG__ 15
+__FLT64_MIN_EXP__ (-1021)
+__FLT64_MIN_10_EXP__ (-307)
+__FLT64_MAX_EXP__ 1024
+__FLT64_MAX_10_EXP__ 308
+__FLT64_DECIMAL_DIG__ 17
+__FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
+__FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
+__FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
+__FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
+__FLT64_HAS_DENORM__ 1
+__FLT64_HAS_INFINITY__ 1
+__FLT64_HAS_QUIET_NAN__ 1
+__FLT64_IS_IEC_60559__ 1
+__FLT128_MANT_DIG__ 113
+__FLT128_DIG__ 33
+__FLT128_MIN_EXP__ (-16381)
+__FLT128_MIN_10_EXP__ (-4931)
+__FLT128_MAX_EXP__ 16384
+__FLT128_MAX_10_EXP__ 4932
+__FLT128_DECIMAL_DIG__ 36
+__FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
+__FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
+__FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
+__FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
+__FLT128_HAS_DENORM__ 1
+__FLT128_HAS_INFINITY__ 1
+__FLT128_HAS_QUIET_NAN__ 1
+__FLT128_IS_IEC_60559__ 1
+__FLT32X_MANT_DIG__ 53
+__FLT32X_DIG__ 15
+__FLT32X_MIN_EXP__ (-1021)
+__FLT32X_MIN_10_EXP__ (-307)
+__FLT32X_MAX_EXP__ 1024
+__FLT32X_MAX_10_EXP__ 308
+__FLT32X_DECIMAL_DIG__ 17
+__FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
+__FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
+__FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
+__FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
+__FLT32X_HAS_DENORM__ 1
+__FLT32X_HAS_INFINITY__ 1
+__FLT32X_HAS_QUIET_NAN__ 1
+__FLT32X_IS_IEC_60559__ 1
+__FLT64X_MANT_DIG__ 64
+__FLT64X_DIG__ 18
+__FLT64X_MIN_EXP__ (-16381)
+__FLT64X_MIN_10_EXP__ (-4931)
+__FLT64X_MAX_EXP__ 16384
+__FLT64X_MAX_10_EXP__ 4932
+__FLT64X_DECIMAL_DIG__ 21
+__FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+__FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
+__FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
+__FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
+__FLT64X_HAS_DENORM__ 1
+__FLT64X_HAS_INFINITY__ 1
+__FLT64X_HAS_QUIET_NAN__ 1
+__FLT64X_IS_IEC_60559__ 1
+__BFLT16_MANT_DIG__ 8
+__BFLT16_DIG__ 2
+__BFLT16_MIN_EXP__ (-125)
+__BFLT16_MIN_10_EXP__ (-37)
+__BFLT16_MAX_EXP__ 128
+__BFLT16_MAX_10_EXP__ 38
+__BFLT16_DECIMAL_DIG__ 4
+__BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
+__BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
+__BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
+__BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
+__BFLT16_HAS_DENORM__ 1
+__BFLT16_HAS_INFINITY__ 1
+__BFLT16_HAS_QUIET_NAN__ 1
+__BFLT16_IS_IEC_60559__ 0
+__DEC32_MANT_DIG__ 7
+__DEC32_MIN_EXP__ (-94)
+__DEC32_MAX_EXP__ 97
+__DEC32_MIN__ 1E-95DF
+__DEC32_MAX__ 9.999999E96DF
+__DEC32_EPSILON__ 1E-6DF
+__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+__DEC64_MANT_DIG__ 16
+__DEC64_MIN_EXP__ (-382)
+__DEC64_MAX_EXP__ 385
+__DEC64_MIN__ 1E-383DD
+__DEC64_MAX__ 9.999999999999999E384DD
+__DEC64_EPSILON__ 1E-15DD
+__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+__DEC128_MANT_DIG__ 34
+__DEC128_MIN_EXP__ (-6142)
+__DEC128_MAX_EXP__ 6145
+__DEC128_MIN__ 1E-6143DL
+__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+__DEC128_EPSILON__ 1E-33DL
+__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+__REGISTER_PREFIX__ 
+__USER_LABEL_PREFIX__ 
+__GNUC_STDC_INLINE__ 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+__GCC_ATOMIC_BOOL_LOCK_FREE 2
+__GCC_ATOMIC_CHAR_LOCK_FREE 2
+__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+__GCC_ATOMIC_SHORT_LOCK_FREE 2
+__GCC_ATOMIC_INT_LOCK_FREE 2
+__GCC_ATOMIC_LONG_LOCK_FREE 2
+__GCC_ATOMIC_LLONG_LOCK_FREE 2
+__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+__GCC_DESTRUCTIVE_SIZE 64
+__GCC_CONSTRUCTIVE_SIZE 64
+__GCC_ATOMIC_POINTER_LOCK_FREE 2
+__HAVE_SPECULATION_SAFE_VALUE 1
+__GCC_HAVE_DWARF2_CFI_ASM 1
+__PRAGMA_REDEFINE_EXTNAME 1
+__SIZEOF_INT128__ 16
+__SIZEOF_WCHAR_T__ 4
+__SIZEOF_WINT_T__ 4
+__SIZEOF_PTRDIFF_T__ 8
+__amd64 1
+__amd64__ 1
+__x86_64 1
+__x86_64__ 1
+__SIZEOF_FLOAT80__ 16
+__SIZEOF_FLOAT128__ 16
+__ATOMIC_HLE_ACQUIRE 65536
+__ATOMIC_HLE_RELEASE 131072
+__GCC_ASM_FLAG_OUTPUTS__ 1
+__k8 1
+__k8__ 1
+__code_model_small__ 1
+__MMX__ 1
+__SSE__ 1
+__SSE2__ 1
+__FXSR__ 1
+__SSE_MATH__ 1
+__SSE2_MATH__ 1
+__MMX_WITH_SSE__ 1
+__SEG_FS 1
+__SEG_GS 1
+__gnu_linux__ 1
+__linux 1
+__linux__ 1
+linux 1
+__unix 1
+__unix__ 1
+unix 1
+__ELF__ 1
+__DECIMAL_BID_FORMAT__ 1
+_GNU_SOURCE 1
+file /home/osandov/src/elfutils/tests/main.cc
+ file /usr/include/stdc-predef.h
+  _STDC_PREDEF_H 1
+  __STDC_IEC_559__ 1
+  __STDC_IEC_60559_BFP__ 201404L
+  __STDC_IEC_559_COMPLEX__ 1
+  __STDC_IEC_60559_COMPLEX__ 201404L
+  __STDC_ISO_10646__ 201706L
+ /file
+ file /home/osandov/src/elfutils/tests/foobar.h
+  FROB(x) ((x) ^ 0x2a2a2a2a)
+  FRY(x) ((x) * 0x100000001b3)
+ /file
+ MAIN_ARGS int argc, char **argv
+/file
+EOF
+done
+
 exit 0
diff --git a/tests/run-get-files.sh b/tests/run-get-files.sh
index 6f90be7d..1306544d 100755
--- a/tests/run-get-files.sh
+++ b/tests/run-get-files.sh
@@ -130,4 +130,119 @@ cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 296
  file[3] = "/usr/include/stdlib.h"
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/get-files testfile-dwp-5 << EOF
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 53
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 20, o = 21, asz = 8, osz = 4, ncu = 106
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 20, o = 42, asz = 8, osz = 4, ncu = 155
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+# Note that this one includes the type units in .debug_info.dwo as expected.
+testrun_compare ${abs_builddir}/get-files testfile-dwp-5.dwp << EOF
+cuhl = 24, o = 0, asz = 8, osz = 4, ncu = 112
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 376
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 24, o = 0, asz = 8, osz = 4, ncu = 486
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 606
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 1009
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+testrun_compare ${abs_builddir}/get-files testfile-dwp-4 << EOF
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 56
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 11, o = 29, asz = 8, osz = 4, ncu = 108
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 11, o = 55, asz = 8, osz = 4, ncu = 160
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+testrun_compare ${abs_builddir}/get-files testfile-dwp-4.dwp << EOF
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 286
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 404
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 857
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
 exit 0
diff --git a/tests/run-get-lines.sh b/tests/run-get-lines.sh
index fb48c77d..0c4e3389 100755
--- a/tests/run-get-lines.sh
+++ b/tests/run-get-lines.sh
@@ -88,4 +88,248 @@ cuhl = 11, o = 125, asz = 8, osz = 4, ncu = 243
  0 lines
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/get-lines testfile-dwp-5 << EOF
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 53
+ 63 lines
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401192: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401196: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bc: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:15:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:11: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c5: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cd: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d7: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:19:10: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f0: /home/osandov/src/elfutils/tests/foo.cc:20:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011fc: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 20, o = 21, asz = 8, osz = 4, ncu = 106
+ 7 lines
+401200: /home/osandov/src/elfutils/tests/bar.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401204: /home/osandov/src/elfutils/tests/bar.cc:8:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401207: /home/osandov/src/elfutils/tests/bar.cc:11:18: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121a: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121b: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 20, o = 42, asz = 8, osz = 4, ncu = 155
+ 41 lines
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401021: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401028: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40102c: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/main.cc:9:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:17:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:20:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401032: /home/osandov/src/elfutils/tests/main.cc:8:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401036: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40103f: /home/osandov/src/elfutils/tests/foobar.h:25:25: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401044: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401049: /home/osandov/src/elfutils/tests/foobar.h:23:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401050: /home/osandov/src/elfutils/tests/foobar.h:27:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401053: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401056: /home/osandov/src/elfutils/tests/foobar.h:27:9: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:28:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401065: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401068: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401076: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401080: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401085: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108a: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108c: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401091: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401095: /home/osandov/src/elfutils/tests/main.cc:10:22: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401097: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401099: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4010a0: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+EOF
+
+testrun_compare ${abs_builddir}/get-lines testfile-dwp-4 << EOF
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 56
+ 63 lines
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401192: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401196: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bc: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:15:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:11: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c5: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cd: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d7: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:19:10: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f0: /home/osandov/src/elfutils/tests/foo.cc:20:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011fc: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 29, asz = 8, osz = 4, ncu = 108
+ 7 lines
+401200: /home/osandov/src/elfutils/tests/bar.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401204: /home/osandov/src/elfutils/tests/bar.cc:8:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401207: /home/osandov/src/elfutils/tests/bar.cc:11:18: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121a: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121b: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 55, asz = 8, osz = 4, ncu = 160
+ 41 lines
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401021: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401028: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40102c: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/main.cc:9:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:17:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:20:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401032: /home/osandov/src/elfutils/tests/main.cc:8:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401036: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40103f: /home/osandov/src/elfutils/tests/foobar.h:25:25: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401044: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401049: /home/osandov/src/elfutils/tests/foobar.h:23:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401050: /home/osandov/src/elfutils/tests/foobar.h:27:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401053: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401056: /home/osandov/src/elfutils/tests/foobar.h:27:9: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:28:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401065: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401068: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401076: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401080: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401085: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108a: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108c: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401091: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401095: /home/osandov/src/elfutils/tests/main.cc:10:22: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401097: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401099: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4010a0: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+EOF
+
 exit 0
diff --git a/tests/run-get-units-split.sh b/tests/run-get-units-split.sh
index 7a43c670..6c7a4f25 100755
--- a/tests/run-get-units-split.sh
+++ b/tests/run-get-units-split.sh
@@ -63,4 +63,22 @@ EOF
 testrun_on_self_exe ${abs_builddir}/get-units-split
 testrun_on_self_lib ${abs_builddir}/get-units-split
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+testfiles testfile-dwp-4-strict testfile-dwp-4-strict.dwp
+
+for file in testfile-dwp-5 testfile-dwp-4 testfile-dwp-4-strict; do
+	testrun_compare ${abs_builddir}/get-units-split "$file" << EOF
+file: $file
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: foo.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: bar.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: main.cc
+
+EOF
+done
+
 exit 0
diff --git a/tests/run-next-files.sh b/tests/run-next-files.sh
index 7a3b6d0f..150a6a1a 100755
--- a/tests/run-next-files.sh
+++ b/tests/run-next-files.sh
@@ -162,4 +162,104 @@ off = 480
  file[1] = "f.c"
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/next-files testfile-dwp-5 << EOF
+off = 0
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 383
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 487
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+testrun_compare ${abs_builddir}/next-files testfile-dwp-5.dwp << EOF
+off = 0
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 127
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 254
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+testrun_compare ${abs_builddir}/next-files testfile-dwp-4 << EOF
+off = 0
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 397
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 515
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
+testrun_compare ${abs_builddir}/next-files testfile-dwp-4.dwp << EOF
+off = 0
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/foo.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 82
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/bar.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+off = 164
+ dirs[0] = "/home/osandov/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/osandov/src/elfutils/tests/main.cc"
+ file[2] = "/home/osandov/src/elfutils/tests/foobar.h"
+ file[3] = "/usr/include/stdc-predef.h"
+EOF
+
 exit 0
diff --git a/tests/run-next-lines.sh b/tests/run-next-lines.sh
index 84aee1c7..551b438e 100755
--- a/tests/run-next-lines.sh
+++ b/tests/run-next-lines.sh
@@ -113,4 +113,246 @@ off = 480
 8048472: f.c:5:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
 EOF
 
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testrun_compare ${abs_builddir}/next-lines testfile-dwp-5 << EOF
+off = 0
+ 63 lines
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401192: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401196: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bc: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:15:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:11: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c5: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cd: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d7: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:19:10: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f0: /home/osandov/src/elfutils/tests/foo.cc:20:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011fc: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+off = 383
+ 7 lines
+401200: /home/osandov/src/elfutils/tests/bar.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401204: /home/osandov/src/elfutils/tests/bar.cc:8:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401207: /home/osandov/src/elfutils/tests/bar.cc:11:18: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121a: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121b: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+off = 487
+ 41 lines
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401021: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401028: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40102c: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/main.cc:9:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:17:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:20:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401032: /home/osandov/src/elfutils/tests/main.cc:8:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401036: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40103f: /home/osandov/src/elfutils/tests/foobar.h:25:25: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401044: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401049: /home/osandov/src/elfutils/tests/foobar.h:23:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401050: /home/osandov/src/elfutils/tests/foobar.h:27:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401053: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401056: /home/osandov/src/elfutils/tests/foobar.h:27:9: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:28:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401065: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401068: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401076: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401080: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401085: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108a: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108c: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401091: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401095: /home/osandov/src/elfutils/tests/main.cc:10:22: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401097: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401099: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4010a0: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+EOF
+
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+testrun_compare ${abs_builddir}/next-lines testfile-dwp-4 << EOF
+off = 0
+ 63 lines
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401190: /home/osandov/src/elfutils/tests/foo.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401192: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401196: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40119e: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a1: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011a4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011b9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bb: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011bc: /home/osandov/src/elfutils/tests/foo.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:15:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c0: /home/osandov/src/elfutils/tests/foo.cc:16:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c2: /home/osandov/src/elfutils/tests/foo.cc:17:11: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c5: /home/osandov/src/elfutils/tests/foo.cc:17:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011c9: /home/osandov/src/elfutils/tests/foo.cc:18:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cb: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011cd: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d1: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d4: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011d7: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e0: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:5: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e3: /home/osandov/src/elfutils/tests/foo.cc:9:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e6: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011e9: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:10:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011eb: /home/osandov/src/elfutils/tests/foo.cc:19:10: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f0: /home/osandov/src/elfutils/tests/foo.cc:20:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:6:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011f8: /home/osandov/src/elfutils/tests/foo.cc:8:21: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+4011fc: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/foo.cc:8:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+off = 397
+ 7 lines
+401200: /home/osandov/src/elfutils/tests/bar.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401200: /home/osandov/src/elfutils/tests/bar.cc:8:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401204: /home/osandov/src/elfutils/tests/bar.cc:8:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401207: /home/osandov/src/elfutils/tests/bar.cc:11:18: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121a: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40121b: /home/osandov/src/elfutils/tests/bar.cc:12:1: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+off = 515
+ 41 lines
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:8:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401020: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401021: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401028: /home/osandov/src/elfutils/tests/main.cc:7:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40102c: /home/osandov/src/elfutils/tests/main.cc:8:28: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/main.cc:9:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:17:1: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401030: /home/osandov/src/elfutils/tests/foobar.h:20:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401032: /home/osandov/src/elfutils/tests/main.cc:8:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401036: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:19:3: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40103a: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40103f: /home/osandov/src/elfutils/tests/foobar.h:25:25: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401044: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401049: /home/osandov/src/elfutils/tests/foobar.h:23:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401050: /home/osandov/src/elfutils/tests/foobar.h:27:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401053: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401056: /home/osandov/src/elfutils/tests/foobar.h:27:9: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:28:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:29:4: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:7: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401059: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/foobar.h:25:34: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401060: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401065: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401068: /home/osandov/src/elfutils/tests/main.cc:9:40: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401076: /home/osandov/src/elfutils/tests/main.cc:9:51: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:3: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40107b: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401080: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401085: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108a: /home/osandov/src/elfutils/tests/main.cc:10:19: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+40108c: /home/osandov/src/elfutils/tests/main.cc:10:33: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401091: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401095: /home/osandov/src/elfutils/tests/main.cc:10:22: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401097: /home/osandov/src/elfutils/tests/main.cc:11:1: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+401099: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:no, bb:no, prologue:no, epilogue:no
+4010a0: /home/osandov/src/elfutils/tests/foobar.h:24:12: is_stmt:no, end_seq:yes, bb:no, prologue:no, epilogue:no
+EOF
+
 exit 0
diff --git a/tests/run-varlocs.sh b/tests/run-varlocs.sh
index cbbcf6c7..4ac5f367 100755
--- a/tests/run-varlocs.sh
+++ b/tests/run-varlocs.sh
@@ -601,4 +601,116 @@ module 'testfile-splitdwarf4-not-split4.debug'
       [4011a0,4011a1) {lit0, stack_value}
 EOF
 
+# See testfile-dwp.source.
+testfiles testfile-dwp-5 testfile-dwp-5.dwp
+testfiles testfile-dwp-4 testfile-dwp-4.dwp
+
+testrun_compare ${abs_builddir}/varlocs -e testfile-dwp-5 << EOF
+module 'testfile-dwp-5'
+[84] CU 'foo.cc'@401190
+  [c6] function 'foo'@4011c0
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [e1] parameter 'this'
+      [4011c0,401200) {reg5}
+    [ea] variable 'x'
+      [4011c2,4011d4) {reg0}
+      [4011d4,4011d7) {reg1}
+      [4011d7,4011d9) {breg1(1), stack_value}
+      [4011f1,401200) {reg0}
+  [f9] inlined function 'x_x'@4011cb
+    [104] parameter 'x'
+      [4011cb,4011eb) {reg0}
+      [4011f1,401200) {reg0}
+  [14a] function 'x_x'@401190
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [15b] parameter 'x'
+      [401190,4011a1) {reg5}
+      [4011a1,4011bd) {reg0}
+module 'testfile-dwp-5'
+[1fa] CU 'bar.cc'@401200
+  [23c] function 'bar'@401200
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [253] parameter 'this'
+      [401200,40121b) {reg5}
+module 'testfile-dwp-5'
+[272] CU 'main.cc'@0
+  [2c7] function 'main'@401020
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [2e0] parameter 'argc'
+      [401020,401068) {reg5}
+      [401068,401080) {fbreg(-40)}
+      [401080,401084) {breg5(0)}
+      [401084,401099) {entry_value(1) {reg5}, stack_value}
+      [401099,4010a0) {reg5}
+    [2ec] parameter 'argv'
+      [401020,40104b) {reg4}
+      [40104b,401099) {entry_value(1) {reg4}, stack_value}
+      [401099,4010a0) {reg4}
+    [2f8] variable 'myfoo'
+      [401020,4010a0) {fbreg(-40)}
+    [303] variable 'mybar'
+      [401020,4010a0) {fbreg(-32)}
+  [30d] inlined function 'fibonacci'@401030
+    [31c] parameter 'n'
+      [401030,401060) {reg5}
+      [401099,4010a0) {reg5}
+  [326] inlined function 'fibonacci'
+    [32f] parameter 'n'
+      <no value>
+EOF
+
+testrun_compare ${abs_builddir}/varlocs -e testfile-dwp-4 << EOF
+module 'testfile-dwp-4'
+[b] CU 'foo.cc'@401190
+  [54] function 'foo'@4011c0
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [6f] parameter 'this'
+      [4011c0,401200) {reg5}
+    [78] variable 'x'
+      [4011c2,4011d4) {reg0}
+      [4011d4,4011d7) {reg1}
+      [4011d7,4011d9) {breg1(1), stack_value}
+      [4011f1,401200) {reg0}
+  [8a] inlined function 'x_x'@4011cb
+    [98] parameter 'x'
+      [4011cb,4011eb) {reg0}
+      [4011f1,401200) {reg0}
+  [e7] function 'x_x'@401190
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [f8] parameter 'x'
+      [401190,4011a1) {reg5}
+      [4011a1,4011bd) {reg0}
+module 'testfile-dwp-4'
+[129] CU 'bar.cc'@401200
+  [172] function 'bar'@401200
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [189] parameter 'this'
+      [401200,40121b) {reg5}
+module 'testfile-dwp-4'
+[19f] CU 'main.cc'@0
+  [1fd] function 'main'@401020
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [216] parameter 'argc'
+      [401020,401068) {reg5}
+      [401068,401080) {fbreg(-40)}
+      [401080,401084) {breg5(0)}
+      [401084,401097) {GNU_entry_value(1) {reg5}, stack_value}
+      [401099,4010a0) {reg5}
+    [228] parameter 'argv'
+      [401020,40104b) {reg4}
+      [40104b,401099) {GNU_entry_value(1) {reg4}, stack_value}
+      [401099,4010a0) {reg4}
+    [23a] variable 'myfoo'
+      [401020,4010a0) {fbreg(-40)}
+    [247] variable 'mybar'
+      [401020,4010a0) {fbreg(-32)}
+  [253] inlined function 'fibonacci'@401030
+    [265] parameter 'n'
+      [401030,401060) {reg5}
+      [401099,4010a0) {reg5}
+  [272] inlined function 'fibonacci'
+    [27e] parameter 'n'
+      <no value>
+EOF
+
 exit 0
-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes
  2024-02-26 19:32 [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support Omar Sandoval
                   ` (2 preceding siblings ...)
  2024-02-26 19:32 ` [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate Omar Sandoval
@ 2024-02-26 19:32 ` Omar Sandoval
  2024-03-01 14:59   ` Mark Wielaard
  3 siblings, 1 reply; 11+ messages in thread
From: Omar Sandoval @ 2024-02-26 19:32 UTC (permalink / raw)
  To: elfutils-devel

From: Omar Sandoval <osandov@fb.com>

Meta uses DWARF package files for our large, statically-linked C++
applications.  Some of our largest applications have more than 4GB in
.debug_info.dwo, but the section offsets in .debug_cu_index and
.debug_tu_index are 32 bits; see the discussion here [1].  We
implemented a workaround/extension for this in LLVM.  Implement the
equivalent in libdw.

To test this, we need files with more than 4GB in .debug_info.dwo.  I
created these artificially by editing GCC's assembly output.  They
compress down to 6KB.  I test them from run-large-elf-file.sh to take
advantage of the existing checks for large file support.

1: https://discourse.llvm.org/t/dwarf-dwp-4gb-limit/63902.

 	* libdw/dwarf_end.c (dwarf_package_index_free): New function.
	* tests/testfile-dwp-4-cu-index-overflow.bz2: New test file.
	* tests/testfile-dwp-4-cu-index-overflow.dwp.bz2: New test file.
	* tests/testfile-dwp-5-cu-index-overflow.bz2: New test file.
	* tests/testfile-dwp-5-cu-index-overflow.dwp.bz2: New test file.
	* tests/testfile-dwp-cu-index-overflow.source: New file.
	* tests/run-large-elf-file.sh: Check
	testfile-dwp-5-cu-index-overflow and
	testfile-dwp-4-cu-index-overflow.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 libdw/dwarf_cu_dwp_section_info.c             | 147 ++++++++++++++-
 libdw/dwarf_end.c                             |  15 +-
 libdw/libdwP.h                                |   3 +
 tests/Makefile.am                             |   7 +-
 tests/run-large-elf-file.sh                   | 174 ++++++++++++++++++
 tests/testfile-dwp-4-cu-index-overflow.bz2    | Bin 0 -> 4490 bytes
 .../testfile-dwp-4-cu-index-overflow.dwp.bz2  | Bin 0 -> 5584 bytes
 tests/testfile-dwp-5-cu-index-overflow.bz2    | Bin 0 -> 4544 bytes
 .../testfile-dwp-5-cu-index-overflow.dwp.bz2  | Bin 0 -> 5790 bytes
 tests/testfile-dwp-cu-index-overflow.source   |  86 +++++++++
 10 files changed, 426 insertions(+), 6 deletions(-)
 create mode 100755 tests/testfile-dwp-4-cu-index-overflow.bz2
 create mode 100644 tests/testfile-dwp-4-cu-index-overflow.dwp.bz2
 create mode 100755 tests/testfile-dwp-5-cu-index-overflow.bz2
 create mode 100644 tests/testfile-dwp-5-cu-index-overflow.dwp.bz2
 create mode 100644 tests/testfile-dwp-cu-index-overflow.source

diff --git a/libdw/dwarf_cu_dwp_section_info.c b/libdw/dwarf_cu_dwp_section_info.c
index 298f36f9..3d11c87a 100644
--- a/libdw/dwarf_cu_dwp_section_info.c
+++ b/libdw/dwarf_cu_dwp_section_info.c
@@ -30,6 +30,8 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
+
 #include "libdwP.h"
 
 static Dwarf_Package_Index *
@@ -110,7 +112,9 @@ __libdw_read_package_index (Dwarf *dbg, bool tu)
 
   index->dbg = dbg;
   /* Set absent sections to UINT32_MAX.  */
-  memset (index->sections, 0xff, sizeof (index->sections));
+  for (size_t i = 0;
+       i < sizeof (index->sections) / sizeof (index->sections[0]); i++)
+    index->sections[i] = UINT32_MAX;
   for (size_t i = 0; i < section_count; i++)
     {
       uint32_t section = read_4ubyte_unaligned (dbg, sections + i * 4);
@@ -161,6 +165,7 @@ __libdw_read_package_index (Dwarf *dbg, bool tu)
   index->indices = indices;
   index->section_offsets = section_offsets;
   index->section_sizes = section_sizes;
+  index->debug_info_offsets = NULL;
 
   return index;
 }
@@ -177,6 +182,137 @@ __libdw_package_index (Dwarf *dbg, bool tu)
   if (index == NULL)
     return NULL;
 
+  /* Offsets in the section offset table are 32-bit unsigned integers.  In
+     practice, the .debug_info.dwo section for very large executables can be
+     larger than 4GB.  GNU dwp as of binutils 2.41 and llvm-dwp before LLVM 15
+     both accidentally truncate offsets larger than 4GB.
+
+     LLVM 15 detects the overflow and errors out instead; see LLVM commit
+     f8df8114715b ("[DWP][DWARF] Detect and error on debug info offset
+     overflow").  However, lldb in LLVM 16 supports using dwp files with
+     truncated offsets by recovering them directly from the unit headers in the
+     .debug_info.dwo section; see LLVM commit c0db06227721 ("[DWARFLibrary] Add
+     support to re-construct cu-index").  Since LLVM 17, the overflow error can
+     be turned into a warning instead; see LLVM commit 53a483cee801 ("[DWP] add
+     overflow check for llvm-dwp tools if offset overflow").
+
+     LLVM's support for > 4GB offsets is effectively an extension to the DWARF
+     package file format, which we implement here.  The strategy is to walk the
+     unit headers in .debug_info.dwo in lockstep with the DW_SECT_INFO columns
+     in the section offset tables.  As long as they are in the same order
+     (which they are in practice for both GNU dwp and llvm-dwp), we can
+     correlate the truncated offset and produce a corrected array of offsets.
+
+     Note that this will be fixed properly in DWARF 6:
+     https://dwarfstd.org/issues/220708.2.html.  */
+  if (index->sections[DW_SECT_INFO - 1] != UINT32_MAX
+      && dbg->sectiondata[IDX_debug_info]->d_size > UINT32_MAX)
+    {
+      Dwarf_Package_Index *cu_index, *tu_index = NULL;
+      if (tu)
+	{
+	  tu_index = index;
+	  assert (dbg->cu_index == NULL);
+	  cu_index = __libdw_read_package_index (dbg, false);
+	  if (cu_index == NULL)
+	    {
+	      free(index);
+	      return NULL;
+	    }
+	}
+      else
+	{
+	  cu_index = index;
+	  if (dbg->sectiondata[IDX_debug_tu_index] != NULL
+	      && dbg->sectiondata[IDX_debug_types] == NULL)
+	    {
+	      assert (dbg->tu_index == NULL);
+	      tu_index = __libdw_read_package_index (dbg, true);
+	      if (tu_index == NULL)
+		{
+		  free(index);
+		  return NULL;
+		}
+	    }
+	}
+
+      cu_index->debug_info_offsets = malloc (cu_index->unit_count
+					     * sizeof (Dwarf_Off));
+      if (cu_index->debug_info_offsets == NULL)
+	{
+	  free (tu_index);
+	  free (cu_index);
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  return NULL;
+	}
+      if (tu_index != NULL)
+	{
+	  tu_index->debug_info_offsets = malloc (tu_index->unit_count
+						 * sizeof (Dwarf_Off));
+	  if (tu_index->debug_info_offsets == NULL)
+	    {
+	      free (tu_index);
+	      free (cu_index->debug_info_offsets);
+	      free (cu_index);
+	      __libdw_seterrno (DWARF_E_NOMEM);
+	      return NULL;
+	    }
+	}
+
+      Dwarf_Off off = 0;
+      uint32_t cui = 0, tui = 0;
+      uint32_t cu_count = cu_index->unit_count;
+      const unsigned char *cu_offset
+	= cu_index->section_offsets + cu_index->sections[DW_SECT_INFO - 1] * 4;
+      uint32_t tu_count = 0;
+      const unsigned char *tu_offset;
+      if (tu_index != NULL)
+	{
+	  tu_count = tu_index->unit_count;
+	  tu_offset = tu_index->section_offsets
+		      + tu_index->sections[DW_SECT_INFO - 1] * 4;
+	}
+      while (cui < cu_count || tui < tu_count)
+	{
+	  Dwarf_Off next_off;
+	  uint8_t unit_type;
+	  if (__libdw_next_unit (dbg, false, off, &next_off, NULL, NULL,
+				 &unit_type, NULL, NULL, NULL, NULL, NULL)
+	      != 0)
+	    {
+	    not_sorted:
+	      free (cu_index->debug_info_offsets);
+	      cu_index->debug_info_offsets = NULL;
+	      if (tu_index != NULL)
+		{
+		  free (tu_index->debug_info_offsets);
+		  tu_index->debug_info_offsets = NULL;
+		}
+	      break;
+	    }
+	  if (unit_type != DW_UT_split_type && cui < cu_count)
+	    {
+	      if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, cu_offset))
+		goto not_sorted;
+	      cu_index->debug_info_offsets[cui++] = off;
+	      cu_offset += cu_index->section_count * 4;
+	    }
+	  else if (unit_type == DW_UT_split_type && tui < tu_count)
+	    {
+	      if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, tu_offset))
+		goto not_sorted;
+	      tu_index->debug_info_offsets[tui++] = off;
+	      tu_offset += tu_index->section_count * 4;
+	    }
+	  off = next_off;
+	}
+
+      if (tu)
+	dbg->cu_index = cu_index;
+      else if (tu_index != NULL)
+	dbg->tu_index = tu_index;
+    }
+
   if (tu)
     dbg->tu_index = index;
   else
@@ -244,8 +380,13 @@ __libdw_dwp_section_info (Dwarf_Package_Index *index, uint32_t unit_row,
   size_t i = (size_t)(unit_row - 1) * index->section_count
 	     + index->sections[section - 1];
   if (offsetp != NULL)
-    *offsetp = read_4ubyte_unaligned (index->dbg,
-				      index->section_offsets + i * 4);
+    {
+      if (section == DW_SECT_INFO && index->debug_info_offsets != NULL)
+	*offsetp = index->debug_info_offsets[unit_row - 1];
+      else
+	*offsetp = read_4ubyte_unaligned (index->dbg,
+					  index->section_offsets + i * 4);
+    }
   if (sizep != NULL)
     *sizep = read_4ubyte_unaligned (index->dbg,
 				    index->section_sizes + i * 4);
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 78224ddb..ed8d27be 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -40,6 +40,17 @@
 #include "cfi.h"
 
 
+static void
+dwarf_package_index_free (Dwarf_Package_Index *index)
+{
+  if (index != NULL)
+    {
+      free (index->debug_info_offsets);
+      free (index);
+    }
+}
+
+
 static void
 noop_free (void *arg __attribute__ ((unused)))
 {
@@ -79,8 +90,8 @@ dwarf_end (Dwarf *dwarf)
 {
   if (dwarf != NULL)
     {
-      free (dwarf->tu_index);
-      free (dwarf->cu_index);
+      dwarf_package_index_free (dwarf->tu_index);
+      dwarf_package_index_free (dwarf->cu_index);
 
       if (dwarf->cfi != NULL)
 	/* Clean up the CFI cache.  */
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 1a0a4df3..6018399c 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -371,6 +371,9 @@ typedef struct Dwarf_Package_Index_s
   const unsigned char *indices;
   const unsigned char *section_offsets;
   const unsigned char *section_sizes;
+  /* If DW_SECT_INFO section offsets were truncated to 32 bits, recovered
+     64-bit offsets.  */
+  Dwarf_Off *debug_info_offsets;
 } Dwarf_Package_Index;
 
 /* CU representation.  */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3f80c451..98131a6b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -641,7 +641,12 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 	     testfile-dwp-4.bz2 testfile-dwp-4.dwp.bz2 \
 	     testfile-dwp-4-strict.bz2 testfile-dwp-4-strict.dwp.bz2 \
 	     testfile-dwp-5.bz2 testfile-dwp-5.dwp.bz2 testfile-dwp.source \
-	     run-cu-dwp-section-info.sh run-declfiles.sh
+	     run-cu-dwp-section-info.sh run-declfiles.sh \
+	     testfile-dwp-5-cu-index-overflow \
+	     testfile-dwp-5-cu-index-overflow.dwp \
+	     testfile-dwp-4-cu-index-overflow \
+	     testfile-dwp-4-cu-index-overflow.dwp \
+	     testfile-dwp-cu-index-overflow.source
 
 
 if USE_VALGRIND
diff --git a/tests/run-large-elf-file.sh b/tests/run-large-elf-file.sh
index 7116de53..8108cb4b 100755
--- a/tests/run-large-elf-file.sh
+++ b/tests/run-large-elf-file.sh
@@ -122,4 +122,178 @@ test_file testfile38
 # 64bit, big endian, non-rel
 test_file testfile27
 
+# See testfile-dwp-cu-index-overflow.source
+testfiles testfile-dwp-5-cu-index-overflow testfile-dwp-5-cu-index-overflow.dwp
+
+testrun_compare ${abs_builddir}/cu-dwp-section-info testfile-dwp-5-cu-index-overflow.dwp << EOF
+file: testfile-dwp-5-cu-index-overflow.dwp
+INFO: 0x0 0x8000004c
+TYPES: 0x0 0x0
+ABBREV: 0x0 0x50
+LINE: 0x0 0x61
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x0 0x1c
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x8000004c 0x6f
+TYPES: 0x0 0x0
+ABBREV: 0x50 0x15e
+LINE: 0x61 0x63
+LOCLISTS: 0x0 0xd4
+STR_OFFSETS: 0x1c 0x24
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x22
+
+INFO: 0x800000bb 0xff
+TYPES: 0x0 0x0
+ABBREV: 0x50 0x15e
+LINE: 0x61 0x63
+LOCLISTS: 0x0 0xd4
+STR_OFFSETS: 0x1c 0x24
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x22
+
+INFO: 0x800001ba 0x8000004c
+TYPES: 0x0 0x0
+ABBREV: 0x1ae 0x50
+LINE: 0xc4 0x61
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x40 0x1c
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x100000206 0x6c
+TYPES: 0x0 0x0
+ABBREV: 0x1fe 0xc8
+LINE: 0x125 0x63
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x5c 0x20
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x100000272 0x6f
+TYPES: 0x0 0x0
+ABBREV: 0x1fe 0xc8
+LINE: 0x125 0x63
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x5c 0x20
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x1000002e1 0x182
+TYPES: 0x0 0x0
+ABBREV: 0x2c6 0x188
+LINE: 0x188 0x65
+LOCLISTS: 0xd4 0xee
+STR_OFFSETS: 0x7c 0x44
+MACRO: 0x0 0x0
+RNGLISTS: 0x22 0x43
+
+EOF
+
+testrun_compare ${abs_builddir}/get-units-split testfile-dwp-5-cu-index-overflow << EOF
+file: testfile-dwp-5-cu-index-overflow
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: filler1.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: foo.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: filler2.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: bar.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: main.cc
+
+EOF
+
+rm -f testfile-dwp-5-cu-index-overflow testfile-dwp-5-cu-index-overflow.dwp
+
+# See testfile-dwp-cu-index-overflow.source
+testfiles testfile-dwp-4-cu-index-overflow testfile-dwp-4-cu-index-overflow.dwp
+
+testrun_compare ${abs_builddir}/cu-dwp-section-info testfile-dwp-4-cu-index-overflow.dwp << EOF
+file: testfile-dwp-4-cu-index-overflow.dwp
+INFO: 0x0 0x8000004b
+TYPES: 0x0 0x0
+ABBREV: 0x0 0x58
+LINE: 0x0 0x2c
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x0 0x14
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x8000004b 0x116
+TYPES: 0x0 0x0
+ABBREV: 0x58 0x16f
+LINE: 0x2c 0x34
+LOCLISTS: 0x0 0x110
+STR_OFFSETS: 0x14 0x1c
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x80000161 0x8000004b
+TYPES: 0x0 0x0
+ABBREV: 0x1c7 0x58
+LINE: 0x60 0x2c
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x30 0x14
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x1000001ac 0x6e
+TYPES: 0x0 0x0
+ABBREV: 0x21f 0xd4
+LINE: 0x8c 0x34
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x44 0x18
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x10000021a 0x1b5
+TYPES: 0x0 0x0
+ABBREV: 0x2f3 0x19b
+LINE: 0xc0 0x35
+LOCLISTS: 0x110 0x12a
+STR_OFFSETS: 0x5c 0x3c
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x0 0x0
+TYPES: 0x0 0x6e
+ABBREV: 0x58 0x16f
+LINE: 0x2c 0x34
+LOCLISTS: 0x0 0x110
+STR_OFFSETS: 0x14 0x1c
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+INFO: 0x0 0x0
+TYPES: 0x6e 0x6b
+ABBREV: 0x21f 0xd4
+LINE: 0x8c 0x34
+LOCLISTS: 0x0 0x0
+STR_OFFSETS: 0x44 0x18
+MACRO: 0x0 0x0
+RNGLISTS: 0x0 0x0
+
+EOF
+
+testrun_compare ${abs_builddir}/get-units-split testfile-dwp-4-cu-index-overflow << EOF
+file: testfile-dwp-4-cu-index-overflow
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: filler1.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: foo.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: filler2.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: bar.cc
+Got cudie unit_type: 4
+Found a skeleton unit, with split die: main.cc
+
+EOF
+
+rm -f testfile-dwp-4-cu-index-overflow testfile-dwp-4-cu-index-overflow.dwp
+
 exit 0
diff --git a/tests/testfile-dwp-4-cu-index-overflow.bz2 b/tests/testfile-dwp-4-cu-index-overflow.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..2aaa4f40b8d0bacf75f617a9ad642a6ead10a6ef
GIT binary patch
literal 4490
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

literal 0
HcmV?d00001

diff --git a/tests/testfile-dwp-4-cu-index-overflow.dwp.bz2 b/tests/testfile-dwp-4-cu-index-overflow.dwp.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..0718c1b2c40310655cdb78ae9859b7b682a5fcaf
GIT binary patch
literal 5584
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
Pwxd_;8J$6MsC@D-pOqt+

literal 0
HcmV?d00001

diff --git a/tests/testfile-dwp-5-cu-index-overflow.bz2 b/tests/testfile-dwp-5-cu-index-overflow.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..07185fe56fcbfcf9a6fa01e6ef9428fee3843f34
GIT binary patch
literal 4544
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

literal 0
HcmV?d00001

diff --git a/tests/testfile-dwp-5-cu-index-overflow.dwp.bz2 b/tests/testfile-dwp-5-cu-index-overflow.dwp.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..dce34e3f51d637e4773c3c8e4ebeb4666b4c0571
GIT binary patch
literal 5790
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
ZQVs!Wj1ebEH_TeZF<rUYrnf)Q{|jo{jkEv&

literal 0
HcmV?d00001

diff --git a/tests/testfile-dwp-cu-index-overflow.source b/tests/testfile-dwp-cu-index-overflow.source
new file mode 100644
index 00000000..2de15441
--- /dev/null
+++ b/tests/testfile-dwp-cu-index-overflow.source
@@ -0,0 +1,86 @@
+# Dummy program that we patch to generate a dwp file with more than 4GB of
+# .debug_info.
+
+# Generate 2 dummy files that result in DWARF blocks.
+$ for (( i = 1; i <= 2; i++ )); do echo 'constexpr int filler'$i'[] = { 1 };' > filler$i.cc; done
+$ g++ -O2 -g -gsplit-dwarf -fdebug-types-section -dA -S filler{1,2}.cc foo.cc bar.cc main.cc
+# Patch the DWARF blocks to be 2GB.
+$ for (( i = 1; i <= 2; i++ )); do patch -p1 << EOF
+--- a/filler$i.s
++++ b/filler$i.s
+@@ -7,5 +7,5 @@
+ 	.section	.debug_info.dwo,"e",@progbits
+ .Ldebug_info0:
+-	.long	0x49	# Length of Compilation Unit Info
++	.long	0x80000048	# Length of Compilation Unit Info
+ 	.value	0x5	# DWARF version number
+ 	.byte	0x5	# DW_UT_split_compile
+@@ -51,9 +51,6 @@
+ 	.long	0x29	# DW_AT_type
+ 			# DW_AT_const_expr
+-	.byte	0x4	# DW_AT_const_value
+-	.byte	0x1	# fp or vector constant word 0
+-	.byte	0	# fp or vector constant word 1
+-	.byte	0	# fp or vector constant word 2
+-	.byte	0	# fp or vector constant word 3
++	.long	0x80000000	# DW_AT_const_value
++	.fill	0x80000000
+ 	.byte	0	# end of children of DIE 0x14
+ 	.section	.debug_info,"",@progbits
+@@ -171,5 +168,5 @@
+ 	.uleb128 0x19	# (DW_FORM_flag_present)
+ 	.uleb128 0x1c	# (DW_AT_const_value)
+-	.uleb128 0xa	# (DW_FORM_block1)
++	.uleb128 0x4	# (DW_FORM_block4)
+ 	.byte	0
+ 	.byte	0
+EOF
+done
+$ for (( i = 1; i <= 2; i++ )); do as filler$i.s -o filler$i.o; done
+$ as foo.s -o foo.o
+$ as bar.s -o bar.o
+$ as main.s -o main.o
+$ g++ filler1.o foo.o filler2.o bar.o main.o -o testfile-dwp-5-cu-index-overflow
+# -continue-on-cu-index-overflow was added in LLVM 17:
+# https://reviews.llvm.org/D144565.
+$ llvm-dwp -continue-on-cu-index-overflow filler1.o foo.o filler2.o bar.o main.o -o testfile-dwp-5-cu-index-overflow.dwp
+
+# Same thing for DWARF 4.
+$ g++ -O2 -g -gdwarf-4 -gsplit-dwarf -fdebug-types-section -dA -S filler{1,2}.cc foo.cc bar.cc main.cc
+$ for (( i = 1; i <= 2; i++ )); do patch -p1 << EOF
+--- a/filler$i.s
++++ b/filler$i.s
+@@ -6,5 +6,5 @@
+ 	.section	.debug_info.dwo,"e",@progbits
+ .Ldebug_info0:
+-	.long	0x48	# Length of Compilation Unit Info
++	.long	0x80000047	# Length of Compilation Unit Info
+ 	.value	0x4	# DWARF version number
+ 	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+@@ -49,9 +49,6 @@
+ 	.long	0x28	# DW_AT_type
+ 			# DW_AT_const_expr
+-	.byte	0x4	# DW_AT_const_value
+-	.byte	0x1	# fp or vector constant word 0
+-	.byte	0	# fp or vector constant word 1
+-	.byte	0	# fp or vector constant word 2
+-	.byte	0	# fp or vector constant word 3
++	.long	0x80000000	# DW_AT_const_value
++	.fill	0x80000000
+ 	.byte	0	# end of children of DIE 0xb
+ 	.section	.debug_info,"",@progbits
+@@ -172,5 +169,5 @@
+ 	.uleb128 0x19	# (DW_FORM_flag_present)
+ 	.uleb128 0x1c	# (DW_AT_const_value)
+-	.uleb128 0xa	# (DW_FORM_block1)
++	.uleb128 0x4	# (DW_FORM_block4)
+ 	.byte	0
+ 	.byte	0
+EOF
+done
+$ for (( i = 1; i <= 2; i++ )); do as filler$i.s -o filler$i.o; done
+$ as foo.s -o foo.o
+$ as bar.s -o bar.o
+$ as main.s -o main.o
+$ g++ filler1.o foo.o filler2.o bar.o main.o -o testfile-dwp-4-cu-index-overflow
+$ llvm-dwp -continue-on-cu-index-overflow filler1.o foo.o filler2.o bar.o main.o -o testfile-dwp-4-cu-index-overflow.dwp
-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file
  2024-02-26 19:32 ` [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file Omar Sandoval
@ 2024-02-29 22:08   ` Mark Wielaard
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Wielaard @ 2024-02-29 22:08 UTC (permalink / raw)
  To: Omar Sandoval; +Cc: elfutils-devel

Hi Omar,

On Mon, Feb 26, 2024 at 11:32:48AM -0800, Omar Sandoval wrote:
> Calling dwarf_decl_file on a split DWARF DIE fails this assertion:
> 
>   dwarf_decl_file.c:72: dwarf_decl_file: Assertion `cu->files != NULL && cu->files != (void *) -1l' failed.
> 
> This is because dwarf_decl_file calls dwarf_getsrclines to populate
> cu->files.  For normal units, cu->files is cached by dwarf_getsrclines
> when it parses the line number information.  However, for split units,
> the line number information is parsed for the skeleton unit, then copied
> to the split unit's cu->lines.  Split units have their own file name
> table, so cu->files is not copied.
> 
> The obvious solution is to use dwarf_getsrcfiles instead of relying on
> implicit caching.

And it cleans up the code nicely.

> Also add a test case for dwarf_decl_file.

Thanks.

> 
> 	* libdw/dwarf_decl_file.c (dwarf_decl_file): Use
> 	dwarf_getsrcfiles instead of dwarf_getsrclines.
> 	* tests/Makefile.am (check_PROGRAMS): Add declfiles.
> 	(TESTS): Add run-declfiles.sh.
> 	(EXTRA_DIST): Add run-declfiles.sh.
> 	(declfiles_LDADD): New variable.
> 	* tests/declfiles.c: New test.
> 	* tests/run-declfiles.sh: New test.

All looks good. Pushed.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU
  2024-02-26 19:32 ` [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU Omar Sandoval
@ 2024-02-29 22:59   ` Mark Wielaard
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Wielaard @ 2024-02-29 22:59 UTC (permalink / raw)
  To: Omar Sandoval; +Cc: elfutils-devel

Hi Omar,

On Mon, Feb 26, 2024 at 11:32:49AM -0800, Omar Sandoval wrote:
> dwarf_next_lines has two loops over CUs: one from the CU after the given
> CU to the end, and one from the first CU up to _but not including_ the
> given CU.  This means that the given CU is never checked.
> 
> This is unlikely to matter in practice since CUs usually correspond 1:1
> with line number tables in the same order, but let's fix it anyways.
> Refactoring it to one loop fixes the problem and simplifies the next
> change to support DWARF package files.
> 
> 	* libdw/dwarf_next_lines.c (dwarf_next_lines): Refactor loops
> 	over CUs into one loop.

Thanks. The patch itself was hard to understand, but when applied the
code is pretty clear. I only had to double check the reversal of the
split unit check was correct.

Pushed,

Mark

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate
  2024-02-26 19:32 ` [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate Omar Sandoval
@ 2024-02-29 23:49   ` Mark Wielaard
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Wielaard @ 2024-02-29 23:49 UTC (permalink / raw)
  To: Omar Sandoval; +Cc: elfutils-devel

Hi Omar,

On Mon, Feb 26, 2024 at 11:32:50AM -0800, Omar Sandoval wrote:
> The final piece of DWARF package file support is that offsets have to be
> interpreted relative to the section offset from the package index.
> .debug_abbrev.dwo is already covered, so sprinkle around calls to
> dwarf_cu_dwp_section_info for the remaining sections: .debug_line.dwo,
> .debug_loclists.dwo/.debug_loc.dwo, .debug_str_offsets.dwo,
> .debug_macro.dwo/.debug_macinfo.dwo, and .debug_rnglists.dwo.  With all
> of that in place, we can finally test various libdw functions on dwp
> files.
> 
> 	* libdw/dwarf_getlocation.c (initial_offset): Call
> 	dwarf_cu_dwp_section_info and add offset to start_offset.
> 	* libdw/dwarf_getmacros.c (get_macinfo_table): Call
> 	dwarf_cu_dwp_section_info and add offset to line_offset.
> 	(get_offset_from): Call dwarf_cu_dwp_section_info and add offset
> 	to *retp.
> 	* libdw/dwarf_getsrcfiles.c (dwarf_getsrcfiles): Call
> 	dwarf_cu_dwp_section_info and pass offset to
>         __libdw_getsrclines.
> 	* libdw/dwarf_next_lines.c (dwarf_next_lines): Call
> 	dwarf_cu_dwp_section_info and add offset to stmt_off.
> 	* libdw/libdwP.h (str_offsets_base_off): Call
> 	dwarf_cu_dwp_section_info and add offset.
> 	(__libdw_cu_ranges_base): Ditto.
> 	(__libdw_cu_locs_base): Ditto.
> 	* tests/run-all-dwarf-ranges.sh: Check testfile-dwp-5 and
> 	testfile-dwp-4.
> 	* tests/run-declfiles.sh: Ditto.
> 	* tests/run-get-lines.sh: Ditto.
> 	* tests/run-next-lines.sh: Ditto.
> 	* tests/run-varlocs.sh: Ditto.
> 	* tests/run-get-files.sh: Check testfile-dwp-5,
> 	testfile-dwp-5.dwp, testfile-dwp-4, and testfile-dwp-4.dwp
> 	* tests/run-next-files.sh: Ditto.
> 	* tests/run-dwarf-getmacros.sh: Check testfile-dwp-5 and
> 	testfile-dwp-4-strict.
> 	* tests/run-get-units-split.sh: Ditto.

Very nice. So the only changes from V2 are

> diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
> index 12fdabf2..cd2e5b5a 100644
> --- a/libdw/dwarf_getsrcfiles.c
> +++ b/libdw/dwarf_getsrcfiles.c
> @@ -64,12 +64,17 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
>  	     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);
> +	      Dwarf_Off dwp_off;
> +	      if (INTUSE(dwarf_cu_dwp_section_info) (cu, DW_SECT_LINE,
> +						     &dwp_off, NULL) == 0)
> +		{
> +		  /* We are only interested in the files, the lines will
> +		     always come from the skeleton.  */
> +		  res = __libdw_getsrclines (cu->dbg, dwp_off,
> +					     __libdw_getcompdir (cudie),
> +					     cu->address_size, NULL,
> +					     &cu->files);
> +		}
>  	    }
>  	  else
>  	    {

Looks correct.

> diff --git a/libdw/dwarf_next_lines.c b/libdw/dwarf_next_lines.c
> index 6a9fe361..a96bd73e 100644
> --- a/libdw/dwarf_next_lines.c
> +++ b/libdw/dwarf_next_lines.c
> @@ -132,6 +132,11 @@ dwarf_next_lines (Dwarf *dbg, Dwarf_Off off,
>  		   && next_cu->unit_type != DW_UT_split_type)
>  	    continue;
>  
> +	  Dwarf_Off dwp_off;
> +	  if (INTUSE(dwarf_cu_dwp_section_info) (next_cu, DW_SECT_LINE,
> +						 &dwp_off, NULL) == 0)
> +	    stmt_off += dwp_off;
> +
>  	  if (stmt_off == off)
>  	    {
>  	      *cu = next_cu;

Also correct.

And the new tests in run-declfiles.sh, run-get-files.sh,
run-get-lines.sh, run-next-files.sh and run-next-lines.sh.

You are certainly very thorough. Thanks.

Pushed,

Mark

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes
  2024-02-26 19:32 ` [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes Omar Sandoval
@ 2024-03-01 14:59   ` Mark Wielaard
  2024-03-01 16:11     ` Mark Wielaard
  2024-03-01 22:36     ` Omar Sandoval
  0 siblings, 2 replies; 11+ messages in thread
From: Mark Wielaard @ 2024-03-01 14:59 UTC (permalink / raw)
  To: Omar Sandoval, elfutils-devel

Hi Omar,

On Mon, 2024-02-26 at 11:32 -0800, Omar Sandoval wrote:
> Meta uses DWARF package files for our large, statically-linked C++
> applications.  Some of our largest applications have more than 4GB in
> .debug_info.dwo, but the section offsets in .debug_cu_index and
> .debug_tu_index are 32 bits; see the discussion here [1].  We
> implemented a workaround/extension for this in LLVM.  Implement the
> equivalent in libdw.
> 
> To test this, we need files with more than 4GB in .debug_info.dwo.  I
> created these artificially by editing GCC's assembly output.  They
> compress down to 6KB.  I test them from run-large-elf-file.sh to take
> advantage of the existing checks for large file support.
> 
> 1: https://discourse.llvm.org/t/dwarf-dwp-4gb-limit/63902.
> 
>  	* libdw/dwarf_end.c (dwarf_package_index_free): New function.
> 	* tests/testfile-dwp-4-cu-index-overflow.bz2: New test file.
> 	* tests/testfile-dwp-4-cu-index-overflow.dwp.bz2: New test file.
> 	* tests/testfile-dwp-5-cu-index-overflow.bz2: New test file.
> 	* tests/testfile-dwp-5-cu-index-overflow.dwp.bz2: New test file.
> 	* tests/testfile-dwp-cu-index-overflow.source: New file.
> 	* tests/run-large-elf-file.sh: Check
> 	testfile-dwp-5-cu-index-overflow and
> 	testfile-dwp-4-cu-index-overflow.

The hack is kind of horrible, but given that this doesn't really
impacts "normal" dwp files and it does work with clang/lldb, lets just
support it too.

> Signed-off-by: Omar Sandoval <osandov@fb.com>
> ---
>  libdw/dwarf_cu_dwp_section_info.c             | 147 ++++++++++++++-
>  libdw/dwarf_end.c                             |  15 +-
>  libdw/libdwP.h                                |   3 +
>  tests/Makefile.am                             |   7 +-
>  tests/run-large-elf-file.sh                   | 174 ++++++++++++++++++
>  tests/testfile-dwp-4-cu-index-overflow.bz2    | Bin 0 -> 4490 bytes
>  .../testfile-dwp-4-cu-index-overflow.dwp.bz2  | Bin 0 -> 5584 bytes
>  tests/testfile-dwp-5-cu-index-overflow.bz2    | Bin 0 -> 4544 bytes
>  .../testfile-dwp-5-cu-index-overflow.dwp.bz2  | Bin 0 -> 5790 bytes
>  tests/testfile-dwp-cu-index-overflow.source   |  86 +++++++++
>  10 files changed, 426 insertions(+), 6 deletions(-)
>  create mode 100755 tests/testfile-dwp-4-cu-index-overflow.bz2
>  create mode 100644 tests/testfile-dwp-4-cu-index-overflow.dwp.bz2
>  create mode 100755 tests/testfile-dwp-5-cu-index-overflow.bz2
>  create mode 100644 tests/testfile-dwp-5-cu-index-overflow.dwp.bz2
>  create mode 100644 tests/testfile-dwp-cu-index-overflow.source
> 
> diff --git a/libdw/dwarf_cu_dwp_section_info.c b/libdw/dwarf_cu_dwp_section_info.c
> index 298f36f9..3d11c87a 100644
> --- a/libdw/dwarf_cu_dwp_section_info.c
> +++ b/libdw/dwarf_cu_dwp_section_info.c
> @@ -30,6 +30,8 @@
>  # include <config.h>
>  #endif
>  
> +#include <assert.h>
> +
>  #include "libdwP.h"
>  
>  static Dwarf_Package_Index *
> @@ -110,7 +112,9 @@ __libdw_read_package_index (Dwarf *dbg, bool tu)
>  
>    index->dbg = dbg;
>    /* Set absent sections to UINT32_MAX.  */
> -  memset (index->sections, 0xff, sizeof (index->sections));
> +  for (size_t i = 0;
> +       i < sizeof (index->sections) / sizeof (index->sections[0]); i++)
> +    index->sections[i] = UINT32_MAX;
>    for (size_t i = 0; i < section_count; i++)
>      {
>        uint32_t section = read_4ubyte_unaligned (dbg, sections + i * 4);
> @@ -161,6 +165,7 @@ __libdw_read_package_index (Dwarf *dbg, bool tu)
>    index->indices = indices;
>    index->section_offsets = section_offsets;
>    index->section_sizes = section_sizes;
> +  index->debug_info_offsets = NULL;
>  
>    return index;
>  }
> @@ -177,6 +182,137 @@ __libdw_package_index (Dwarf *dbg, bool tu)
>    if (index == NULL)
>      return NULL;
>  
> +  /* Offsets in the section offset table are 32-bit unsigned integers.  In
> +     practice, the .debug_info.dwo section for very large executables can be
> +     larger than 4GB.  GNU dwp as of binutils 2.41 and llvm-dwp before LLVM 15
> +     both accidentally truncate offsets larger than 4GB.
> +
> +     LLVM 15 detects the overflow and errors out instead; see LLVM commit
> +     f8df8114715b ("[DWP][DWARF] Detect and error on debug info offset
> +     overflow").  However, lldb in LLVM 16 supports using dwp files with
> +     truncated offsets by recovering them directly from the unit headers in the
> +     .debug_info.dwo section; see LLVM commit c0db06227721 ("[DWARFLibrary] Add
> +     support to re-construct cu-index").  Since LLVM 17, the overflow error can
> +     be turned into a warning instead; see LLVM commit 53a483cee801 ("[DWP] add
> +     overflow check for llvm-dwp tools if offset overflow").
> +
> +     LLVM's support for > 4GB offsets is effectively an extension to the DWARF
> +     package file format, which we implement here.  The strategy is to walk the
> +     unit headers in .debug_info.dwo in lockstep with the DW_SECT_INFO columns
> +     in the section offset tables.  As long as they are in the same order
> +     (which they are in practice for both GNU dwp and llvm-dwp), we can
> +     correlate the truncated offset and produce a corrected array of offsets.
> +
> +     Note that this will be fixed properly in DWARF 6:
> +     https://dwarfstd.org/issues/220708.2.html.  */
> +  if (index->sections[DW_SECT_INFO - 1] != UINT32_MAX
> +      && dbg->sectiondata[IDX_debug_info]->d_size > UINT32_MAX)
> +    {
> +      Dwarf_Package_Index *cu_index, *tu_index = NULL;
> +      if (tu)
> +	{
> +	  tu_index = index;
> +	  assert (dbg->cu_index == NULL);
> +	  cu_index = __libdw_read_package_index (dbg, false);
> +	  if (cu_index == NULL)
> +	    {
> +	      free(index);
> +	      return NULL;
> +	    }
> +	}
> +      else
> +	{
> +	  cu_index = index;
> +	  if (dbg->sectiondata[IDX_debug_tu_index] != NULL
> +	      && dbg->sectiondata[IDX_debug_types] == NULL)
> +	    {
> +	      assert (dbg->tu_index == NULL);
> +	      tu_index = __libdw_read_package_index (dbg, true);
> +	      if (tu_index == NULL)
> +		{
> +		  free(index);
> +		  return NULL;
> +		}
> +	    }
> +	}
> +
> +      cu_index->debug_info_offsets = malloc (cu_index->unit_count
> +					     * sizeof (Dwarf_Off));
> +      if (cu_index->debug_info_offsets == NULL)
> +	{
> +	  free (tu_index);
> +	  free (cu_index);
> +	  __libdw_seterrno (DWARF_E_NOMEM);
> +	  return NULL;
> +	}
> +      if (tu_index != NULL)
> +	{
> +	  tu_index->debug_info_offsets = malloc (tu_index->unit_count
> +						 * sizeof (Dwarf_Off));
> +	  if (tu_index->debug_info_offsets == NULL)
> +	    {
> +	      free (tu_index);
> +	      free (cu_index->debug_info_offsets);
> +	      free (cu_index);
> +	      __libdw_seterrno (DWARF_E_NOMEM);
> +	      return NULL;
> +	    }
> +	}
> +
> +      Dwarf_Off off = 0;
> +      uint32_t cui = 0, tui = 0;
> +      uint32_t cu_count = cu_index->unit_count;
> +      const unsigned char *cu_offset
> +	= cu_index->section_offsets + cu_index->sections[DW_SECT_INFO - 1] * 4;
> +      uint32_t tu_count = 0;
> +      const unsigned char *tu_offset;
> +      if (tu_index != NULL)
> +	{
> +	  tu_count = tu_index->unit_count;
> +	  tu_offset = tu_index->section_offsets
> +		      + tu_index->sections[DW_SECT_INFO - 1] * 4;
> +	}
> +      while (cui < cu_count || tui < tu_count)
> +	{
> +	  Dwarf_Off next_off;
> +	  uint8_t unit_type;
> +	  if (__libdw_next_unit (dbg, false, off, &next_off, NULL, NULL,
> +				 &unit_type, NULL, NULL, NULL, NULL, NULL)
> +	      != 0)
> +	    {
> +	    not_sorted:
> +	      free (cu_index->debug_info_offsets);
> +	      cu_index->debug_info_offsets = NULL;
> +	      if (tu_index != NULL)
> +		{
> +		  free (tu_index->debug_info_offsets);
> +		  tu_index->debug_info_offsets = NULL;
> +		}
> +	      break;
> +	    }
> +	  if (unit_type != DW_UT_split_type && cui < cu_count)
> +	    {
> +	      if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, cu_offset))
> +		goto not_sorted;
> +	      cu_index->debug_info_offsets[cui++] = off;
> +	      cu_offset += cu_index->section_count * 4;
> +	    }
> +	  else if (unit_type == DW_UT_split_type && tui < tu_count)
> +	    {
> +	      if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, tu_offset))
> +		goto not_sorted;
> +	      tu_index->debug_info_offsets[tui++] = off;
> +	      tu_offset += tu_index->section_count * 4;
> +	    }
> +	  off = next_off;
> +	}
> +
> +      if (tu)
> +	dbg->cu_index = cu_index;
> +      else if (tu_index != NULL)
> +	dbg->tu_index = tu_index;
> +    }
> +
>    if (tu)
>      dbg->tu_index = index;
>    else

This looks correct, but gcc noticed a path to use tu_offset (and
tu_index) if they weren't initialized or NULL:

In file included from /home/mark/src/elfutils/libdw/libdwP.h:684,
                 from /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:35:
In function ‘read_4ubyte_unaligned_1’,
    inlined from ‘__libdw_package_index’ at /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:302:34:
/home/mark/src/elfutils/libdw/memory-access.h:291:12: error: ‘tu_offset’ may be used uninitialized [-Werror=maybe-uninitialized]
  291 |   return up->u4;
      |          ~~^~~~
/home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c: In function ‘__libdw_package_index’:
/home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:268:28: note: ‘tu_offset’ was declared here
  268 |       const unsigned char *tu_offset;
      |                            ^~~~~~~~~
cc1: all warnings being treated as errors

I couldn't immediately disprove gcc here, so I think it is a good idea
to add an explicit check for tu_index != NULL.

diff --git a/libdw/dwarf_cu_dwp_section_info.c b/libdw/dwarf_cu_dwp_section_info.c
index 3d11c87a..9fdc15bf 100644
--- a/libdw/dwarf_cu_dwp_section_info.c
+++ b/libdw/dwarf_cu_dwp_section_info.c
@@ -297,7 +297,8 @@ __libdw_package_index (Dwarf *dbg, bool tu)
              cu_index->debug_info_offsets[cui++] = off;
              cu_offset += cu_index->section_count * 4;
            }
-         else if (unit_type == DW_UT_split_type && tui < tu_count)
+         else if (unit_type == DW_UT_split_type && tu_index != NULL
+                  && tui < tu_count)
            {
              if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, tu_offset))
                goto not_sorted;

Which makes gcc happy again.

> @@ -244,8 +380,13 @@ __libdw_dwp_section_info (Dwarf_Package_Index *index, uint32_t unit_row,
>    size_t i = (size_t)(unit_row - 1) * index->section_count
>  	     + index->sections[section - 1];
>    if (offsetp != NULL)
> -    *offsetp = read_4ubyte_unaligned (index->dbg,
> -				      index->section_offsets + i * 4);
> +    {
> +      if (section == DW_SECT_INFO && index->debug_info_offsets != NULL)
> +	*offsetp = index->debug_info_offsets[unit_row - 1];
> +      else
> +	*offsetp = read_4ubyte_unaligned (index->dbg,
> +					  index->section_offsets + i * 4);
> +    }
>    if (sizep != NULL)
>      *sizep = read_4ubyte_unaligned (index->dbg,
>  				    index->section_sizes + i * 4);

OK.

> diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
> index 78224ddb..ed8d27be 100644
> --- a/libdw/dwarf_end.c
> +++ b/libdw/dwarf_end.c
> @@ -40,6 +40,17 @@
>  #include "cfi.h"
>  
>  
> +static void
> +dwarf_package_index_free (Dwarf_Package_Index *index)
> +{
> +  if (index != NULL)
> +    {
> +      free (index->debug_info_offsets);
> +      free (index);
> +    }
> +}
> +
> +
>  static void
>  noop_free (void *arg __attribute__ ((unused)))
>  {
> @@ -79,8 +90,8 @@ dwarf_end (Dwarf *dwarf)
>  {
>    if (dwarf != NULL)
>      {
> -      free (dwarf->tu_index);
> -      free (dwarf->cu_index);
> +      dwarf_package_index_free (dwarf->tu_index);
> +      dwarf_package_index_free (dwarf->cu_index);
>  
>        if (dwarf->cfi != NULL)
>  	/* Clean up the CFI cache.  */

OK.

> diff --git a/libdw/libdwP.h b/libdw/libdwP.h
> index 1a0a4df3..6018399c 100644
> --- a/libdw/libdwP.h
> +++ b/libdw/libdwP.h
> @@ -371,6 +371,9 @@ typedef struct Dwarf_Package_Index_s
>    const unsigned char *indices;
>    const unsigned char *section_offsets;
>    const unsigned char *section_sizes;
> +  /* If DW_SECT_INFO section offsets were truncated to 32 bits, recovered
> +     64-bit offsets.  */
> +  Dwarf_Off *debug_info_offsets;
>  } Dwarf_Package_Index;
>  
>  /* CU representation.  */

OK.

> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 3f80c451..98131a6b 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -641,7 +641,12 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
>  	     testfile-dwp-4.bz2 testfile-dwp-4.dwp.bz2 \
>  	     testfile-dwp-4-strict.bz2 testfile-dwp-4-strict.dwp.bz2 \
>  	     testfile-dwp-5.bz2 testfile-dwp-5.dwp.bz2 testfile-dwp.source \
> -	     run-cu-dwp-section-info.sh run-declfiles.sh
> +	     run-cu-dwp-section-info.sh run-declfiles.sh \
> +	     testfile-dwp-5-cu-index-overflow \
> +	     testfile-dwp-5-cu-index-overflow.dwp \
> +	     testfile-dwp-4-cu-index-overflow \
> +	     testfile-dwp-4-cu-index-overflow.dwp \
> +	     testfile-dwp-cu-index-overflow.source
>  
>  
>  if USE_VALGRIND

You mean the .bz2 files here. Fixed.

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 98131a6b..9141074f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -642,10 +642,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             testfile-dwp-4-strict.bz2 testfile-dwp-4-strict.dwp.bz2 \
             testfile-dwp-5.bz2 testfile-dwp-5.dwp.bz2 testfile-dwp.source \
             run-cu-dwp-section-info.sh run-declfiles.sh \
-            testfile-dwp-5-cu-index-overflow \
-            testfile-dwp-5-cu-index-overflow.dwp \
-            testfile-dwp-4-cu-index-overflow \
-            testfile-dwp-4-cu-index-overflow.dwp \
+            testfile-dwp-5-cu-index-overflow.bz2 \
+            testfile-dwp-5-cu-index-overflow.dwp.bz2 \
+            testfile-dwp-4-cu-index-overflow.bz2 \
+            testfile-dwp-4-cu-index-overflow.dwp.bz2 \
             testfile-dwp-cu-index-overflow.source
 
 
Thanks for the new tests.

Pushed with the fixlets above.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes
  2024-03-01 14:59   ` Mark Wielaard
@ 2024-03-01 16:11     ` Mark Wielaard
  2024-03-01 22:36     ` Omar Sandoval
  1 sibling, 0 replies; 11+ messages in thread
From: Mark Wielaard @ 2024-03-01 16:11 UTC (permalink / raw)
  To: Omar Sandoval, elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 2021 bytes --]

Hi,

On Fri, 2024-03-01 at 15:59 +0100, Mark Wielaard wrote:
> This looks correct, but gcc noticed a path to use tu_offset (and
> tu_index) if they weren't initialized or NULL:
> 
> In file included from /home/mark/src/elfutils/libdw/libdwP.h:684,
>                  from /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:35:
> In function ‘read_4ubyte_unaligned_1’,
>     inlined from ‘__libdw_package_index’ at /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:302:34:
> /home/mark/src/elfutils/libdw/memory-access.h:291:12: error: ‘tu_offset’ may be used uninitialized [-Werror=maybe-uninitialized]
>   291 |   return up->u4;
>       |          ~~^~~~
> /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c: In function ‘__libdw_package_index’:
> /home/mark/src/elfutils/libdw/dwarf_cu_dwp_section_info.c:268:28: note: ‘tu_offset’ was declared here
>   268 |       const unsigned char *tu_offset;
>       |                            ^~~~~~~~~
> cc1: all warnings being treated as errors
> 
> I couldn't immediately disprove gcc here, so I think it is a good idea
> to add an explicit check for tu_index != NULL.
> 
> diff --git a/libdw/dwarf_cu_dwp_section_info.c b/libdw/dwarf_cu_dwp_section_info.c
> index 3d11c87a..9fdc15bf 100644
> --- a/libdw/dwarf_cu_dwp_section_info.c
> +++ b/libdw/dwarf_cu_dwp_section_info.c
> @@ -297,7 +297,8 @@ __libdw_package_index (Dwarf *dbg, bool tu)
>               cu_index->debug_info_offsets[cui++] = off;
>               cu_offset += cu_index->section_count * 4;
>             }
> -         else if (unit_type == DW_UT_split_type && tui < tu_count)
> +         else if (unit_type == DW_UT_split_type && tu_index != NULL
> +                  && tui < tu_count)
>             {
>               if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, tu_offset))
>                 goto not_sorted;
> 
> Which makes gcc happy again.

But not all gcc versions apparently. So I added the following on top.

[-- Attachment #2: Type: text/x-patch, Size: 1839 bytes --]

From cc6e53b9f305148bda275ade40c0e625d98da2f2 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Fri, 1 Mar 2024 17:05:16 +0100
Subject: [PATCH] libdw: Initialize tu_offset in __libdw_package_index
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

dwarf_cu_dwp_section_info.c: In function ‘__libdw_package_index’:
dwarf_cu_dwp_section_info.c:306:25: error: ‘tu_offset’ may be used uninitialized [-Werror=maybe-uninitialized]
  306 |               tu_offset += tu_index->section_count * 4;
      |               ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dwarf_cu_dwp_section_info.c:268:28: note: ‘tu_offset’ was declared here
  268 |       const unsigned char *tu_offset;
      |                            ^~~~~~~~~

Which is the same issue we thought to have fixed by checking for
tu_index != NULL but not all gcc versions seem able to see that.
So just explicitly initialize tu_offset to NULL. We keep the older
check, so the NULL pointer should never be used.

       * libdw/dwarf_cu_dwp_section_info.c (__libdw_package_index):
       Initialize tu_offset.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/dwarf_cu_dwp_section_info.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libdw/dwarf_cu_dwp_section_info.c b/libdw/dwarf_cu_dwp_section_info.c
index 9fdc15bf..5a081f5a 100644
--- a/libdw/dwarf_cu_dwp_section_info.c
+++ b/libdw/dwarf_cu_dwp_section_info.c
@@ -265,7 +265,7 @@ __libdw_package_index (Dwarf *dbg, bool tu)
       const unsigned char *cu_offset
 	= cu_index->section_offsets + cu_index->sections[DW_SECT_INFO - 1] * 4;
       uint32_t tu_count = 0;
-      const unsigned char *tu_offset;
+      const unsigned char *tu_offset = NULL;
       if (tu_index != NULL)
 	{
 	  tu_count = tu_index->unit_count;
-- 
2.43.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes
  2024-03-01 14:59   ` Mark Wielaard
  2024-03-01 16:11     ` Mark Wielaard
@ 2024-03-01 22:36     ` Omar Sandoval
  1 sibling, 0 replies; 11+ messages in thread
From: Omar Sandoval @ 2024-03-01 22:36 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

On Fri, Mar 01, 2024 at 03:59:22PM +0100, Mark Wielaard wrote:
> Hi Omar,
> 
> On Mon, 2024-02-26 at 11:32 -0800, Omar Sandoval wrote:
> > Meta uses DWARF package files for our large, statically-linked C++
> > applications.  Some of our largest applications have more than 4GB in
> > .debug_info.dwo, but the section offsets in .debug_cu_index and
> > .debug_tu_index are 32 bits; see the discussion here [1].  We
> > implemented a workaround/extension for this in LLVM.  Implement the
> > equivalent in libdw.
> > 
> > To test this, we need files with more than 4GB in .debug_info.dwo.  I
> > created these artificially by editing GCC's assembly output.  They
> > compress down to 6KB.  I test them from run-large-elf-file.sh to take
> > advantage of the existing checks for large file support.
> > 
> > 1: https://discourse.llvm.org/t/dwarf-dwp-4gb-limit/63902.
> > 
> >  	* libdw/dwarf_end.c (dwarf_package_index_free): New function.
> > 	* tests/testfile-dwp-4-cu-index-overflow.bz2: New test file.
> > 	* tests/testfile-dwp-4-cu-index-overflow.dwp.bz2: New test file.
> > 	* tests/testfile-dwp-5-cu-index-overflow.bz2: New test file.
> > 	* tests/testfile-dwp-5-cu-index-overflow.dwp.bz2: New test file.
> > 	* tests/testfile-dwp-cu-index-overflow.source: New file.
> > 	* tests/run-large-elf-file.sh: Check
> > 	testfile-dwp-5-cu-index-overflow and
> > 	testfile-dwp-4-cu-index-overflow.
> 
> The hack is kind of horrible, but given that this doesn't really
> impacts "normal" dwp files and it does work with clang/lldb, lets just
> support it too.

Yup, I hate it, too. Thanks for merging this series and for the followup
fixes!

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-03-01 22:36 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-26 19:32 [PATCH v3 0/4] elfutils: DWARF package (.dwp) file support Omar Sandoval
2024-02-26 19:32 ` [PATCH v3 1/4] libdw: Handle split DWARF in dwarf_decl_file Omar Sandoval
2024-02-29 22:08   ` Mark Wielaard
2024-02-26 19:32 ` [PATCH v3 2/4] libdw: Refactor dwarf_next_lines and fix skipped CU Omar Sandoval
2024-02-29 22:59   ` Mark Wielaard
2024-02-26 19:32 ` [PATCH v3 3/4] libdw: Apply DWARF package file section offsets where appropriate Omar Sandoval
2024-02-29 23:49   ` Mark Wielaard
2024-02-26 19:32 ` [PATCH v3 4/4] libdw: Handle overflowed DW_SECT_INFO offsets in DWARF package file indexes Omar Sandoval
2024-03-01 14:59   ` Mark Wielaard
2024-03-01 16:11     ` Mark Wielaard
2024-03-01 22:36     ` Omar Sandoval

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).