dwarf_ranges: do not request base address attributes if not necessary

- Instead of bailing out at iteration start, we remember the
  base-address-selecting attributes were not seen, and then bail out
  later if no base address selection entry has been seen.

Signed-off-by: Petr Machata <pmachata@redhat.com>
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 97c7ab8..5091a9b 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2015-02-11  Petr Machata  <pmachata@redhat.com>
+
+	* run-dwarf-ranges.sh: New test.
+	* dwarf-ranges.c: New file.
+	* debug-ranges-no-lowpc.s, debug-ranges-no-lowpc.o.bz2: New test case.
+
 2015-01-21  Mark Wielaard  <mjw@redhat.com>
 
 	* Makefile.am (check_PROGRAMS): Add elfstrtab.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5ba8cdd..b03f62e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -44,7 +44,7 @@
 		  find-prologues funcretval allregs rdwrmmap \
 		  dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \
 		  dwfl-addr-sect dwfl-bug-report early-offscn \
-		  dwfl-bug-getmodules dwarf-getmacros addrcfi \
+		  dwfl-bug-getmodules dwarf-getmacros dwarf-ranges addrcfi \
 		  test-flag-nobits dwarf-getstring rerequest_tag \
 		  alldts md5-sha1-test typeiter typeiter2 low_high_pc \
 		  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
@@ -94,7 +94,7 @@
 	dwfl-bug-fd-leak dwfl-bug-report \
 	run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \
 	run-disasm-x86.sh run-disasm-x86-64.sh \
-	run-early-offscn.sh run-dwarf-getmacros.sh \
+	run-early-offscn.sh run-dwarf-getmacros.sh run-dwarf-ranges.sh \
 	run-test-flag-nobits.sh run-prelink-addr-test.sh \
 	run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \
 	run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \
@@ -394,6 +394,7 @@
 dwfl_bug_getmodules_LDADD = $(libdw) $(libebl) $(libelf) -ldl
 dwfl_addr_sect_LDADD = $(libdw) $(libebl) $(libelf) -ldl
 dwarf_getmacros_LDADD = $(libdw)
+dwarf_ranges_LDADD = $(libdw)
 dwarf_getstring_LDADD = $(libdw)
 addrcfi_LDADD = $(libdw) $(libebl) $(libelf) -ldl
 test_flag_nobits_LDADD = $(libelf)
diff --git a/tests/debug-ranges-no-lowpc.o.bz2 b/tests/debug-ranges-no-lowpc.o.bz2
new file mode 100644
index 0000000..871a3fb
--- /dev/null
+++ b/tests/debug-ranges-no-lowpc.o.bz2
Binary files differ
diff --git a/tests/debug-ranges-no-lowpc.s b/tests/debug-ranges-no-lowpc.s
new file mode 100644
index 0000000..879bce2
--- /dev/null
+++ b/tests/debug-ranges-no-lowpc.s
@@ -0,0 +1,49 @@
+        .section .debug_info
+.Lcu1_begin:
+        .4byte        .Lcu1_end - .Lcu1_start
+.Lcu1_start:
+        .2byte        3                 /* Version */
+        .4byte        .Labbrev1_begin   /* Abbrevs */
+        .byte        8                  /* Pointer size */
+        .uleb128        2               /* Abbrev (DW_TAG_compile_unit) */
+        .4byte        0
+.Lcu1_end:
+        .section .note.gnu.build-id, "a", %note
+        .4byte        4
+        .4byte        8
+        .4byte        3
+        .ascii        "GNU\0"
+        .byte        0x01
+        .byte        0x02
+        .byte        0x03
+        .byte        0x04
+        .byte        0x05
+        .byte        0x06
+        .byte        0x07
+        .byte        0x08
+        .section .debug_abbrev
+.Labbrev1_begin:
+        .uleb128        2               /* Abbrev start */
+        .uleb128        0x11            /* DW_TAG_compile_unit */
+        .byte        0                  /* has_children */
+        .uleb128        0x55            /* DW_AT_ranges */
+        .uleb128        0x06            /* DW_FORM_data4 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+
+	.section .debug_ranges
+
+	.8byte 0xffffffffffffffff
+	.8byte 0
+
+	.8byte 1
+	.8byte 2
+
+	.8byte 3
+	.8byte 4
+
+	.8byte 0
+	.8byte 0
+
diff --git a/tests/dwarf-ranges.c b/tests/dwarf-ranges.c
new file mode 100644
index 0000000..4bcf96c
--- /dev/null
+++ b/tests/dwarf-ranges.c
@@ -0,0 +1,57 @@
+/* Test program for dwarf_ranges
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include ELFUTILS_HEADER(dw)
+#include <dwarf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+
+int
+main (int argc, char *argv[])
+{
+  assert (argc >= 3);
+  const char *name = argv[1];
+  ptrdiff_t cuoff = strtol (argv[2], NULL, 0);
+
+  int fd = open (name, O_RDONLY);
+  Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+
+  Dwarf_Die cudie_mem, *cudie = dwarf_offdie (dbg, cuoff, &cudie_mem);
+
+  Dwarf_Addr base, start, end;
+  for (ptrdiff_t off = 0;
+       (off = dwarf_ranges (cudie, off, &base, &start, &end)); )
+    if (off == -1)
+      {
+	puts (dwarf_errmsg (dwarf_errno ()));
+	break;
+      }
+    else
+      fprintf (stderr, "%"PRIx64"..%"PRIx64" (base %"PRIx64")\n",
+	       start, end, base);
+
+  dwarf_end (dbg);
+
+  return 0;
+}
diff --git a/tests/run-dwarf-ranges.sh b/tests/run-dwarf-ranges.sh
new file mode 100755
index 0000000..d202ed3
--- /dev/null
+++ b/tests/run-dwarf-ranges.sh
@@ -0,0 +1,27 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles debug-ranges-no-lowpc.o
+
+testrun_compare ${abs_builddir}/dwarf-ranges debug-ranges-no-lowpc.o 0xb <<\EOF
+1..2 (base 0)
+3..4 (base 0)
+EOF
+
+exit 0