static void generate_and_add_actives ( /* spec list and the owning TopSpec */ Spec* specs, TopSpec* parent_spec, /* seginfo and the owning TopSpec */ SegInfo* si, TopSpec* parent_sym ) { Spec* sp; Bool anyMark; Active act; Int nsyms, i; Addr sym_addr; HChar* sym_name; /* First figure out which of the specs match the seginfo's soname. */ anyMark = False; for (sp = specs; sp; sp = sp->next) { sp->mark = VG_(string_match)( sp->from_sopatt, VG_(seginfo_soname)(si) ); anyMark = anyMark || sp->mark; } /* shortcut: if none of the sonames match, there will be no bindings. */ if (!anyMark) return; /* Iterate outermost over the symbols in the seginfo, in the hope of trashing the caches less. */ nsyms = VG_(seginfo_syms_howmany)( si ); for (i = 0; i < nsyms; i++) { VG_(seginfo_syms_getidx)( si, i, &sym_addr, NULL, NULL, &sym_name ); /* On AIX, we cannot redirect calls to a so-called glink function for reasons which are not obvious - something to do with saving r2 across the call. Not a problem, as we don't want to anyway; presumably it is the target of the glink we need to redirect. Hence just spot them and ignore them. They are always of a very specific (more or less ABI-mandated) form. */ if (is_aix5_glink_idiom(sym_addr)) continue; for (sp = specs; sp; sp = sp->next) { if (!sp->mark) continue; /* soname doesn't match */ if (VG_(string_match)( sp->from_fnpatt, sym_name )) { /* got a new binding. Add to collection. */ act.from_addr = sym_addr; act.to_addr = sp->to_addr; act.parent_spec = parent_spec; act.parent_sym = parent_sym; act.isWrap = sp->isWrap; maybe_add_active( act ); } } } }
static void generate_and_add_actives ( /* spec list and the owning TopSpec */ Spec* specs, TopSpec* parent_spec, /* seginfo and the owning TopSpec */ DebugInfo* di, TopSpec* parent_sym ) { Spec* sp; Bool anyMark, isText; Active act; Int nsyms, i; Addr sym_addr; HChar* sym_name; /* First figure out which of the specs match the seginfo's soname. Also clear the 'done' bits, so that after the main loop below tell which of the Specs really did get done. */ anyMark = False; for (sp = specs; sp; sp = sp->next) { sp->done = False; sp->mark = VG_(string_match)( sp->from_sopatt, VG_(DebugInfo_get_soname)(di) ); anyMark = anyMark || sp->mark; } /* shortcut: if none of the sonames match, there will be no bindings. */ if (!anyMark) return; /* Iterate outermost over the symbols in the seginfo, in the hope of trashing the caches less. */ nsyms = VG_(DebugInfo_syms_howmany)( di ); for (i = 0; i < nsyms; i++) { VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, NULL, &sym_name, &isText ); /* ignore data symbols */ if (!isText) continue; /* On AIX, we cannot redirect calls to a so-called glink function for reasons which are not obvious - something to do with saving r2 across the call. Not a problem, as we don't want to anyway; presumably it is the target of the glink we need to redirect. Hence just spot them and ignore them. They are always of a very specific (more or less ABI-mandated) form. */ if (is_aix5_glink_idiom(sym_addr)) continue; for (sp = specs; sp; sp = sp->next) { if (!sp->mark) continue; /* soname doesn't match */ if (VG_(string_match)( sp->from_fnpatt, sym_name )) { /* got a new binding. Add to collection. */ act.from_addr = sym_addr; act.to_addr = sp->to_addr; act.parent_spec = parent_spec; act.parent_sym = parent_sym; act.isWrap = sp->isWrap; sp->done = True; maybe_add_active( act ); } } /* for (sp = specs; sp; sp = sp->next) */ } /* for (i = 0; i < nsyms; i++) */ /* Now, finally, look for Specs which were marked to be done, but didn't get matched. If any such are mandatory we must abort the system at this point. */ for (sp = specs; sp; sp = sp->next) { if (!sp->mark) continue; if (sp->mark && (!sp->done) && sp->mandatory) break; } if (sp) { const HChar** strp; HChar* v = "valgrind: "; vg_assert(sp->mark); vg_assert(!sp->done); vg_assert(sp->mandatory); VG_(printf)("\n"); VG_(printf)( "%sFatal error at startup: a function redirection\n", v); VG_(printf)( "%swhich is mandatory for this platform-tool combination\n", v); VG_(printf)( "%scannot be set up. Details of the redirection are:\n", v); VG_(printf)( "%s\n", v); VG_(printf)( "%sA must-be-redirected function\n", v); VG_(printf)( "%swhose name matches the pattern: %s\n", v, sp->from_fnpatt); VG_(printf)( "%sin an object with soname matching: %s\n", v, sp->from_sopatt); VG_(printf)( "%swas not found whilst processing\n", v); VG_(printf)( "%ssymbols from the object with soname: %s\n", v, VG_(DebugInfo_get_soname)(di)); VG_(printf)( "%s\n", v); for (strp = sp->mandatory; *strp; strp++) VG_(printf)( "%s%s\n", v, *strp); VG_(printf)( "%s\n", v); VG_(printf)( "%sCannot continue -- exiting now. Sorry.\n", v); VG_(printf)("\n"); VG_(exit)(1); } }