]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
New flag --require-text-symbol=:sopatt:fnpatt, to be used to check
authorJulian Seward <jseward@acm.org>
Sun, 9 May 2010 22:30:43 +0000 (22:30 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 9 May 2010 22:30:43 +0000 (22:30 +0000)
that specified shared objects contain specified symbols.  Along with a
couple of regtests that unfortunately will fail on MacOSX.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11125

14 files changed:
coregrind/m_main.c
coregrind/m_options.c
coregrind/m_redir.c
coregrind/pub_core_options.h
coregrind/pub_core_redir.h
docs/xml/manual-core.xml
none/tests/Makefile.am
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp
none/tests/require-text-symbol-1.stderr.exp [new file with mode: 0644]
none/tests/require-text-symbol-1.vgtest [new file with mode: 0644]
none/tests/require-text-symbol-2.stderr.exp-libcso6 [new file with mode: 0644]
none/tests/require-text-symbol-2.vgtest [new file with mode: 0644]
none/tests/require-text-symbol.c [new file with mode: 0644]

index b8569ed0602d47af12a78b0c1f7b2b5710aeca97..5c69df6b8e9081b41bb4401003455a2b2414dc8f 100644 (file)
@@ -55,6 +55,7 @@
 #include "pub_core_debuginfo.h"
 #include "pub_core_redir.h"
 #include "pub_core_scheduler.h"
+#include "pub_core_seqmatch.h"      // For VG_(string_match)
 #include "pub_core_signals.h"
 #include "pub_core_stacks.h"        // For VG_(register_stack)
 #include "pub_core_syswrap.h"
@@ -168,6 +169,9 @@ static void usage_NORETURN ( Bool debug_help )
 "    --kernel-variant=variant1,variant2,...  known variants: bproc [none]\n"
 "                              handle non-standard kernel variants\n"
 "    --show-emwarns=no|yes     show warnings about emulation limits? [no]\n"
+"    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the\n"
+"                              stated shared object doesn't have the stated\n"
+"                              text symbol.  Patterns can contain ? and *.\n"
 "\n";
 
    Char* usage2 = 
@@ -538,7 +542,8 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
 
       else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
          if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
-            VG_(message)(Vg_UserMsg, "Too many suppression files specified.\n");
+            VG_(message)(Vg_UserMsg,
+                         "Too many suppression files specified.\n");
             VG_(message)(Vg_UserMsg, 
                          "Increase VG_CLO_MAX_SFILES and recompile.\n");
             VG_(err_bad_option)(arg);
@@ -547,6 +552,39 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
          VG_(clo_n_suppressions)++;
       }
 
+      else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
+         if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
+            VG_(message)(Vg_UserMsg,
+                         "Too many --require-text-symbol= specifications.\n");
+            VG_(message)(Vg_UserMsg, 
+                         "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
+            VG_(err_bad_option)(arg);
+         }
+         /* String needs to be of the form C?*C?*, where C is any
+            character, but is the same both times.  Having it in this
+            form facilitates finding the boundary between the sopatt
+            and the fnpatt just by looking for the second occurrence
+            of C, without hardwiring any assumption about what C
+            is. */
+         Char patt[7];
+         Bool ok = True;
+         ok = tmp_str && VG_(strlen)(tmp_str) > 0;
+         if (ok) {
+           patt[0] = patt[3] = tmp_str[0];
+           patt[1] = patt[4] = '?';
+           patt[2] = patt[5] = '*';
+           patt[6] = 0;
+           ok = VG_(string_match)(patt, tmp_str);
+         }
+         if (!ok) {
+            VG_(message)(Vg_UserMsg,
+                         "Invalid --require-text-symbol= specification.\n");
+            VG_(err_bad_option)(arg);
+         }
+         VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
+         VG_(clo_n_req_tsyms)++;
+      }
+
       /* "stuvwxyz" --> stuvwxyz (binary) */
       else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
          Int j;
index 8162a48fee840a6e42159f461ee912983deb5322..d6aea74f0952b3280f0f397b2ebac7827cf7c4da 100644 (file)
@@ -84,6 +84,9 @@ Int    VG_(clo_backtrace_size) = 12;
 Char*  VG_(clo_sim_hints)      = NULL;
 Bool   VG_(clo_sym_offsets)    = False;
 Bool   VG_(clo_read_var_info)  = False;
+Int    VG_(clo_n_req_tsyms)    = 0;
+HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS];
+HChar* VG_(clo_require_text_symbol) = NULL;
 Bool   VG_(clo_run_libc_freeres) = True;
 Bool   VG_(clo_track_fds)      = False;
 Bool   VG_(clo_show_below_main)= False;
index b1ab3c9e7579d19994fbbd300889c46747b17668..124507ae53194a8463fe645eb686856fcf787749 100644 (file)
    platform-specific.
 
    The module is notified of redirection state changes by m_debuginfo.
-   That calls VG_(redir_notify_new_SegInfo) when a new SegInfo (shared
-   object symbol table, basically) appears.  Appearance of new symbols
-   can cause new (active) redirections to appear for two reasons: the
-   symbols in the new table may match existing redirection
-   specifications (see comments below), and because the symbols in the
-   new table may themselves supply new redirect specifications which
-   match existing symbols (or ones in the new table).
+   That calls VG_(redir_notify_new_DebugInfo) when a new DebugInfo
+   (shared object symbol table, basically) appears.  Appearance of new
+   symbols can cause new (active) redirections to appear for two
+   reasons: the symbols in the new table may match existing
+   redirection specifications (see comments below), and because the
+   symbols in the new table may themselves supply new redirect
+   specifications which match existing symbols (or ones in the new
+   table).
 
    Redirect specifications are really symbols with "funny" prefixes
    (_vgrZU_ and _vgrZZ_).  These names tell m_redir that the
@@ -86,8 +87,8 @@
    by VG_(maybe_Z_demangle).
 
    When a shared object is unloaded, this module learns of it via a
-   call to VG_(redir_notify_delete_SegInfo).  It then removes from its
-   tables all active redirections in any way associated with that
+   call to VG_(redir_notify_delete_DebugInfo).  It then removes from
+   its tables all active redirections in any way associated with that
    object, and tidies up the translation caches accordingly.
 
    That takes care of tracking the redirection state.  When a
    ===========================================================
    Incremental implementation:
 
-   When a new SegInfo appears:
+   When a new DebugInfo appears:
    - it may be the source of new specs
    - it may be the source of new matches for existing specs
    Therefore:
 
-   - (new Specs x existing SegInfos): scan all symbols in the new 
-     SegInfo to find new specs.  Each of these needs to be compared 
-     against all symbols in all the existing SegInfos to generate 
+   - (new Specs x existing DebugInfos): scan all symbols in the new
+     DebugInfo to find new specs.  Each of these needs to be compared
+     against all symbols in all the existing DebugInfos to generate
      new actives.
      
-   - (existing Specs x new SegInfo): scan all symbols in the SegInfo,
-     trying to match them to any existing specs, also generating
-     new actives.
+   - (existing Specs x new DebugInfo): scan all symbols in the
+     DebugInfo, trying to match them to any existing specs, also
+     generating new actives.
 
-   - (new Specs x new SegInfo): scan all symbols in the new SegInfo,
-     trying to match them against the new specs, to generate new
-     actives.
+   - (new Specs x new DebugInfo): scan all symbols in the new
+     DebugInfo, trying to match them against the new specs, to
+     generate new actives.
 
    - Finally, add new new specs to the current set of specs.
 
         else add (s,d) to Actives
              and discard (s,1) and (d,1)  (maybe overly conservative)
 
-   When a SegInfo disappears:
+   When a DebugInfo disappears:
    - delete all specs acquired from the seginfo
    - delete all actives derived from the just-deleted specs
    - if each active (s,d) deleted, discard (s,1) and (d,1)
@@ -234,8 +235,8 @@ typedef
    }
    Spec;
 
-/* Top-level data structure.  It contains a pointer to a SegInfo and
-   also a list of the specs harvested from that SegInfo.  Note that
+/* Top-level data structure.  It contains a pointer to a DebugInfo and
+   also a list of the specs harvested from that DebugInfo.  Note that
    seginfo is allowed to be NULL, meaning that the specs are
    pre-loaded ones at startup and are not associated with any
    particular seginfo. */
@@ -249,7 +250,7 @@ typedef
    TopSpec;
 
 /* This is the top level list of redirections.  m_debuginfo maintains
-   a list of SegInfos, and the idea here is to maintain a list with
+   a list of DebugInfos, and the idea here is to maintain a list with
    the same number of elements (in fact, with one more element, so as
    to record abovementioned preloaded specifications.) */
 static TopSpec* topSpecs = NULL;
@@ -298,6 +299,7 @@ static void   show_active ( HChar* left, Active* act );
 static void   handle_maybe_load_notifier( const UChar* soname, 
                                                 HChar* symbol, Addr addr );
 
+static void   handle_require_text_symbols ( DebugInfo* );
 
 /*------------------------------------------------------------*/
 /*--- NOTIFICATIONS                                        ---*/
@@ -422,7 +424,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
       }
    }
 
-   /* Ok.  Now specList holds the list of specs from the DebugInfo. 
+   /* Ok.  Now specList holds the list of specs from the DebugInfo.
       Build a new TopSpec, but don't add it to topSpecs yet. */
    newts = dinfo_zalloc("redir.rnnD.4", sizeof(TopSpec));
    vg_assert(newts);
@@ -471,6 +473,11 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
 
    if (VG_(clo_trace_redir))
       show_redir_state("after VG_(redir_notify_new_DebugInfo)");
+
+   /* Really finally (quite unrelated to all the above) check the
+      names in the module against any --require-text-symbol=
+      specifications we might have. */
+   handle_require_text_symbols(newsi);
 }
 
 #undef N_DEMANGLED
@@ -1123,6 +1130,7 @@ static Bool is_aix5_glink_idiom ( Addr sym_addr )
    return False;
 }
 
+
 /*------------------------------------------------------------*/
 /*--- NOTIFY-ON-LOAD FUNCTIONS                             ---*/
 /*------------------------------------------------------------*/
@@ -1160,6 +1168,114 @@ void handle_maybe_load_notifier( const UChar* soname,
 }
 
 
+/*------------------------------------------------------------*/
+/*--- REQUIRE-TEXT-SYMBOL HANDLING                         ---*/
+/*------------------------------------------------------------*/
+
+/* In short: check that the currently-being-loaded object has text
+   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 ( DebugInfo* di )
+{
+   /* First thing to do is figure out which, if any,
+      --require-text-symbol specification strings apply to this
+      object.  Most likely none do, since it is not expected to
+      frequently be used.  Work through the list of specs and
+      accumulate in fnpatts[] the fn patterns that pertain to this
+      object. */
+   HChar* fnpatts[VG_CLO_MAX_REQ_TSYMS];
+   Int    fnpatts_used = 0;
+   Int    i, j;
+   const HChar* di_soname = VG_(DebugInfo_get_soname)(di);
+   vg_assert(di_soname); // must be present
+
+   VG_(memset)(&fnpatts, 0, sizeof(fnpatts));
+
+   vg_assert(VG_(clo_n_req_tsyms) >= 0);
+   vg_assert(VG_(clo_n_req_tsyms) <= VG_CLO_MAX_REQ_TSYMS);
+   for (i = 0; i < VG_(clo_n_req_tsyms); i++) {
+      HChar* spec = VG_(clo_req_tsyms)[i];
+      vg_assert(spec && VG_(strlen)(spec) >= 4);
+      // clone the spec, so we can stick a zero at the end of the sopatt
+      spec = VG_(strdup)("m_redir.hrts.1", spec);
+      HChar sep = spec[0];
+      HChar* sopatt = &spec[1];
+      HChar* fnpatt = VG_(strchr)(sopatt, sep);
+      // the initial check at clo processing in time in m_main
+      // should ensure this.
+      vg_assert(fnpatt && *fnpatt == sep);
+      *fnpatt = 0;
+      fnpatt++;
+      if (VG_(string_match)(sopatt, di_soname))
+         fnpatts[fnpatts_used++]
+            = VG_(strdup)("m_redir.hrts.2", fnpatt);
+      VG_(free)(spec);
+   }
+
+   if (fnpatts_used == 0)
+      return;  /* no applicable spec strings */
+
+   /* So finally, fnpatts[0 .. fnpatts_used - 1] contains the set of
+      (patterns for) text symbol names that must be found in this
+      object, in order to continue.  That is, we must find at least
+      one text symbol name that matches each pattern, else we must
+      abort the run. */
+
+   if (0) VG_(printf)("for %s\n", di_soname);
+   for (i = 0; i < fnpatts_used; i++)
+      if (0) VG_(printf)("   fnpatt: %s\n", fnpatts[i]);
+
+   /* For each spec, look through the syms to find one that matches.
+      This isn't terribly efficient but it happens rarely, so no big
+      deal. */
+   for (i = 0; i < fnpatts_used; i++) {
+      Bool   found = False;
+      HChar* fnpatt = fnpatts[i];
+      Int    nsyms = VG_(DebugInfo_syms_howmany)(di);
+      for (j = 0; j < nsyms; j++) {
+         Bool   isText   = False;
+         HChar* sym_name = NULL;
+         VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL,
+                                     NULL, &sym_name, &isText, NULL );
+         /* ignore data symbols */
+         if (0) VG_(printf)("QQQ %s\n", sym_name);
+         vg_assert(sym_name);
+         if (!isText)
+            continue;
+         if (VG_(string_match)(fnpatt, sym_name)) {
+            found = True;
+            break;
+         }
+      }
+
+      if (!found) {
+         HChar* v = "valgrind:  ";
+         VG_(printf)("\n");
+         VG_(printf)(
+         "%sFatal error at when loading library with soname\n", v);
+         VG_(printf)(
+         "%s   %s\n", v, di_soname);
+         VG_(printf)(
+         "%sCannot find any text symbol with a name "
+         "that matches the pattern\n", v);
+         VG_(printf)("%s   %s\n", v, fnpatt);
+         VG_(printf)("%sas required by a --require-text-symbol= "
+         "specification.\n", v);
+         VG_(printf)("\n");
+         VG_(printf)(
+         "%sCannot continue -- exiting now.\n", v);
+         VG_(printf)("\n");
+         VG_(exit)(1);
+      }
+   }
+
+   /* All required specs were found.  Just free memory and return. */
+   for (i = 0; i < fnpatts_used; i++)
+      VG_(free)(fnpatts[i]);
+}
+
+
 /*------------------------------------------------------------*/
 /*--- SANITY/DEBUG                                         ---*/
 /*------------------------------------------------------------*/
index fa358eb2230432c9889fb8883f13d2953ecb8bb6..716a124c06fe1e7bf33a240f98711cea17e371f8 100644 (file)
@@ -42,6 +42,9 @@
 /* The max number of suppression files. */
 #define VG_CLO_MAX_SFILES 100
 
+/* The max number of --require-text-symbol= specification strings. */
+#define VG_CLO_MAX_REQ_TSYMS 100
+
 /* Should we stop collecting errors if too many appear?  default: YES */
 extern Bool  VG_(clo_error_limit);
 /* Alternative exit code to hand to parent if errors were found.
@@ -82,6 +85,7 @@ extern Bool  VG_(clo_time_stamp);
 
 /* The file descriptor to read for input.  default: 0 == stdin */
 extern Int   VG_(clo_input_fd);
+
 /* The number of suppression files specified. */
 extern Int   VG_(clo_n_suppressions);
 /* The names of the suppression files. */
@@ -125,6 +129,39 @@ extern Bool VG_(clo_sym_offsets);
 /* Read DWARF3 variable info even if tool doesn't ask for it? */
 extern Bool VG_(clo_read_var_info);
 
+/* An array of strings harvested from --require-text-symbol= 
+   flags.
+
+   Each string specifies a pair: a soname pattern and a text symbol
+   name pattern, separated by a colon.  The patterns can be written
+   using the normal "?" and "*" wildcards.  For example:
+   ":*libc.so*:foo?bar".
+
+   These flags take effect when reading debuginfo from objects.  If an
+   object is loaded and the object's soname matches the soname
+   component of one of the specified pairs, then Valgrind will examine
+   all the text symbol names in the object.  If none of them match the
+   symbol name component of that same specification, then the run is
+   aborted, with an error message.
+
+   The purpose of this is to support reliable usage of marked-up
+   libraries.  For example, suppose we have a version of GCC's
+   libgomp.so which has been marked up with annotations to support
+   Helgrind.  It is only too easy and confusing to load the 'wrong'
+   libgomp.so into the application.  So the idea is: add a text symbol
+   in the marked-up library (eg), "annotated_for_helgrind_3_6", and
+   then give the flag
+
+     --require-text-symbol=:*libgomp*so*:annotated_for_helgrind_3_6
+
+   so that when libgomp.so is loaded, we scan the symbol table, and if
+   the symbol isn't present the run is aborted, rather than continuing
+   silently with the un-marked-up library.  Note that you should put
+   the entire flag in quotes to stop shells messing up the * and ?
+   wildcards. */
+extern Int    VG_(clo_n_req_tsyms);
+extern HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS];
+
 /* Track open file descriptors? */
 extern Bool  VG_(clo_track_fds);
 
index 817699aca4617f185a6c368b13986e8cd3ca7be9..8bd12f7f3df49f23679299623f9d5104242d5a60 100644 (file)
 
 //--------------------------------------------------------------------
 // PURPOSE: This module deals with:
+//
 // - code replacement: intercepting calls to client functions, and
 //   pointing them to a different piece of code.
+//
 // - loading notification: telling the core where certain client-space
 //   functions are when they get loaded.
+//
 // - function wrapping: add calls to code before and after client
 //   functions execute, for inspection and/or modification.
+//
+// - checking of --require-text-symbol= specifications: when a new
+//   object is loaded, its symbol table is examined, and if a symbol
+//   (as required by the specifications) is not found then the run
+//   is aborted.  See comment by VG_(clo_n_req_tsyms) in
+//   pub_core_options.h for background.  This doesn't have anything
+//   to do with function intercepting or wrapping, but it does have
+//   to do with examining all symbols at object load time, so this
+//   module seems like a logical place to put it.
+//
 //--------------------------------------------------------------------
 
 #include "pub_tool_redir.h"
index 24ab6aeea3a97247bcfc4151e65679eeaa02145f..724dac99e5d534b074283c06a10a48604abcf5e0 100644 (file)
@@ -1501,6 +1501,55 @@ need to use these.</para>
    </listitem>
   </varlistentry>
 
+  <varlistentry id="opt.require-text-symbol"
+        xreflabel="--require-text-symbol">
+    <term>
+      <option><![CDATA[--require-text-symbol=:sonamepatt:fnnamepatt]]></option>
+    </term>
+    <listitem>
+      <para>When a shared object whose soname
+      matches <varname>sonamepatt</varname> is loaded into the
+      process, examine all the text symbols it exports.  If none of
+      those match <varname>fnnamepatt</varname>, print an error
+      message and abandon the run.  This makes it possible to ensure
+      that the run does not continue unless a given shared object
+      contains a particular function name.
+      </para>
+      <para>
+      Both <varname>sonamepatt</varname> and
+      <varname>fnnamepatt</varname> can be written using the usual
+      <varname>?</varname> and <varname>*</varname> wildcards.  For
+      example: <varname>":*libc.so*:foo?bar"</varname>.  You may use
+      characters other than a colon to separate the two patterns.  It
+      is only important that the first character and the separator
+      character are the same.  For example, the above example could
+      also be written <varname>"Q*libc.so*Qfoo?bar"</varname>.
+      Multiple <varname> --require-text-symbol</varname> flags are
+      allowed, in which case shared objects that are loaded into
+      the process will be checked against all of them.
+      </para>
+      <para>
+      The purpose of this is to support reliable usage of marked-up
+      libraries.  For example, suppose we have a version of GCC's
+      <varname>libgomp.so</varname> which has been marked up with
+      annotations to support Helgrind.  It is only too easy and
+      confusing to load the wrong, un-annotated
+      <varname>libgomp.so</varname> into the application.  So the idea
+      is: add a text symbol in the marked-up library, for
+      example <varname>annotated_for_helgrind_3_6</varname>, and then
+      give the flag
+      <varname>--require-text-symbol=:*libgomp*so*:annotated_for_helgrind_3_6</varname>
+      so that when <varname>libgomp.so</varname> is loaded, Valgrind
+      scans its symbol table, and if the symbol isn't present the run
+      is aborted, rather than continuing silently with the
+      un-marked-up library.  Note that you should put the entire flag
+      in quotes to stop shells expanding up the <varname>*</varname>
+      and <varname>?</varname> wildcards.
+      </para>
+   </listitem>
+  </varlistentry>
+
+
 </variablelist>
 <!-- end of xi:include in the manpage -->
 
index ff28e2a1fa777fbe16490d7533dd5dfd887fc19e..a299436fca5867d8ddb5db85895800e64f15c63d 100644 (file)
@@ -113,6 +113,10 @@ EXTRA_DIST = \
        rcrl.stderr.exp rcrl.stdout.exp rcrl.vgtest \
        readline1.stderr.exp readline1.stdout.exp \
        readline1.vgtest \
+       require-text-symbol-1.vgtest \
+               require-text-symbol-1.stderr.exp
+       require-text-symbol-2.vgtest \
+               require-text-symbol-2.stderr.exp-libcso6 \
        res_search.stderr.exp res_search.stdout.exp res_search.vgtest \
        resolv.stderr.exp resolv.stdout.exp resolv.vgtest \
        rlimit_nofile.stderr.exp rlimit_nofile.stdout.exp rlimit_nofile.vgtest \
@@ -166,7 +170,9 @@ check_PROGRAMS = \
        pth_atfork1 pth_blockedsig pth_cancel1 pth_cancel2 pth_cvsimple \
        pth_empty pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \
        pth_stackalign \
-       rcrl readline1 res_search resolv \
+       rcrl readline1 \
+       require-text-symbol \
+       res_search resolv \
        rlimit_nofile selfrun sem semlimit sha1_test \
        shortpush shorts stackgrowth sigstackgrowth \
        syscall-restart1 syscall-restart2 \
index 19dfa1f90ade0d13c2ca01751a46ec33c029b1ae..c06b53fd3264d914ba3c70c7b564eed237967af9 100644 (file)
@@ -57,6 +57,9 @@ usage: valgrind [options] prog-and-args
     --kernel-variant=variant1,variant2,...  known variants: bproc [none]
                               handle non-standard kernel variants
     --show-emwarns=no|yes     show warnings about emulation limits? [no]
+    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
+                              stated shared object doesn't have the stated
+                              text symbol.  Patterns can contain ? and *.
 
   user options for Nulgrind:
     (none)
index ba700bd37cd90e785797f3778c233097f2b68800..60e0328f2832f8b72d55474606dd47075bd22bac 100644 (file)
@@ -57,6 +57,9 @@ usage: valgrind [options] prog-and-args
     --kernel-variant=variant1,variant2,...  known variants: bproc [none]
                               handle non-standard kernel variants
     --show-emwarns=no|yes     show warnings about emulation limits? [no]
+    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
+                              stated shared object doesn't have the stated
+                              text symbol.  Patterns can contain ? and *.
 
   user options for Nulgrind:
     (none)
diff --git a/none/tests/require-text-symbol-1.stderr.exp b/none/tests/require-text-symbol-1.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/require-text-symbol-1.vgtest b/none/tests/require-text-symbol-1.vgtest
new file mode 100644 (file)
index 0000000..fca0092
--- /dev/null
@@ -0,0 +1,2 @@
+prog: require-text-symbol
+vgopts: -q "--require-text-symbol=:*libc.so*:strl?n"
diff --git a/none/tests/require-text-symbol-2.stderr.exp-libcso6 b/none/tests/require-text-symbol-2.stderr.exp-libcso6
new file mode 100644 (file)
index 0000000..0d66f2d
--- /dev/null
@@ -0,0 +1,9 @@
+
+valgrind:  Fatal error at when loading library with soname
+valgrind:     libc.so.6
+valgrind:  Cannot find any text symbol with a name that matches the pattern
+valgrind:     doesntexist
+valgrind:  as required by a --require-text-symbol= specification.
+
+valgrind:  Cannot continue -- exiting now.
+
diff --git a/none/tests/require-text-symbol-2.vgtest b/none/tests/require-text-symbol-2.vgtest
new file mode 100644 (file)
index 0000000..48b553b
--- /dev/null
@@ -0,0 +1,2 @@
+prog: require-text-symbol
+vgopts: -q "--require-text-symbol=:*libc.so*:doesntexist"
diff --git a/none/tests/require-text-symbol.c b/none/tests/require-text-symbol.c
new file mode 100644 (file)
index 0000000..15b827c
--- /dev/null
@@ -0,0 +1,8 @@
+
+/* Doesn't do anything.  The point of this is to test for the presence
+   of a couple of symbols in libc.so.  See the .vgtest files. */
+
+int main ( void )
+{
+  return 0;
+}