}
}
+/* Load DI if it hasn't already been been loaded. */
+void VG_(di_load_di)( DebugInfo *di )
+{
+ 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);
+ }
+}
+
/* 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
+ if (!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);
+ VG_(di_load_di)(di);
}
/* Attempt to load DebugInfo with a text segment containing A,
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);
- }
+ VG_(di_load_di)(di);
}
/* Unmap is simpler - throw away any SegInfos intersecting
typedef
struct _TopSpec {
struct _TopSpec* next; /* linked list */
- const DebugInfo* seginfo; /* symbols etc */
+ DebugInfo* seginfo; /* symbols etc */
Spec* specs; /* specs pulled out of seginfo */
Bool mark; /* transient temporary used during deletion */
}
static void handle_maybe_load_notifier( const HChar* soname,
const HChar* symbol, Addr addr );
-static void handle_require_text_symbols ( const DebugInfo* );
+static void handle_require_text_symbols ( DebugInfo* );
/*------------------------------------------------------------*/
/*--- NOTIFICATIONS ---*/
Spec* specs,
TopSpec* parent_spec,
/* debuginfo and the owning TopSpec */
- const DebugInfo* di,
+ DebugInfo* di,
TopSpec* parent_sym
);
topspecs list, and (2) figure out what new binding are now active,
and, as a result, add them to the actives mapping. */
-void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
+void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi )
{
Bool ok, isWrap, isGlobal;
Int i, nsyms, becTag, becPrio;
newdi_soname = VG_(DebugInfo_get_soname)(newdi);
vg_assert(newdi_soname != NULL);
+ /* libc is special, because it contains some of the core redirects.
+ Make sure it is fully loaded. */
+ if (0 == VG_(strcmp)(newdi_soname, libc_soname) ||
+ 0 == VG_(strcmp)(newdi_soname, pthread_soname))
+ VG_(di_load_di)(newdi);
+
#ifdef ENABLE_INNER
{
/* When an outer Valgrind is executing an inner Valgrind, the
Spec* specs,
TopSpec* parent_spec,
/* seginfo and the owning TopSpec */
- const DebugInfo* di,
+ DebugInfo* di,
TopSpec* parent_sym
)
{
sp->mark = VG_(string_match)( sp->from_sopatt, soname );
anyMark = anyMark || sp->mark;
+
+ /* The symtab might be in a separate debuginfo file. Make sure the
+ debuginfo is fully loaded. */
+ if (sp->mark && sp->mandatory)
+ VG_(di_load_di)(di);
}
/* shortcut: if none of the sonames match, there will be no bindings. */
symbols that satisfy any --require-text-symbol= specifications that
apply to it, and abort the run with an error message if not.
*/
-static void handle_require_text_symbols ( const DebugInfo* di )
+static void handle_require_text_symbols ( DebugInfo* di )
{
/* First thing to do is figure out which, if any,
--require-text-symbol specification strings apply to this