From 5660f170b2194b35e0ed0040908d775a53553a2b Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Mon, 25 Jun 2012 17:18:53 +0200
Subject: [PATCH] Add low-level support for .debug_macro.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 libdw/ChangeLog            |    7 +++++
 libdw/dwarf.h              |    5 ++++
 libdw/dwarf_begin_elf.c    |    1 +
 libdw/dwarf_formudata.c    |   10 +++++++-
 libdw/libdwP.h             |    1 +
 libebl/ChangeLog           |    4 +++
 libebl/eblopenbackend.c    |    2 +
 src/ChangeLog              |    4 +++
 src/readelf.c              |    4 +++
 tests/ChangeLog            |    6 +++++
 tests/Makefile.am          |    6 +++-
 tests/run-macro-test.sh    |   53 ++++++++++++++++++++++++++++++++++++++++++++
 tests/testfile-macinfo.bz2 |  Bin 0 -> 6689 bytes
 tests/testfile-macros.bz2  |  Bin 0 -> 7882 bytes
 14 files changed, 100 insertions(+), 3 deletions(-)
 create mode 100755 tests/run-macro-test.sh
 create mode 100755 tests/testfile-macinfo.bz2
 create mode 100755 tests/testfile-macros.bz2

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 3ff83e4..48bbaa0 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h: Add IDX_debug_macro.
+	* dwarf.h: Add DW_AT_GNU_macros.
+	* dwarf_begin_elf.c (dwarf_scnnames): Add .debug_macro.
+	* dwarf_formudata.c (dwarf_formudata): Recognize DW_AT_GNU_macros.
+
 2012-04-27  Mark Wielaard  <mjw@redhat.com>
 
 	* libdw/dwarf_highpc.c (dwarf_highpc): Handle DW_AT_high_pc being
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 38f663d..41a1024 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -267,6 +267,11 @@ enum
     DW_AT_GNU_all_call_sites = 0x2117,
     DW_AT_GNU_all_source_call_sites = 0x2118,
 
+    /* More compact macro information - .debug_macro section
+       http://www.dwarfstd.org/ShowIssue.php?issue=110722.1
+       offset into .debug_macro section. */
+    DW_AT_GNU_macros = 0x2119,
+
     DW_AT_hi_user = 0x3fff
   };
 
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index fc6ac8d..3e01800 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -61,6 +61,7 @@ static const char dwarf_scnnames[IDX_last][17] =
   [IDX_debug_pubnames] = ".debug_pubnames",
   [IDX_debug_str] = ".debug_str",
   [IDX_debug_macinfo] = ".debug_macinfo",
+  [IDX_debug_macro] = ".debug_macro",
   [IDX_debug_ranges] = ".debug_ranges"
 };
 #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index f5b2a1a..f08e0d8 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -140,13 +140,21 @@ dwarf_formudata (attr, return_uval)
 	      break;
 
 	    case DW_AT_macro_info:
-	      /* macptr */
+	      /* macptr into .debug_macinfo */
 	      if (__libdw_formptr (attr, IDX_debug_macinfo,
 				   DWARF_E_NO_ENTRY, NULL,
 				   return_uval) == NULL)
 		return -1;
 	      break;
 
+	    case DW_AT_GNU_macros:
+	      /* macptr into .debug_macro */
+	      if (__libdw_formptr (attr, IDX_debug_macro,
+				   DWARF_E_NO_ENTRY, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
 	    case DW_AT_ranges:
 	    case DW_AT_start_scope:
 	      /* rangelistptr */
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 3c1925b..77e1b31 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -71,6 +71,7 @@ enum
     IDX_debug_pubnames,
     IDX_debug_str,
     IDX_debug_macinfo,
+    IDX_debug_macro,
     IDX_debug_ranges,
     IDX_last
   };
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index ac2160d..941ed6f 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,7 @@
+2011-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* eblopenbackend.c (default_debugscn_p): Add .debug_macro.
+
 2011-04-26  Mark Wielaard  <mjw@redhat.com>
 
 	* libebl.h (ebl_object_note_type_name): Add const char *name arg.
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 9789ef3..b39ab2e 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -646,6 +646,8 @@ default_debugscn_p (const char *name)
       ".debug_types",
       /* GDB DWARF 4 extension */
       ".gdb_index",
+      /* GNU/DWARF 5 extension/proposal */
+      ".debug_macro",
       /* SGI/MIPS DWARF 2 extensions */
       ".debug_weaknames",
       ".debug_funcnames",
diff --git a/src/ChangeLog b/src/ChangeLog
index 40905b8..2928ab1 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_attr_string): Add DW_AT_GNU_macros.
+
 2012-06-22  Mark Wielaard  <mjw@redhat.com>
 
 	* readelf.c (print_ops): Cast printf PRIu/x64 arguments to uint64_t
diff --git a/src/readelf.c b/src/readelf.c
index d182ab5..eb1d469 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3590,6 +3590,10 @@ dwarf_attr_string (unsigned int attrnum)
 	result = "GNU_all_source_call_sites";
 	break;
 
+      case DW_AT_GNU_macros:
+	result = "GNU_macros";
+	break;
+
       default:
 	if (attrnum < DW_AT_lo_user)
 	  snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"),
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 6f5e458..9b64917 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* run-macro-test.sh: New test.
+	* testfile-macinfo.bz2: New testfile.
+	* testfile-macros.bz2: Likewise.
+
 2012-05-07  Mark Wielaard  <mjw@redhat.com>
 
 	* low_high_pc.c: Use proper inttypes in printf formats.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ced7831..39e58ae 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -79,7 +79,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
 	run-early-offscn.sh run-dwarf-getmacros.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-unstrip-n.sh run-low_high_pc.sh
+	run-readelf-d.sh run-unstrip-n.sh run-low_high_pc.sh \
+	run-macro-test.sh
 
 if !STANDALONE
 noinst_PROGRAMS += msg_tst md5-sha1-test
@@ -157,7 +158,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     run-typeiter.sh testfile59.bz2 \
 	     run-readelf-d.sh testlib_dynseg.so.bz2 \
 	     run-unstrip-n.sh testcore-rtlib.bz2 \
-	     run-low_high_pc.sh testfile_low_high_pc.bz2
+	     run-low_high_pc.sh testfile_low_high_pc.bz2 \
+	     run-macro-test.sh testfile-macinfo.bz2 testfile-macros.bz2
 
 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
 			      bindir=$(DESTDIR)$(bindir) \
diff --git a/tests/run-macro-test.sh b/tests/run-macro-test.sh
new file mode 100755
index 0000000..70a16ed
--- /dev/null
+++ b/tests/run-macro-test.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+# Copyright (C) 2012 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
+
+# #include <string.h>
+#
+# #define HELLO "world"
+#
+# int
+# main(int argc, char ** argv)
+# {
+#   return strlen (HELLO);
+# }
+#
+# gcc -gdwarf-4 -g3 -o testfile-macros macro.c
+# gcc -gstrict-dwarf -gdwarf-4 -g3 -o testfile-macinfo macro.c
+
+testfiles testfile-macinfo testfile-macros
+
+status=0
+
+testrun ../src/readelf --debug-dump=info testfile-macinfo \
+	| grep macro_info > readelf.macros.out ||
+  { echo "*** failure readelf --debug-dump=info testfile-macinfo"; status=1; }
+testrun_compare cat readelf.macros.out <<\EOF
+           macro_info           (sec_offset) 0
+EOF
+
+testrun ../src/readelf --debug-dump=info testfile-macros \
+	| grep GNU_macros > readelf.macros.out ||
+  { echo "*** failure readelf --debug-dump=info testfile-macros"; status=1; }
+testrun_compare cat readelf.macros.out <<\EOF
+           GNU_macros           (sec_offset) 0
+EOF
+
+rm -f readelf.macros.out
+
+exit $status
diff --git a/tests/testfile-macinfo.bz2 b/tests/testfile-macinfo.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..e6cc5f1c246de436dce5b8df176963887d27f7f7
GIT binary patch
diff --git a/tests/testfile-macros.bz2 b/tests/testfile-macros.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..d74df94c62c8f29a046ebea0aae8e2e3e9454f5a
GIT binary patch
-- 
1.7.7.6

