Signed-off-by: Florian Weimer <[email protected]>
---
 libdw/ChangeLog         |  8 ++++++++
 libdw/Makefile.am       |  2 +-
 libdw/dwarf_begin_elf.c | 10 +++++-----
 libdw/dwarf_end.c       |  3 +--
 libdw/dwarf_set_alt.c   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 libdw/libdw.h           |  7 +++++++
 libdw/libdw.map         |  1 +
 libdw/libdwP.h          |  1 +
 8 files changed, 68 insertions(+), 8 deletions(-)
 create mode 100644 libdw/dwarf_set_alt.c

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 581fc52..798e2ba 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -10,6 +10,14 @@
        element.
        (check_section): Call open_debugaltlink.
 
+       * libdw.h (dwarf_set_alt): New function.
+       * libdwP.h (dwarf_set_alt): Internal declaration.
+       * Makefile.am (libdw_a_SOURCES): Add dwarf_set_alt.c.
+       * libdw.map (ELFUTILS_0.159): Export dwarf_set_alt.
+       * dwarf_set_alt.c: New file.
+       * dwarf_begin_elf.c (try_debugaltlink): Call dwarf_set_alt.
+       * dwarf_end.c (dwarf_end): Likewise.
+
 2014-03-03  Jan Kratochvil  <[email protected]>
 
        Fix abort() on missing section headers.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index c40410d..cffaeca 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -88,7 +88,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c 
dwarf_getelf.c \
                  dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \
                  dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \
                  dwarf_getlocation_die.c dwarf_getlocation_attr.c \
-                 dwarf_debugaltlink.c
+                 dwarf_debugaltlink.c dwarf_set_alt.c
 
 if MAINTAINER_MODE
 BUILT_SOURCES = $(srcdir)/known-dwarf.h
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index a2bf245..e530a88 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -119,15 +119,15 @@ try_debugaltlink (Dwarf *result, const char *try_name,
   int fd = open (try_name, O_RDONLY);
   if (fd > 0)
     {
-      result->alt_dwarf = INTUSE (dwarf_begin) (fd, DWARF_C_READ);
-      if (result->alt_dwarf != NULL)
+      Dwarf *alt_dwarf = INTUSE (dwarf_begin) (fd, DWARF_C_READ);
+      if (alt_dwarf != NULL)
        {
-         Elf *elf = result->alt_dwarf->elf;
-         if (__check_build_id (result->alt_dwarf, build_id, id_len) == 0
+         Elf *elf = alt_dwarf->elf;
+         if (__check_build_id (alt_dwarf, build_id, id_len) == 0
              && elf_cntl (elf, ELF_C_FDREAD) == 0)
            {
              close (fd);
-             result->free_alt = 1;
+             INTUSE (dwarf_set_alt) (result, alt_dwarf, true);
              return result;
            }
          INTUSE (dwarf_end) (result->alt_dwarf);
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index e65314a..d0b0332 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -112,8 +112,7 @@ dwarf_end (dwarf)
        elf_end (dwarf->elf);
 
       /* Free the alternative Dwarf descriptor if necessary.  */
-      if (dwarf->free_alt)
-       INTUSE (dwarf_end) (dwarf->alt_dwarf);
+      INTUSE (dwarf_set_alt) (dwarf, NULL, false);
 
       /* Free the context descriptor.  */
       free (dwarf);
diff --git a/libdw/dwarf_set_alt.c b/libdw/dwarf_set_alt.c
new file mode 100644
index 0000000..29422b1
--- /dev/null
+++ b/libdw/dwarf_set_alt.c
@@ -0,0 +1,44 @@
+/* Create descriptor from ELF descriptor for processing file.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+void
+dwarf_set_alt (Dwarf *dwarf, Dwarf *alt, bool free_alt)
+{
+  if (dwarf->free_alt)
+    INTUSE (dwarf_end) (dwarf->alt_dwarf);
+  dwarf->free_alt = free_alt;
+  dwarf->alt_dwarf = alt;
+}
+
+INTDEF (dwarf_set_alt)
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 2682989..1880c9a 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -273,6 +273,13 @@ extern int dwarf_debugaltlink (Dwarf *dwarf,
                               const void **build_id,
                               size_t *build_id_len);
 
+/* Provides the data referenced by the .gnu_debugaltlink section.  It
+   is the responsibility of the caller not ensure that the data
+   referenced by ALT stays valid as long as MAIN is used.  If
+   ALT_FREE, ALT will automatically be deallocated by the next call to
+   dwarf_set_alt or dwarf_end on MAIN.  */
+extern void dwarf_set_alt (Dwarf *main, Dwarf *alt, bool alt_free);
+
 /* Read the header for the DWARF CU.  */
 extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
                         size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 92605d0..388e941 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -296,4 +296,5 @@ ELFUTILS_0.158 {
 ELFUTILS_0.159 {
   global:
     dwarf_debugaltlink;
+    dwarf_set_alt;
 } ELFUTILS_0.158;
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 28d6260..db71466 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -702,6 +702,7 @@ INTDECL (dwarf_nextcu)
 INTDECL (dwarf_next_unit)
 INTDECL (dwarf_offdie)
 INTDECL (dwarf_ranges)
+INTDECL (dwarf_set_alt)
 INTDECL (dwarf_siblingof)
 INTDECL (dwarf_srclang)
 INTDECL (dwarf_tag)
-- 
1.9.0

Reply via email to