3.21.0-10 lazy debuginfo loading
- Add valgrind-3.21.0-lazy-debuginfo.patch - Add valgrind-3.21.0-cleanup-read_elf_object.patch
This commit is contained in:
parent
d20757b5fd
commit
35cf45d805
58
valgrind-3.21.0-cleanup-read_elf_object.patch
Normal file
58
valgrind-3.21.0-cleanup-read_elf_object.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From a0d555a0dfe078ef04ea49d991a8090ab14bd4a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Floyd <pjfloyd@wanadoo.fr>
|
||||||
|
Date: Sat, 19 Aug 2023 21:37:33 +0200
|
||||||
|
Subject: [PATCH] Always cleanup on exit from ML_(read_elf_object)
|
||||||
|
|
||||||
|
I'm still a but baffled as to why this wasn't seen earlier.
|
||||||
|
A FreeBSD testcase started failing with kernel 13.2 patch 2,
|
||||||
|
which is quite a minor change. The testcase gets an fd from
|
||||||
|
pdfork and the parent does a printf with the fd then zaps the
|
||||||
|
process with pdkill. Standalone the fd is 3, and that's what
|
||||||
|
the expected contains. However, when it started failing I saw
|
||||||
|
with lsof that fds 3 and 4 were associated with the guest exe
|
||||||
|
and ld-elf.so.1.
|
||||||
|
---
|
||||||
|
coregrind/m_debuginfo/readelf.c | 16 +++++++---------
|
||||||
|
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
|
||||||
|
index f99d3dfd2..ac72f98fb 100644
|
||||||
|
--- a/coregrind/m_debuginfo/readelf.c
|
||||||
|
+++ b/coregrind/m_debuginfo/readelf.c
|
||||||
|
@@ -1916,6 +1916,7 @@ Bool ML_(read_elf_object) ( struct _DebugInfo* di )
|
||||||
|
Word i, j;
|
||||||
|
Bool dynbss_present = False;
|
||||||
|
Bool sdynbss_present = False;
|
||||||
|
+ Bool retval = False;
|
||||||
|
|
||||||
|
/* Image for the main ELF file we're working with. */
|
||||||
|
DiImage* mimg = NULL;
|
||||||
|
@@ -2944,19 +2945,16 @@ Bool ML_(read_elf_object) ( struct _DebugInfo* di )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- return True;
|
||||||
|
+ retval = True;
|
||||||
|
|
||||||
|
- out:
|
||||||
|
- {
|
||||||
|
- /* Last, but not least, detach from the image. */
|
||||||
|
- if (mimg) ML_(img_done)(mimg);
|
||||||
|
+ out:
|
||||||
|
|
||||||
|
- if (svma_ranges) VG_(deleteXA)(svma_ranges);
|
||||||
|
+ /* Last, but not least, detach from the image. */
|
||||||
|
+ if (mimg) ML_(img_done)(mimg);
|
||||||
|
|
||||||
|
- return False;
|
||||||
|
- } /* out: */
|
||||||
|
+ if (svma_ranges) VG_(deleteXA)(svma_ranges);
|
||||||
|
|
||||||
|
- /* NOTREACHED */
|
||||||
|
+ return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool ML_(read_elf_debug) ( struct _DebugInfo* di )
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
850
valgrind-3.21.0-lazy-debuginfo.patch
Normal file
850
valgrind-3.21.0-lazy-debuginfo.patch
Normal file
@ -0,0 +1,850 @@
|
|||||||
|
From 60f7e89ba32b54d73b9e36d49e28d0f559ade0b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aaron Merey <amerey@redhat.com>
|
||||||
|
Date: Fri, 30 Jun 2023 18:31:42 -0400
|
||||||
|
Subject: [PATCH] Support lazy reading and downloading of DWARF debuginfo
|
||||||
|
|
||||||
|
Currently valgrind attempts to read DWARF .debug_* sections as well
|
||||||
|
as separate debuginfo files for ELF binaries as soon as a shared library
|
||||||
|
is loaded. This might also result in the downloading of separate debuginfo
|
||||||
|
files via debuginfod.
|
||||||
|
|
||||||
|
This is inefficient when some of this debuginfo never ends up being used
|
||||||
|
by valgrind while running the client process.
|
||||||
|
|
||||||
|
This patch adds support for lazy reading and downloading of DWARF
|
||||||
|
debuginfo. When an ELF shared library is loaded, the reading of .debug_*
|
||||||
|
sections as well as separate or alternate debuginfo is deferred until
|
||||||
|
valgrind handles an instruction pointer corresponding to a text segment
|
||||||
|
of the shared library. At this point the deferred sections and separate
|
||||||
|
debug files are loaded.
|
||||||
|
|
||||||
|
This feature is only supported on ELF platforms.
|
||||||
|
|
||||||
|
https://bugs.kde.org/show_bug.cgi?id=471807
|
||||||
|
|
||||||
|
ChangeLog
|
||||||
|
* debuginfo.c (di_notify_ACHIEVE_ACCEPT_STATE): Replace
|
||||||
|
read_elf_debug_info with read_elf_object.
|
||||||
|
(addr_load_di): New function. Attempts to load deferred debuginfo
|
||||||
|
associated with a given address.
|
||||||
|
(load_di): New function. Attempts to load a given deferred
|
||||||
|
debuginfo associated with a given address.
|
||||||
|
(describe_IP): Add calls to load_di and addr_load_di.
|
||||||
|
(find_DiCfSI): Add call to load_di.
|
||||||
|
|
||||||
|
* priv_readelf.h (read_elf_object): New declaration.
|
||||||
|
(read_elf_debug): Ditto.
|
||||||
|
|
||||||
|
* priv_storage.h (struct _DebugInfo): New field 'bool deferred'.
|
||||||
|
|
||||||
|
* readelf.c (read_elf_debug_info): Split into read_elf_object and
|
||||||
|
read_elf_debug.
|
||||||
|
(read_elf_object): Read non .debug_* section from an ELF binary.
|
||||||
|
(read_elf_debug): Read .debug_* sections from an ELF binary as
|
||||||
|
as well any separate/alternate debuginfo files.
|
||||||
|
|
||||||
|
* storage.c (canonicaliseSymtab): Remove assert in order to support
|
||||||
|
canonicalization of deferred _DebugInfo.
|
||||||
|
(finish_CFSI_arrays): Add early return if _DebugInfo is
|
||||||
|
deferred in order to avoid freeing memory that will be needed
|
||||||
|
when reading debuginfo at a later time.
|
||||||
|
(canonicaliseTables): Ditto.
|
||||||
|
|
||||||
|
* pub_core_debuginfo.h (addr_load_di): New declaration.
|
||||||
|
(load_di): New declaration.
|
||||||
|
---
|
||||||
|
NEWS | 1 +
|
||||||
|
coregrind/m_debuginfo/debuginfo.c | 57 +++-
|
||||||
|
coregrind/m_debuginfo/priv_readelf.h | 24 +-
|
||||||
|
coregrind/m_debuginfo/priv_storage.h | 7 +
|
||||||
|
coregrind/m_debuginfo/readelf.c | 437 ++++++++++++++++++---------
|
||||||
|
coregrind/m_debuginfo/storage.c | 13 +-
|
||||||
|
coregrind/pub_core_debuginfo.h | 4 +
|
||||||
|
7 files changed, 379 insertions(+), 164 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
|
||||||
|
index 22b41def2..8d1fdc696 100644
|
||||||
|
--- a/coregrind/m_debuginfo/debuginfo.c
|
||||||
|
+++ b/coregrind/m_debuginfo/debuginfo.c
|
||||||
|
@@ -959,14 +959,16 @@ static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
|
||||||
|
discard_DebugInfos_which_overlap_with( di );
|
||||||
|
|
||||||
|
/* The DebugInfoMappings that now exist in the FSM may involve
|
||||||
|
- overlaps. This confuses ML_(read_elf_debug_info), and may cause
|
||||||
|
+ overlaps. This confuses ML_(read_elf_*), and may cause
|
||||||
|
it to compute wrong biases. So de-overlap them now.
|
||||||
|
See http://bugzilla.mozilla.org/show_bug.cgi?id=788974 */
|
||||||
|
truncate_DebugInfoMapping_overlaps( di, di->fsm.maps );
|
||||||
|
|
||||||
|
/* And acquire new info. */
|
||||||
|
# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
|
||||||
|
- ok = ML_(read_elf_debug_info)( di );
|
||||||
|
+ ok = ML_(read_elf_object)( di );
|
||||||
|
+ if (ok)
|
||||||
|
+ di->deferred = True;
|
||||||
|
# elif defined(VGO_darwin)
|
||||||
|
ok = ML_(read_macho_debug_info)( di );
|
||||||
|
# else
|
||||||
|
@@ -1443,6 +1445,50 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Load DI if it has a text segment containing A and DI hasn't already
|
||||||
|
+ been loaded. */
|
||||||
|
+
|
||||||
|
+void VG_(load_di)( DebugInfo *di, Addr a)
|
||||||
|
+{
|
||||||
|
+ if (!di->deferred
|
||||||
|
+ || !di->text_present
|
||||||
|
+ || di->text_size <= 0
|
||||||
|
+ || di->text_avma > a
|
||||||
|
+ || a >= di->text_avma + di->text_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ di->deferred = False;
|
||||||
|
+ ML_(read_elf_debug) (di);
|
||||||
|
+ ML_(canonicaliseTables)( di );
|
||||||
|
+
|
||||||
|
+ /* Check invariants listed in
|
||||||
|
+ Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
|
||||||
|
+ priv_storage.h. */
|
||||||
|
+ check_CFSI_related_invariants(di);
|
||||||
|
+ ML_(finish_CFSI_arrays)(di);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Attempt to load DebugInfo with a text segment containing A,
|
||||||
|
+ if such a debuginfo hasn't already been loaded. */
|
||||||
|
+
|
||||||
|
+void VG_(addr_load_di)( Addr a )
|
||||||
|
+{
|
||||||
|
+ DebugInfo *di;
|
||||||
|
+
|
||||||
|
+ di = VG_(find_DebugInfo)(VG_(current_DiEpoch)(), a);
|
||||||
|
+ if (di != NULL)
|
||||||
|
+ if (di->deferred) {
|
||||||
|
+ di->deferred = False;
|
||||||
|
+ ML_(read_elf_debug) (di);
|
||||||
|
+ ML_(canonicaliseTables)( di );
|
||||||
|
+
|
||||||
|
+ /* Check invariants listed in
|
||||||
|
+ Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
|
||||||
|
+ priv_storage.h. */
|
||||||
|
+ check_CFSI_related_invariants(di);
|
||||||
|
+ ML_(finish_CFSI_arrays)(di);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Unmap is simpler - throw away any SegInfos intersecting
|
||||||
|
[a, a+len). */
|
||||||
|
@@ -2746,6 +2792,11 @@ const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc)
|
||||||
|
Bool know_objname;
|
||||||
|
Bool know_srcloc;
|
||||||
|
|
||||||
|
+ if (iipc && iipc->di)
|
||||||
|
+ VG_(load_di) (iipc->di, eip);
|
||||||
|
+ else
|
||||||
|
+ VG_(addr_load_di) (eip);
|
||||||
|
+
|
||||||
|
if (is_bottom(iipc)) {
|
||||||
|
// At the bottom (towards main), we describe the fn at eip.
|
||||||
|
know_fnname = VG_(clo_sym_offsets)
|
||||||
|
@@ -3090,6 +3141,8 @@ static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
|
||||||
|
if (!is_DI_valid_for_epoch(di, curr_epoch))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ VG_(load_di)(di, ip);
|
||||||
|
+
|
||||||
|
/* Use the per-DebugInfo summary address ranges to skip
|
||||||
|
inapplicable DebugInfos quickly. */
|
||||||
|
if (di->cfsi_used == 0)
|
||||||
|
diff --git a/coregrind/m_debuginfo/priv_readelf.h b/coregrind/m_debuginfo/priv_readelf.h
|
||||||
|
index 57aa0cc3f..7e0fa17c9 100644
|
||||||
|
--- a/coregrind/m_debuginfo/priv_readelf.h
|
||||||
|
+++ b/coregrind/m_debuginfo/priv_readelf.h
|
||||||
|
@@ -44,13 +44,23 @@
|
||||||
|
extern Bool ML_(is_elf_object_file)( const void* image, SizeT n_image,
|
||||||
|
Bool rel_ok );
|
||||||
|
|
||||||
|
-/* The central function for reading ELF debug info. For the
|
||||||
|
- object/exe specified by the SegInfo, find ELF sections, then read
|
||||||
|
- the symbols, line number info, file name info, CFA (stack-unwind
|
||||||
|
- info) and anything else we want, into the tables within the
|
||||||
|
- supplied SegInfo.
|
||||||
|
-*/
|
||||||
|
-extern Bool ML_(read_elf_debug_info) ( DebugInfo* di );
|
||||||
|
+/* Read the ELF binary specified by DI. For the object/exe specified
|
||||||
|
+ by the SegInfo, find ELF sections, then read the symbols, line number
|
||||||
|
+ info, file name info, CFA (stack-unwind info) and anything else we
|
||||||
|
+ want, into the tables within the supplied SegInfo.
|
||||||
|
+
|
||||||
|
+ .debug_* sections as well as any separate debuginfo files are not
|
||||||
|
+ loaded by this function but instead by ML_(read_elf_debug). This
|
||||||
|
+ separation facilitates lazy loading of debuginfo. */
|
||||||
|
+extern Bool ML_(read_elf_object) ( DebugInfo* di );
|
||||||
|
+
|
||||||
|
+/* Read .debug_* sections from the ELF binary specified by DI. Also
|
||||||
|
+ attempt to load any separate debuginfo files associated with the
|
||||||
|
+ object.
|
||||||
|
+
|
||||||
|
+ ML_(read_elf_object) should be called on DI before calling this
|
||||||
|
+ function. */
|
||||||
|
+extern Bool ML_(read_elf_debug) ( DebugInfo* di );
|
||||||
|
|
||||||
|
extern Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename, Int * rw_load_count );
|
||||||
|
|
||||||
|
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
|
||||||
|
index a4b90d36b..b959873ab 100644
|
||||||
|
--- a/coregrind/m_debuginfo/priv_storage.h
|
||||||
|
+++ b/coregrind/m_debuginfo/priv_storage.h
|
||||||
|
@@ -678,6 +678,13 @@ struct _DebugInfo {
|
||||||
|
invalid and should not be consulted. */
|
||||||
|
Bool have_dinfo; /* initially False */
|
||||||
|
|
||||||
|
+ /* If true then the reading of .debug_* section has been deferred
|
||||||
|
+ until it this information is required (such as when printing
|
||||||
|
+ a stacktrace). Additionally, if true then the reading of any
|
||||||
|
+ separate debuginfo files associated with this object has also
|
||||||
|
+ been deferred. */
|
||||||
|
+ Bool deferred;
|
||||||
|
+
|
||||||
|
/* All the rest of the fields in this structure are filled in once
|
||||||
|
we have committed to reading the symbols and debug info (that
|
||||||
|
is, at the point where .have_dinfo is set to True). */
|
||||||
|
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
|
||||||
|
index ce7b7998d..f99d3dfd2 100644
|
||||||
|
--- a/coregrind/m_debuginfo/readelf.c
|
||||||
|
+++ b/coregrind/m_debuginfo/readelf.c
|
||||||
|
@@ -1836,6 +1836,44 @@ static HChar* readlink_path (const HChar *path)
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define FINDX_MIMG(_sec_name, _sec_escn, _post_fx) \
|
||||||
|
+ do { \
|
||||||
|
+ ElfXX_Shdr a_shdr; \
|
||||||
|
+ ML_(img_get)(&a_shdr, mimg, \
|
||||||
|
+ INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
|
||||||
|
+ sizeof(a_shdr)); \
|
||||||
|
+ if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
|
||||||
|
+ + a_shdr.sh_name, _sec_name)) { \
|
||||||
|
+ Bool nobits; \
|
||||||
|
+ _sec_escn.img = mimg; \
|
||||||
|
+ _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
|
||||||
|
+ _sec_escn.szB = a_shdr.sh_size; \
|
||||||
|
+ if (!check_compression(&a_shdr, &_sec_escn)) { \
|
||||||
|
+ ML_(symerr)(di, True, " Compression type is unsupported"); \
|
||||||
|
+ goto out; \
|
||||||
|
+ } \
|
||||||
|
+ nobits = a_shdr.sh_type == SHT_NOBITS; \
|
||||||
|
+ vg_assert(_sec_escn.img != NULL); \
|
||||||
|
+ vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
|
||||||
|
+ TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
|
||||||
|
+ _sec_name, (ULong)a_shdr.sh_offset, \
|
||||||
|
+ ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
|
||||||
|
+ /* SHT_NOBITS sections have zero size in the file. */ \
|
||||||
|
+ if (!nobits && \
|
||||||
|
+ a_shdr.sh_offset + \
|
||||||
|
+ a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
|
||||||
|
+ ML_(symerr)(di, True, \
|
||||||
|
+ " section beyond image end?!"); \
|
||||||
|
+ goto out; \
|
||||||
|
+ } \
|
||||||
|
+ _post_fx; \
|
||||||
|
+ } \
|
||||||
|
+ } while (0);
|
||||||
|
+
|
||||||
|
+/* Version with no post-effects */
|
||||||
|
+#define FIND_MIMG(_sec_name, _sec_escn) \
|
||||||
|
+ FINDX_MIMG(_sec_name, _sec_escn, /**/)
|
||||||
|
+
|
||||||
|
/* The central function for reading ELF debug info. For the
|
||||||
|
object/exe specified by the DebugInfo, find ELF sections, then read
|
||||||
|
the symbols, line number info, file name info, CFA (stack-unwind
|
||||||
|
@@ -1843,7 +1881,7 @@ static HChar* readlink_path (const HChar *path)
|
||||||
|
supplied DebugInfo.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
+Bool ML_(read_elf_object) ( struct _DebugInfo* di )
|
||||||
|
{
|
||||||
|
/* This function is long and complex. That, and the presence of
|
||||||
|
nested scopes, means it's not always easy to see which parts are
|
||||||
|
@@ -1874,7 +1912,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
|
||||||
|
|
||||||
|
/* TOPLEVEL */
|
||||||
|
- Bool res, ok;
|
||||||
|
+ Bool ok;
|
||||||
|
Word i, j;
|
||||||
|
Bool dynbss_present = False;
|
||||||
|
Bool sdynbss_present = False;
|
||||||
|
@@ -1882,12 +1920,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
/* Image for the main ELF file we're working with. */
|
||||||
|
DiImage* mimg = NULL;
|
||||||
|
|
||||||
|
- /* Ditto for any ELF debuginfo file that we might happen to load. */
|
||||||
|
- DiImage* dimg = NULL;
|
||||||
|
-
|
||||||
|
- /* Ditto for alternate ELF debuginfo file that we might happen to load. */
|
||||||
|
- DiImage* aimg = NULL;
|
||||||
|
-
|
||||||
|
/* ELF header offset for the main file. Should be zero since the
|
||||||
|
ELF header is at start of file. */
|
||||||
|
DiOffT ehdr_mioff = 0;
|
||||||
|
@@ -1970,8 +2002,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
got, plt, and toc.
|
||||||
|
---------------------------------------------------------- */
|
||||||
|
|
||||||
|
- res = False;
|
||||||
|
-
|
||||||
|
if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
|
||||||
|
VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
|
||||||
|
di->fsm.filename );
|
||||||
|
@@ -2056,7 +2086,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
shdr_strtab_mioff
|
||||||
|
= ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
|
||||||
|
|
||||||
|
- if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
|
||||||
|
+ if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
|
||||||
|
1/*bogus, but we don't know the real size*/ )) {
|
||||||
|
ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
|
||||||
|
goto out;
|
||||||
|
@@ -2798,10 +2828,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
di->text_avma - di->text_bias,
|
||||||
|
di->text_avma );
|
||||||
|
|
||||||
|
- TRACE_SYMTAB("\n");
|
||||||
|
- TRACE_SYMTAB("------ Finding image addresses "
|
||||||
|
- "for debug-info sections ------\n");
|
||||||
|
-
|
||||||
|
/* TOPLEVEL */
|
||||||
|
/* Find interesting sections, read the symbol table(s), read any
|
||||||
|
debug information. Each section is located either in the main,
|
||||||
|
@@ -2821,27 +2847,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
# if defined(VGO_solaris)
|
||||||
|
DiSlice ldynsym_escn = DiSlice_INVALID; // .SUNW_ldynsym
|
||||||
|
# endif
|
||||||
|
- DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink
|
||||||
|
- DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink
|
||||||
|
- DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2)
|
||||||
|
- DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2)
|
||||||
|
- DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
|
||||||
|
- DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
|
||||||
|
- DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
|
||||||
|
- DiSlice debug_line_str_escn = DiSlice_INVALID; // .debug_line_str(dwarf5)
|
||||||
|
- DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
|
||||||
|
- DiSlice debug_rnglists_escn = DiSlice_INVALID; // .debug_rnglists(dwarf5)
|
||||||
|
- DiSlice debug_loclists_escn = DiSlice_INVALID; // .debug_loclists(dwarf5)
|
||||||
|
- DiSlice debug_addr_escn = DiSlice_INVALID; // .debug_addr (dwarf5)
|
||||||
|
- DiSlice debug_str_offsets_escn = DiSlice_INVALID; // .debug_str_offsets (dwarf5)
|
||||||
|
- DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
|
||||||
|
- DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
|
||||||
|
- DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
|
||||||
|
- DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt)
|
||||||
|
- DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
|
||||||
|
- DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt)
|
||||||
|
- DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1)
|
||||||
|
- DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1)
|
||||||
|
DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2,
|
||||||
|
// ppc64be-linux)
|
||||||
|
DiSlice ehframe_escn[N_EHFRAME_SECTS]; // .eh_frame (dwarf2)
|
||||||
|
@@ -2868,118 +2873,282 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
/* TOPLEVEL */
|
||||||
|
/* Iterate over section headers (again) */
|
||||||
|
for (i = 0; i < ehdr_m.e_shnum; i++) {
|
||||||
|
+ /* NAME ElfSec */
|
||||||
|
+ FIND_MIMG( ".dynsym", dynsym_escn)
|
||||||
|
+ FIND_MIMG( ".dynstr", dynstr_escn)
|
||||||
|
+ FIND_MIMG( ".symtab", symtab_escn)
|
||||||
|
+ FIND_MIMG( ".strtab", strtab_escn)
|
||||||
|
+# if defined(VGO_solaris)
|
||||||
|
+ FIND_MIMG( ".SUNW_ldynsym", ldynsym_escn)
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
-# define FINDX(_sec_name, _sec_escn, _post_fx) \
|
||||||
|
- do { \
|
||||||
|
- ElfXX_Shdr a_shdr; \
|
||||||
|
- ML_(img_get)(&a_shdr, mimg, \
|
||||||
|
- INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
|
||||||
|
- sizeof(a_shdr)); \
|
||||||
|
- if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
|
||||||
|
- + a_shdr.sh_name, _sec_name)) { \
|
||||||
|
- Bool nobits; \
|
||||||
|
- _sec_escn.img = mimg; \
|
||||||
|
- _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
|
||||||
|
- _sec_escn.szB = a_shdr.sh_size; \
|
||||||
|
- if (!check_compression(&a_shdr, &_sec_escn)) { \
|
||||||
|
- ML_(symerr)(di, True, " Compression type is unsupported"); \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- nobits = a_shdr.sh_type == SHT_NOBITS; \
|
||||||
|
- vg_assert(_sec_escn.img != NULL); \
|
||||||
|
- vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
|
||||||
|
- TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
|
||||||
|
- _sec_name, (ULong)a_shdr.sh_offset, \
|
||||||
|
- ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
|
||||||
|
- /* SHT_NOBITS sections have zero size in the file. */ \
|
||||||
|
- if (!nobits && \
|
||||||
|
- a_shdr.sh_offset + \
|
||||||
|
- a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
|
||||||
|
- ML_(symerr)(di, True, \
|
||||||
|
- " section beyond image end?!"); \
|
||||||
|
- goto out; \
|
||||||
|
- } \
|
||||||
|
- _post_fx; \
|
||||||
|
- } \
|
||||||
|
- } while (0);
|
||||||
|
+ FINDX_MIMG( ".eh_frame", ehframe_escn[ehframe_mix],
|
||||||
|
+ do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
|
||||||
|
+ } while (0)
|
||||||
|
+ )
|
||||||
|
+ /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
|
||||||
|
+ multi-instance kludgery, how are we assured that the order
|
||||||
|
+ in which we fill in ehframe_escn[] is consistent with the
|
||||||
|
+ order in which we previously filled in di->ehframe_avma[]
|
||||||
|
+ and di->ehframe_size[] ? By the fact that in both cases,
|
||||||
|
+ these arrays were filled in by iterating over the section
|
||||||
|
+ headers top-to-bottom. So both loops (this one and the
|
||||||
|
+ previous one) encounter the .eh_frame entries in the same
|
||||||
|
+ order and so fill in these arrays in a consistent order.
|
||||||
|
+ */
|
||||||
|
+ } /* Iterate over section headers (again) */
|
||||||
|
|
||||||
|
- /* Version with no post-effects */
|
||||||
|
-# define FIND(_sec_name, _sec_escn) \
|
||||||
|
- FINDX(_sec_name, _sec_escn, /**/)
|
||||||
|
+ /* Check some sizes */
|
||||||
|
+ vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
+ vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
+# if defined(VGO_solaris)
|
||||||
|
+ vg_assert((ldynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
- /* NAME ElfSec */
|
||||||
|
- FIND( ".dynsym", dynsym_escn)
|
||||||
|
- FIND( ".dynstr", dynstr_escn)
|
||||||
|
- FIND( ".symtab", symtab_escn)
|
||||||
|
- FIND( ".strtab", strtab_escn)
|
||||||
|
+ /* Read symbols */
|
||||||
|
+ {
|
||||||
|
+ void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
|
||||||
|
+ DiSlice*, DiSlice*, DiSlice*, Bool);
|
||||||
|
+# if defined(VGP_ppc64be_linux)
|
||||||
|
+ read_elf_symtab = read_elf_symtab__ppc64be_linux;
|
||||||
|
+# else
|
||||||
|
+ read_elf_symtab = read_elf_symtab__normal;
|
||||||
|
+# endif
|
||||||
|
+ if (symtab_escn.img != NULL)
|
||||||
|
+ read_elf_symtab(di, "symbol table",
|
||||||
|
+ &symtab_escn, &strtab_escn, &opd_escn,
|
||||||
|
+ False);
|
||||||
|
+ read_elf_symtab(di, "dynamic symbol table",
|
||||||
|
+ &dynsym_escn, &dynstr_escn, &opd_escn,
|
||||||
|
+ False);
|
||||||
|
# if defined(VGO_solaris)
|
||||||
|
- FIND( ".SUNW_ldynsym", ldynsym_escn)
|
||||||
|
+ read_elf_symtab(di, "local dynamic symbol table",
|
||||||
|
+ &ldynsym_escn, &dynstr_escn, &opd_escn,
|
||||||
|
+ False);
|
||||||
|
# endif
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- FIND( ".gnu_debuglink", debuglink_escn)
|
||||||
|
- FIND( ".gnu_debugaltlink", debugaltlink_escn)
|
||||||
|
+ /* TOPLEVEL */
|
||||||
|
+ /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
|
||||||
|
+ the .eh_frame section(s) first. */
|
||||||
|
+ vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
|
||||||
|
+ for (i = 0; i < di->n_ehframe; i++) {
|
||||||
|
+ /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
|
||||||
|
+ this next assertion should hold. */
|
||||||
|
+ vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
|
||||||
|
+ vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
|
||||||
|
+ ML_(read_callframe_info_dwarf3)( di,
|
||||||
|
+ ehframe_escn[i],
|
||||||
|
+ di->ehframe_avma[i],
|
||||||
|
+ True/*is_ehframe*/ );
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return True;
|
||||||
|
+
|
||||||
|
+ out:
|
||||||
|
+ {
|
||||||
|
+ /* Last, but not least, detach from the image. */
|
||||||
|
+ if (mimg) ML_(img_done)(mimg);
|
||||||
|
+
|
||||||
|
+ if (svma_ranges) VG_(deleteXA)(svma_ranges);
|
||||||
|
|
||||||
|
- FIND( ".debug_line", debug_line_escn)
|
||||||
|
+ return False;
|
||||||
|
+ } /* out: */
|
||||||
|
+
|
||||||
|
+ /* NOTREACHED */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+Bool ML_(read_elf_debug) ( struct _DebugInfo* di )
|
||||||
|
+{
|
||||||
|
+ Word i, j;
|
||||||
|
+ Bool res = True;
|
||||||
|
+ Bool ok;
|
||||||
|
+
|
||||||
|
+ /* Image for the main ELF file we're working with. */
|
||||||
|
+ DiImage* mimg = NULL;
|
||||||
|
+
|
||||||
|
+ /* Ditto for any ELF debuginfo file that we might happen to load. */
|
||||||
|
+ DiImage* dimg = NULL;
|
||||||
|
+
|
||||||
|
+ /* Ditto for alternate ELF debuginfo file that we might happen to load. */
|
||||||
|
+ DiImage* aimg = NULL;
|
||||||
|
+
|
||||||
|
+ /* Section header image addr, # entries, entry size. Also the
|
||||||
|
+ associated string table. */
|
||||||
|
+ DiOffT shdr_mioff = 0;
|
||||||
|
+ UWord shdr_mnent = 0;
|
||||||
|
+ UWord shdr_ment_szB = 0;
|
||||||
|
+ DiOffT shdr_strtab_mioff = 0;
|
||||||
|
+
|
||||||
|
+ DiOffT ehdr_mioff = 0;
|
||||||
|
+
|
||||||
|
+ /* Connect to the primary object image, so that we can read symbols
|
||||||
|
+ and line number info out of it. It will be disconnected
|
||||||
|
+ immediately thereafter; it is only connected transiently. */
|
||||||
|
+ mimg = ML_(img_from_local_file)(di->fsm.filename);
|
||||||
|
+ if (mimg == NULL) {
|
||||||
|
+ VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
|
||||||
|
+ di->fsm.filename );
|
||||||
|
+ VG_(message)(Vg_UserMsg, " no debug info loaded\n" );
|
||||||
|
+ return False;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Ok, the object image is available. Now verify that it is a
|
||||||
|
+ valid ELF .so or executable image. */
|
||||||
|
+ ok = is_elf_object_file_by_DiImage(mimg, False);
|
||||||
|
+ if (!ok) {
|
||||||
|
+ ML_(symerr)(di, True, "Invalid ELF Header");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Find where the program and section header tables are, and give
|
||||||
|
+ up if either is missing or outside the image (bogus). */
|
||||||
|
+ ElfXX_Ehdr ehdr_m;
|
||||||
|
+ vg_assert(ehdr_mioff == 0); // ensured by its initialisation
|
||||||
|
+ ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
|
||||||
|
+ vg_assert(ok); // ML_(is_elf_object_file) should ensure this
|
||||||
|
+ ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
|
||||||
|
+
|
||||||
|
+ shdr_mioff = ehdr_mioff + ehdr_m.e_shoff;
|
||||||
|
+ shdr_mnent = ehdr_m.e_shnum;
|
||||||
|
+ shdr_ment_szB = ehdr_m.e_shentsize;
|
||||||
|
+
|
||||||
|
+ if (shdr_mnent == 0
|
||||||
|
+ || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
|
||||||
|
+ ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Also find the section header's string table, and validate. */
|
||||||
|
+ /* checked previously by is_elf_object_file: */
|
||||||
|
+ vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
|
||||||
|
+
|
||||||
|
+ // shdr_mioff is the offset of the section header table
|
||||||
|
+ // and we need the ehdr_m.e_shstrndx'th entry
|
||||||
|
+ { ElfXX_Shdr a_shdr;
|
||||||
|
+ ML_(img_get)(&a_shdr, mimg,
|
||||||
|
+ INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
|
||||||
|
+ sizeof(a_shdr));
|
||||||
|
+ shdr_strtab_mioff
|
||||||
|
+ = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
|
||||||
|
+
|
||||||
|
+ if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
|
||||||
|
+ 1/*bogus, but we don't know the real size*/ )) {
|
||||||
|
+ ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TRACE_SYMTAB("\n");
|
||||||
|
+ TRACE_SYMTAB("------ Finding image addresses "
|
||||||
|
+ "for debug-info sections ------\n");
|
||||||
|
+ /* TOPLEVEL */
|
||||||
|
+ /* Find interesting sections, read the symbol table(s), read any
|
||||||
|
+ debug information. Each section is located either in the main,
|
||||||
|
+ debug or alt-debug files, but only in one. For each section,
|
||||||
|
+ |section_escn| records which of |mimg|, |dimg| or |aimg| we
|
||||||
|
+ found it in, along with the section's image offset and its size.
|
||||||
|
+ The triples (section_img, section_ioff, section_szB) are
|
||||||
|
+ consistent, in that they are always either (NULL,
|
||||||
|
+ DiOffT_INVALID, 0), or refer to the same image, and are all
|
||||||
|
+ assigned together. */
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ /* TOPLEVEL */
|
||||||
|
+ DiSlice strtab_escn = DiSlice_INVALID; // .strtab
|
||||||
|
+ DiSlice symtab_escn = DiSlice_INVALID; // .symtab
|
||||||
|
+ DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink
|
||||||
|
+ DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink
|
||||||
|
+ DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2)
|
||||||
|
+ DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2)
|
||||||
|
+ DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
|
||||||
|
+ DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
|
||||||
|
+ DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
|
||||||
|
+ DiSlice debug_line_str_escn = DiSlice_INVALID; // .debug_line_str(dwarf5)
|
||||||
|
+ DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
|
||||||
|
+ DiSlice debug_rnglists_escn = DiSlice_INVALID; // .debug_rnglists(dwarf5)
|
||||||
|
+ DiSlice debug_loclists_escn = DiSlice_INVALID; // .debug_loclists(dwarf5)
|
||||||
|
+ DiSlice debug_addr_escn = DiSlice_INVALID; // .debug_addr (dwarf5)
|
||||||
|
+ DiSlice debug_str_offsets_escn = DiSlice_INVALID; // .debug_str_offsets (dwarf5)
|
||||||
|
+ DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
|
||||||
|
+ DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
|
||||||
|
+ DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
|
||||||
|
+ DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt)
|
||||||
|
+ DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
|
||||||
|
+ DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt)
|
||||||
|
+ DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1)
|
||||||
|
+ DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1)
|
||||||
|
+ DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2,
|
||||||
|
+ // ppc64be-linux)
|
||||||
|
+
|
||||||
|
+ /* TOPLEVEL */
|
||||||
|
+ /* Iterate over section headers (again) */
|
||||||
|
+ for (i = 0; i < ehdr_m.e_shnum; i++) {
|
||||||
|
+
|
||||||
|
+ /* NAME ElfSec */
|
||||||
|
+ FIND_MIMG( ".symtab", symtab_escn)
|
||||||
|
+ FIND_MIMG( ".strtab", strtab_escn)
|
||||||
|
+ FIND_MIMG( ".gnu_debuglink", debuglink_escn)
|
||||||
|
+ FIND_MIMG( ".gnu_debugaltlink", debugaltlink_escn)
|
||||||
|
+
|
||||||
|
+ FIND_MIMG( ".debug_line", debug_line_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_line_escn))
|
||||||
|
- FIND(".zdebug_line", debug_line_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_line", debug_line_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_info", debug_info_escn)
|
||||||
|
+ FIND_MIMG( ".debug_info", debug_info_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_info_escn))
|
||||||
|
- FIND(".zdebug_info", debug_info_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_info", debug_info_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_types", debug_types_escn)
|
||||||
|
+ FIND_MIMG( ".debug_types", debug_types_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_types_escn))
|
||||||
|
- FIND(".zdebug_types", debug_types_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_types", debug_types_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_abbrev", debug_abbv_escn)
|
||||||
|
+ FIND_MIMG( ".debug_abbrev", debug_abbv_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_abbv_escn))
|
||||||
|
- FIND(".zdebug_abbrev", debug_abbv_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_abbrev", debug_abbv_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_str", debug_str_escn)
|
||||||
|
+ FIND_MIMG( ".debug_str", debug_str_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_str_escn))
|
||||||
|
- FIND(".zdebug_str", debug_str_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_str", debug_str_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_line_str", debug_line_str_escn)
|
||||||
|
+ FIND_MIMG( ".debug_line_str", debug_line_str_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_line_str_escn))
|
||||||
|
- FIND(".zdebug_str", debug_line_str_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_str", debug_line_str_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_ranges", debug_ranges_escn)
|
||||||
|
+ FIND_MIMG( ".debug_ranges", debug_ranges_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_ranges_escn))
|
||||||
|
- FIND(".zdebug_ranges", debug_ranges_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_ranges", debug_ranges_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_rnglists", debug_rnglists_escn)
|
||||||
|
+ FIND_MIMG( ".debug_rnglists", debug_rnglists_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_rnglists_escn))
|
||||||
|
- FIND(".zdebug_rnglists", debug_rnglists_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_rnglists", debug_rnglists_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_loclists", debug_loclists_escn)
|
||||||
|
+ FIND_MIMG( ".debug_loclists", debug_loclists_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_loclists_escn))
|
||||||
|
- FIND(".zdebug_loclists", debug_loclists_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_loclists", debug_loclists_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_loc", debug_loc_escn)
|
||||||
|
+ FIND_MIMG( ".debug_loc", debug_loc_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_loc_escn))
|
||||||
|
- FIND(".zdebug_loc", debug_loc_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_loc", debug_loc_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_frame", debug_frame_escn)
|
||||||
|
+ FIND_MIMG( ".debug_frame", debug_frame_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_frame_escn))
|
||||||
|
- FIND(".zdebug_frame", debug_frame_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_frame", debug_frame_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_addr", debug_addr_escn)
|
||||||
|
+ FIND_MIMG( ".debug_addr", debug_addr_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_addr_escn))
|
||||||
|
- FIND(".zdebug_addr", debug_addr_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_addr", debug_addr_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug_str_offsets", debug_str_offsets_escn)
|
||||||
|
+ FIND_MIMG( ".debug_str_offsets", debug_str_offsets_escn)
|
||||||
|
if (!ML_(sli_is_valid)(debug_str_offsets_escn))
|
||||||
|
- FIND(".zdebug_str_offsets", debug_str_offsets_escn)
|
||||||
|
+ FIND_MIMG(".zdebug_str_offsets", debug_str_offsets_escn)
|
||||||
|
|
||||||
|
- FIND( ".debug", dwarf1d_escn)
|
||||||
|
- FIND( ".line", dwarf1l_escn)
|
||||||
|
+ FIND_MIMG( ".debug", dwarf1d_escn)
|
||||||
|
+ FIND_MIMG( ".line", dwarf1l_escn)
|
||||||
|
|
||||||
|
- FIND( ".opd", opd_escn)
|
||||||
|
+ FIND_MIMG( ".opd", opd_escn)
|
||||||
|
|
||||||
|
- FINDX( ".eh_frame", ehframe_escn[ehframe_mix],
|
||||||
|
- do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
|
||||||
|
- } while (0)
|
||||||
|
- )
|
||||||
|
/* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
|
||||||
|
multi-instance kludgery, how are we assured that the order
|
||||||
|
in which we fill in ehframe_escn[] is consistent with the
|
||||||
|
@@ -2991,8 +3160,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
order and so fill in these arrays in a consistent order.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-# undef FINDX
|
||||||
|
-# undef FIND
|
||||||
|
} /* Iterate over section headers (again) */
|
||||||
|
|
||||||
|
/* TOPLEVEL */
|
||||||
|
@@ -3465,53 +3632,23 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
} /* Find all interesting sections */
|
||||||
|
} /* do we have a debug image? */
|
||||||
|
|
||||||
|
-
|
||||||
|
/* TOPLEVEL */
|
||||||
|
- /* Check some sizes */
|
||||||
|
- vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
-# if defined(VGO_solaris)
|
||||||
|
- vg_assert((ldynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
|
||||||
|
-# endif
|
||||||
|
|
||||||
|
/* TOPLEVEL */
|
||||||
|
/* Read symbols */
|
||||||
|
{
|
||||||
|
void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
|
||||||
|
DiSlice*, DiSlice*, DiSlice*, Bool);
|
||||||
|
- Bool symtab_in_debug;
|
||||||
|
# if defined(VGP_ppc64be_linux)
|
||||||
|
read_elf_symtab = read_elf_symtab__ppc64be_linux;
|
||||||
|
# else
|
||||||
|
read_elf_symtab = read_elf_symtab__normal;
|
||||||
|
# endif
|
||||||
|
- symtab_in_debug = symtab_escn.img == dimg;
|
||||||
|
- read_elf_symtab(di, "symbol table",
|
||||||
|
- &symtab_escn, &strtab_escn, &opd_escn,
|
||||||
|
- symtab_in_debug);
|
||||||
|
- read_elf_symtab(di, "dynamic symbol table",
|
||||||
|
- &dynsym_escn, &dynstr_escn, &opd_escn,
|
||||||
|
- False);
|
||||||
|
-# if defined(VGO_solaris)
|
||||||
|
- read_elf_symtab(di, "local dynamic symbol table",
|
||||||
|
- &ldynsym_escn, &dynstr_escn, &opd_escn,
|
||||||
|
- False);
|
||||||
|
-# endif
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* TOPLEVEL */
|
||||||
|
- /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
|
||||||
|
- the .eh_frame section(s) first. */
|
||||||
|
- vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
|
||||||
|
- for (i = 0; i < di->n_ehframe; i++) {
|
||||||
|
- /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
|
||||||
|
- this next assertion should hold. */
|
||||||
|
- vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
|
||||||
|
- vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
|
||||||
|
- ML_(read_callframe_info_dwarf3)( di,
|
||||||
|
- ehframe_escn[i],
|
||||||
|
- di->ehframe_avma[i],
|
||||||
|
- True/*is_ehframe*/ );
|
||||||
|
+ if (symtab_escn.img != NULL)
|
||||||
|
+ read_elf_symtab(di, "symbol table",
|
||||||
|
+ &symtab_escn, &strtab_escn, &opd_escn,
|
||||||
|
+ True);
|
||||||
|
}
|
||||||
|
if (ML_(sli_is_valid)(debug_frame_escn)) {
|
||||||
|
ML_(read_callframe_info_dwarf3)( di,
|
||||||
|
@@ -3643,8 +3780,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
|
||||||
|
if (dimg) ML_(img_done)(dimg);
|
||||||
|
if (aimg) ML_(img_done)(aimg);
|
||||||
|
|
||||||
|
- if (svma_ranges) VG_(deleteXA)(svma_ranges);
|
||||||
|
-
|
||||||
|
return res;
|
||||||
|
} /* out: */
|
||||||
|
|
||||||
|
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
|
||||||
|
index c3fa62e96..3ad114607 100644
|
||||||
|
--- a/coregrind/m_debuginfo/storage.c
|
||||||
|
+++ b/coregrind/m_debuginfo/storage.c
|
||||||
|
@@ -1297,8 +1297,7 @@ void ML_(addVar)( struct _DebugInfo* di,
|
||||||
|
that those extra sections have the same bias as .text, but that
|
||||||
|
seems a reasonable assumption to me. */
|
||||||
|
/* This is assured us by top level steering logic in debuginfo.c,
|
||||||
|
- and it is re-checked at the start of
|
||||||
|
- ML_(read_elf_debug_info). */
|
||||||
|
+ and it is re-checked at the start of ML_(read_elf_object). */
|
||||||
|
vg_assert(di->fsm.have_rx_map && di->fsm.rw_map_count);
|
||||||
|
if (level > 0 && ML_(find_rx_mapping)(di, aMin, aMax) == NULL) {
|
||||||
|
if (VG_(clo_verbosity) > 1) {
|
||||||
|
@@ -1725,7 +1724,6 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
|
||||||
|
for (i = 0; i < di->symtab_used; i++) {
|
||||||
|
DiSym* sym = &di->symtab[i];
|
||||||
|
vg_assert(sym->pri_name);
|
||||||
|
- vg_assert(!sym->sec_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort by address. */
|
||||||
|
@@ -2383,6 +2381,9 @@ void ML_(finish_CFSI_arrays) ( struct _DebugInfo* di )
|
||||||
|
vg_assert (f_holes == n_holes);
|
||||||
|
vg_assert (pos == new_used);
|
||||||
|
|
||||||
|
+ if (di->deferred)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
di->cfsi_used = new_used;
|
||||||
|
di->cfsi_size = new_used;
|
||||||
|
ML_(dinfo_free) (di->cfsi_rd);
|
||||||
|
@@ -2398,9 +2399,13 @@ void ML_(canonicaliseTables) ( struct _DebugInfo* di )
|
||||||
|
canonicaliseLoctab ( di );
|
||||||
|
canonicaliseInltab ( di );
|
||||||
|
ML_(canonicaliseCFI) ( di );
|
||||||
|
+ canonicaliseVarInfo ( di );
|
||||||
|
+
|
||||||
|
+ if (di->deferred)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (di->cfsi_m_pool)
|
||||||
|
VG_(freezeDedupPA) (di->cfsi_m_pool, ML_(dinfo_shrink_block));
|
||||||
|
- canonicaliseVarInfo ( di );
|
||||||
|
if (di->strpool)
|
||||||
|
VG_(freezeDedupPA) (di->strpool, ML_(dinfo_shrink_block));
|
||||||
|
if (di->fndnpool)
|
||||||
|
diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h
|
||||||
|
index 938ed00cc..ce7246217 100644
|
||||||
|
--- a/coregrind/pub_core_debuginfo.h
|
||||||
|
+++ b/coregrind/pub_core_debuginfo.h
|
||||||
|
@@ -76,6 +76,10 @@ extern void VG_(di_notify_pdb_debuginfo)( Int fd, Addr avma,
|
||||||
|
extern void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+extern void VG_(addr_load_di)( Addr a );
|
||||||
|
+
|
||||||
|
+extern void VG_(load_di)( DebugInfo *di, Addr a );
|
||||||
|
+
|
||||||
|
extern void VG_(di_discard_ALL_debuginfo)( void );
|
||||||
|
|
||||||
|
/* Like VG_(get_fnname), but it does not do C++ demangling nor Z-demangling
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
Summary: Dynamic analysis tools to detect memory or thread bugs and profile
|
Summary: Dynamic analysis tools to detect memory or thread bugs and profile
|
||||||
Name: %{?scl_prefix}valgrind
|
Name: %{?scl_prefix}valgrind
|
||||||
Version: 3.21.0
|
Version: 3.21.0
|
||||||
Release: 9%{?dist}
|
Release: 10%{?dist}
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: https://www.valgrind.org/
|
URL: https://www.valgrind.org/
|
||||||
@ -116,6 +116,12 @@ Patch12: valgrind-3.21.0-pgste.patch
|
|||||||
# https://bugs.kde.org/show_bug.cgi?id=471311
|
# https://bugs.kde.org/show_bug.cgi?id=471311
|
||||||
Patch13: valgrind-3.21.0-gdb-multi-mode-stdout-redirecting-to-stderr.patch
|
Patch13: valgrind-3.21.0-gdb-multi-mode-stdout-redirecting-to-stderr.patch
|
||||||
|
|
||||||
|
# Add support for lazy reading and downloading of DWARF debuginfo
|
||||||
|
# https://bugs.kde.org/show_bug.cgi?id=471807
|
||||||
|
# Plus fixup commit a0d555a0dfe078ef04ea49d991a8090ab14bd4a5
|
||||||
|
Patch14: valgrind-3.21.0-lazy-debuginfo.patch
|
||||||
|
Patch15: valgrind-3.21.0-cleanup-read_elf_object.patch
|
||||||
|
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
BuildRequires: glibc-devel
|
BuildRequires: glibc-devel
|
||||||
|
|
||||||
@ -262,6 +268,8 @@ Valgrind User Manual for details.
|
|||||||
%patch -P11 -p1
|
%patch -P11 -p1
|
||||||
%patch -P12 -p1
|
%patch -P12 -p1
|
||||||
%patch -P13 -p1
|
%patch -P13 -p1
|
||||||
|
%patch -P14 -p1
|
||||||
|
%patch -P15 -p1
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -495,6 +503,10 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 21 2023 Mark Wielaard <mjw@fedoraproject.org> - 3.21.0-10
|
||||||
|
- Add valgrind-3.21.0-lazy-debuginfo.patch
|
||||||
|
- Add valgrind-3.21.0-cleanup-read_elf_object.patch
|
||||||
|
|
||||||
* Thu Aug 17 2023 Mark Wielaard <mjw@fedoraproject.org> - 3.21.0-9
|
* Thu Aug 17 2023 Mark Wielaard <mjw@fedoraproject.org> - 3.21.0-9
|
||||||
- Add valgrind-3.21.0-gdb-multi-mode-stdout-redirecting-to-stderr.patch
|
- Add valgrind-3.21.0-gdb-multi-mode-stdout-redirecting-to-stderr.patch
|
||||||
- Use %%patch -Pn instead of deprecated %%patchn
|
- Use %%patch -Pn instead of deprecated %%patchn
|
||||||
|
Loading…
Reference in New Issue
Block a user