[gdb/testsuite] use args as lib list for jit-elf tests
authorMihails Strasuns via Gdb-patches <gdb-patches@sourceware.org>
Tue, 31 Mar 2020 17:13:51 +0000 (19:13 +0200)
committerMihails Strasuns <mihails.strasuns@intel.com>
Tue, 12 May 2020 07:52:46 +0000 (09:52 +0200)
Old usage: jit-elf-main lib.so 2
New usage: jit-elf-main lib.so.1 lib.so.2

Refactoring necessary to support running tests over multiple jit
binaries rather than mapping the same binary muultiple times.

gdb/testsuite/ChangeLog:

2020-02-18  Mihails Strasuns  <mihails.strasuns@intel.com>

* gdb.base/jit-elf-main.c: Read lib list from argc/argv.
* gdb.base/jit-elf.exp: Compile N jit libraries and use the list.
* gdb.base/jit-elf-so.exp: Ditto.

gdb/testsuite/gdb.base/jit-elf-main.c
gdb/testsuite/gdb.base/jit-elf-so.exp
gdb/testsuite/gdb.base/jit-elf.exp

index 4eaac514b537e4954fb18b6674306ddb8b63a258..acfd17d417940649728b35802adf502c263e04ce 100644 (file)
@@ -45,9 +45,9 @@
 #endif /* !ElfW  */
 
 static void
-usage (const char *const argv0)
+usage (void)
 {
-  fprintf (stderr, "Usage: %s library [count]\n", argv0);
+  fprintf (stderr, "Usage: jit-elf-main libraries...\n");
   exit (1);
 }
 
@@ -106,49 +106,39 @@ int mypid;
 int
 MAIN (int argc, char *argv[])
 {
-  /* These variables are here so they can easily be set from jit.exp.  */
-  const char *libname = NULL;
-  int count = 0, i, fd;
-  struct stat st;
-
+  int i;
   alarm (300);
+  /* Used as backing storage for GDB to populate argv.  */
+  char *fake_argv[10];
 
   mypid = getpid ();
-
-  count = count;  /* gdb break here 0  */
+  /* gdb break here 0  */
 
   if (argc < 2)
     {
-      usage (argv[0]);
+      usage ();
       exit (1);
     }
 
-  if (libname == NULL)
-    /* Only set if not already set from GDB.  */
-    libname = argv[1];
-
-  if (argc > 2 && count == 0)
-    /* Only set if not already set from GDB.  */
-    count = atoi (argv[2]);
-
-  printf ("%s:%d: libname = %s, count = %d\n", __FILE__, __LINE__,
-         libname, count);
-
-  if ((fd = open (libname, O_RDONLY)) == -1)
+  for (i = 1; i < argc; ++i)
     {
-      fprintf (stderr, "open (\"%s\", O_RDONLY): %s\n", libname,
-              strerror (errno));
-      exit (1);
-    }
+      struct stat st;
+      int fd;
 
-  if (fstat (fd, &st) != 0)
-    {
-      fprintf (stderr, "fstat (\"%d\"): %s\n", fd, strerror (errno));
-      exit (1);
-    }
+      printf ("%s:%d: libname = %s, i = %d\n", __FILE__, __LINE__, argv[i], i);
+      if ((fd = open (argv[i], O_RDONLY)) == -1)
+       {
+         fprintf (stderr, "open (\"%s\", O_RDONLY): %s\n", argv[i],
+                  strerror (errno));
+         exit (1);
+       }
+
+      if (fstat (fd, &st) != 0)
+       {
+         fprintf (stderr, "fstat (\"%d\"): %s\n", fd, strerror (errno));
+         exit (1);
+       }
 
-  for (i = 0; i < count; ++i)
-    {
       const void *const addr = mmap (0, st.st_size, PROT_READ|PROT_WRITE,
                                     MAP_PRIVATE, fd, 0);
       struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
index 0f05221a62a213138c2d5b5351582f70d3d91ab6..4f50c443f0f31494cd0fe9fb9446b405e09b704c 100644 (file)
@@ -26,48 +26,105 @@ if {[get_compiler_info]} {
     return 1
 }
 
+# The "real" main of this test, which loads jit-elf-main
+# as a shared library.
+set main_loader_basename jit-elf-dlmain
+set main_loader_srcfile ${srcdir}/${subdir}/${main_loader_basename}.c
+set main_loader_binfile [standard_output_file ${main_loader_basename}]
+
+# The main code that loads and registers JIT objects.
+set main_solib_basename jit-elf-main
+set main_solib_srcfile ${srcdir}/${subdir}/${main_solib_basename}.c
+set main_solib_binfile [standard_output_file ${main_solib_basename}.so]
+
+# The shared library that gets loaded as JIT objects.
+set jit_solib_basename jit-elf-solib
+set jit_solib_srcfile ${srcdir}/${subdir}/${jit_solib_basename}.c
+
+# Compile jit-elf-main.c as a shared library.
 #
-# test running programs
+# OPTIONS is passed to gdb_compile when compiling the program.
 #
+# On success, return 0.
+# On failure, return -1.
+proc compile_jit_elf_main_as_so {options} {
+    global main_solib_srcfile main_solib_binfile
+    set options [concat $options debug]
+
+    if { [gdb_compile_shlib ${main_solib_srcfile} ${main_solib_binfile} \
+           $options] != "" } {
+       untested "failed to compile ${main_solib_basename}.c as a shared library"
+       return -1
+    }
 
-set testfile jit-elf-dlmain
-set srcfile ${testfile}.c
-set binfile [standard_output_file ${testfile}]
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug shlib_load}] != "" } {
-    untested "failed to compile"
-    return -1
+    return 0
 }
 
-set testfile2 jit-elf-main
-set srcfile2 ${testfile2}.c
-set binfile2 [standard_output_file ${testfile2}.so]
-set binfile2_dlopen [shlib_target_file ${testfile2}.so]
-if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcfile2}" ${binfile2} {debug additional_flags="-DMAIN=jit_dl_main"}] != "" } {
-    untested "failed to compile main shared library"
-    return -1
+# Compile the testcase shared library loader.
+#
+# OPTIONS is passed to gdb_compile when compiling the binary.
+#
+# On success, return 0.
+# On failure, return -1.
+proc compile_jit_dlmain {options} {
+    global main_loader_srcfile main_loader_binfile
+    set options [concat $options debug]
+
+    if { [gdb_compile ${main_loader_srcfile} ${main_loader_binfile} \
+           executable $options] != "" } {
+       untested "failed to compile ${main_loader_basename}.c as an executable"
+       return -1
+    }
+
+    return 0
 }
 
-set solib_testfile "jit-elf-solib"
-set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c"
-set solib_binfile [standard_output_file ${solib_testfile}.so]
-set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}.so"
+# Compile jit-elf-solib.c as a shared library in multiple copies and
+# upload them to the target.
+#
+# On success, return a list of target path to the shared libraries.
+# On failure, return -1.
+proc compile_and_download_n_jit_so {count} {
+    global jit_solib_basename jit_solib_srcfile
+    set binfiles_target {}
+
+    for {set i 1} {$i <= $count} {incr i} {
+       set binfile [standard_output_file ${jit_solib_basename}.$i.so]
+
+       # Note: compiling without debug info by default: some test
+       # do symbol renaming by munging on ELF symbol table, and that
+       # wouldn't work for .debug sections.  Also, output for "info
+       # function" changes when debug info is present.
+       if { [gdb_compile_shlib ${jit_solib_srcfile} ${binfile} {}] != "" } {
+           untested "failed to compile ${jit_solib_basename}.c as a shared library"
+           return -1
+       }
 
-# Note: compiling without debug info: the library goes through symbol
-# renaming by munging on its symbol table, and that wouldn't work for .debug
-# sections.  Also, output for "info function" changes when debug info is resent.
-if { [gdb_compile_shlib ${solib_srcfile} ${solib_binfile} {}] != "" } {
-    untested "failed to compile jit shared library"
-    return -1
+       set path [gdb_remote_download target ${binfile}]
+       lappend binfiles_target $path
+    }
+
+    return $binfiles_target
 }
 
-set solib_binfile_target [gdb_remote_download target ${solib_binfile}]
+# Run $main_loader_binfile and load $main_solib_binfile in
+# GDB.  Check jit-related debug output and matches `info function`
+# output for a jit loaded function using MATCH_STR.
+#
+# SOLIB_BINFILES_TARGETS is a list of shared libraries to pass
+# as arguments when running $main_loader_binfile.
+# MATCH_STR is a regular expression that output of `info function`
+# must match.
+proc one_jit_test {solib_binfiles_target match_str} {
+    set count [llength $solib_binfiles_target]
 
-proc one_jit_test {count match_str} {
     with_test_prefix "one_jit_test-$count" {
-       global verbose testfile srcfile2 binfile2 binfile2_dlopen solib_binfile_target solib_binfile_test_msg
+       global verbose
+       global main_loader_binfile main_loader_srcfile
+       global main_solib_binfile main_solib_srcfile
 
-       clean_restart $testfile
-       gdb_load_shlib $binfile2
+       clean_restart $main_loader_binfile
+       gdb_load_shlib $main_solib_binfile
 
        # This is just to help debugging when things fail
        if {$verbose > 0} {
@@ -79,23 +136,32 @@ proc one_jit_test {count match_str} {
            return
        }
 
-       gdb_breakpoint [gdb_get_line_number "break here before-dlopen" ]
+       gdb_breakpoint [gdb_get_line_number "break here before-dlopen" \
+                           $main_loader_srcfile]
        gdb_continue_to_breakpoint "break here before-dlopen"
-       # Poke desired values directly into inferior instead of using "set args"
-       # because "set args" does not work under gdbserver.
-       gdb_test_no_output "set var jit_libname = \"$binfile2_dlopen\""
+       gdb_test_no_output "set var jit_libname = \"$main_solib_binfile\"" \
+           "setting library name"
 
-       gdb_breakpoint [gdb_get_line_number "break here after-dlopen" ]
+       gdb_breakpoint [gdb_get_line_number "break here after-dlopen" \
+                       $main_loader_srcfile]
        gdb_continue_to_breakpoint "break here after-dlopen"
 
-       gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here 0} $srcfile2]"
+       set line [gdb_get_line_number {break here 0} $main_solib_srcfile]
+       gdb_breakpoint "$main_solib_srcfile:$line"
        gdb_continue_to_breakpoint "break here 0"
 
-       gdb_test_no_output "set var argc = 2"
-       gdb_test_no_output "set var libname = \"$solib_binfile_target\"" "set var libname = \"$solib_binfile_test_msg\""
-       gdb_test_no_output "set var count = $count"
+       # Poke desired values directly into inferior instead of using "set args"
+       # because "set args" does not work under gdbserver.
+       gdb_test_no_output "set var argc=[expr $count + 1]" "forging argc"
+       gdb_test_no_output "set var argv=fake_argv" "forging argv"
+       for {set i 1} {$i <= $count} {incr i} {
+           set binfile_target [lindex $solib_binfiles_target [expr $i-1]]
+           gdb_test_no_output "set var argv\[$i\]=\"${binfile_target}\"" \
+               "forging argv\[$i\]"
+       }
 
-       gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here 1} $srcfile2]"
+       set line [gdb_get_line_number {break here 1} $main_solib_srcfile]
+       gdb_breakpoint "$main_solib_srcfile:$line"
        gdb_continue_to_breakpoint "break here 1"
 
        gdb_test "info function jit_function" "$match_str"
@@ -106,8 +172,10 @@ proc one_jit_test {count match_str} {
            gdb_test "maintenance info break"
        }
 
-       gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here 2} $srcfile2]"
+       set line [gdb_get_line_number {break here 2} $main_solib_srcfile]
+       gdb_breakpoint "$main_solib_srcfile:$line"
        gdb_continue_to_breakpoint "break here 2"
+
        # All jit librares must have been unregistered
        gdb_test "info function jit_function" \
            "All functions matching regular expression \"jit_function\":" \
@@ -115,12 +183,31 @@ proc one_jit_test {count match_str} {
     }
 }
 
-one_jit_test 1 "${hex}  jit_function_0000"
-one_jit_test 2 "${hex}  jit_function_0000\[\r\n\]+${hex}  jit_function_0001"
+# Compile the main code (which loads the JIT objects) as a shared library.
+if { [compile_jit_elf_main_as_so {additional_flags="-DMAIN=jit_dl_main"}] < 0 } {
+    return
+}
+
+# Compile the "real" main for this test.
+if { [compile_jit_dlmain {shlib_load}] < 0 } {
+    return
+}
 
-# We don't intend to load the .so as a JIT debuginfo reader, but we
-# need some handy file name for a completion test.
-gdb_test \
-    "complete jit-reader-load [standard_output_file ${solib_testfile}.s]" \
-    "jit-reader-load $solib_binfile" \
-    "test jit-reader-load filename completion"
+# Compile two shared libraries to use as JIT objects.
+set jit_solibs_target [compile_and_download_n_jit_so 2]
+if { $jit_solibs_target == -1 } {
+    return
+}
+
+one_jit_test [lindex $jit_solibs_target 0] "${hex}  jit_function_0001"
+one_jit_test $jit_solibs_target "${hex}  jit_function_0001\[\r\n\]+${hex}  jit_function_0002"
+
+foreach solib $jit_solibs_target {
+    # We don't intend to load the .so as a JIT debuginfo reader, but we
+    # need some handy file name for a completion test.
+    set input [string range $solib 0 [expr { [string length $solib] - 2 }]]
+    gdb_test \
+       "complete jit-reader-load [standard_output_file $input]" \
+       "jit-reader-load $solib" \
+       "test jit-reader-load filename completion [file tail $solib]"
+}
index 71d3e37dfb82b2f07ee89b8edba595dfc63e52c7..98da57bd50f0c29f2ef19818ff80b33d8f0f006a 100644 (file)
@@ -23,48 +23,70 @@ if {[get_compiler_info]} {
     return 1
 }
 
-# Compile the testcase program and library.  BINSUFFIX is the suffix
-# to append to the program and library filenames, to make them unique
-# between invocations.  OPTIONS is passed to gdb_compile when
-# compiling the program.
-
-proc compile_jit_test {testname binsuffix options} {
-    global testfile srcfile binfile srcdir subdir
-    global solib_testfile solib_srcfile solib_binfile solib_binfile_test_msg
-    global solib_binfile_target
-
-    set testfile jit-elf-main
-    set srcfile ${testfile}.c
-    set binfile [standard_output_file $testfile$binsuffix]
-    if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
-             executable [concat debug $options]] != "" } {
-       untested $testname
-       return -1
-    }
+# The main code that loads and registers JIT objects.
+set main_basename jit-elf-main
+set main_srcfile ${srcdir}/${subdir}/${main_basename}.c
+set main_binfile [standard_output_file ${main_basename}]
 
-    set solib_testfile "jit-elf-solib"
-    set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c"
-    set solib_binfile [standard_output_file ${solib_testfile}$binsuffix.so]
-    set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}$binsuffix.so"
-
-    # Note: compiling without debug info: the library goes through
-    # symbol renaming by munging on its symbol table, and that
-    # wouldn't work for .debug sections.  Also, output for "info
-    # function" changes when debug info is present.
-    if { [gdb_compile_shlib ${solib_srcfile} ${solib_binfile} {-fPIC}] != "" } {
-       untested $testname
-       return -1
-    }
+# The shared library that gets loaded as JIT objects.
+set jit_solib_basename jit-elf-solib
+set jit_solib_srcfile ${srcdir}/${subdir}/${jit_solib_basename}.c
 
-    set solib_binfile_target [gdb_remote_download target ${solib_binfile}]
+# Compile jit-elf-main.c as an executable.
+#
+# BINSUFFIX is appended to the binary name.
+# OPTIONS is passed to gdb_compile when compiling the program.
+#
+# On success, return 0.
+# On failure, return -1.
+proc compile_jit_main {binsuffix options} {
+    global main_binfile main_srcfile main_basename
+
+    set binfile ${main_binfile}${binsuffix}
+    set options [concat $options debug]
+
+    if { [gdb_compile ${main_srcfile} ${binfile} \
+         executable $options] != "" } {
+             untested "failed to compile ${main_basename}.c"
+             return -1
+    }
 
     return 0
 }
 
+# Compile jit-elf-solib.c as a shared library in multiple copies and
+# upload them to the target.
+#
+# On success, return a list of target paths to the shared libraries.
+# On failure, return -1.
+proc compile_and_download_n_jit_so {count} {
+    global jit_solib_basename jit_solib_srcfile
+    set binfiles_target {}
+
+    for {set i 1} {$i <= $count} {incr i} {
+       set binfile [standard_output_file ${jit_solib_basename}.$i.so]
+
+       # Note: compiling without debug info by default: some test
+       # do symbol renaming by munging on ELF symbol table, and that
+       # wouldn't work for .debug sections.  Also, output for "info
+       # function" changes when debug info is present.
+       if { [gdb_compile_shlib ${jit_solib_srcfile} ${binfile} {}] != "" } {
+           untested "failed to compile ${jit_solib_basename}.c as a shared library"
+           return -1
+       }
+
+       set path [gdb_remote_download target ${binfile}]
+       lappend binfiles_target $path
+    }
+
+    return $binfiles_target
+}
+
 # Detach, restart GDB, and re-attach to the program.
 
 proc clean_reattach {} {
-    global decimal gdb_prompt srcfile testfile
+    global decimal gdb_prompt
+    global main_binfile main_srcfile
 
     # Get PID of test program.
     set testpid -1
@@ -79,11 +101,11 @@ proc clean_reattach {} {
     gdb_test_no_output "set var wait_for_gdb = 1"
     gdb_test "detach" "Detaching from .*"
 
-    clean_restart $testfile
+    clean_restart ${main_binfile}
 
     set test "attach"
     gdb_test_multiple "attach $testpid" "$test" {
-       -re "Attaching to program.*.*main.*at .*$srcfile:.*$gdb_prompt $" {
+       -re "Attaching to program.*.*main.*at .*$main_srcfile:.*$gdb_prompt $" {
            pass "$test"
        }
     }
@@ -94,7 +116,9 @@ proc clean_reattach {} {
 # Continue to LOCATION in the program.  If REATTACH, detach and
 # re-attach to the program from scratch.
 proc continue_to_test_location {location reattach} {
-    gdb_breakpoint [gdb_get_line_number $location]
+    global main_srcfile
+
+    gdb_breakpoint [gdb_get_line_number $location $main_srcfile]
     gdb_continue_to_breakpoint $location
     if {$reattach} {
        with_test_prefix "$location" {
@@ -103,11 +127,14 @@ proc continue_to_test_location {location reattach} {
     }
 }
 
-proc one_jit_test {count match_str reattach} {
+proc one_jit_test {jit_solibs_target match_str reattach} {
+    set count [llength $jit_solibs_target]
+
     with_test_prefix "one_jit_test-$count" {
-       global verbose testfile solib_binfile_target solib_binfile_test_msg
+       global verbose
+       global main_binfile main_srcfile
 
-       clean_restart $testfile
+       clean_restart ${main_binfile}
 
        # This is just to help debugging when things fail
        if {$verbose > 0} {
@@ -119,14 +146,20 @@ proc one_jit_test {count match_str reattach} {
            return
        }
 
-       gdb_breakpoint [gdb_get_line_number "break here 0"]
-       gdb_continue_to_breakpoint "break here 0"
-
        # Poke desired values directly into inferior instead of using "set args"
        # because "set args" does not work under gdbserver.
-       gdb_test_no_output "set var argc = 2"
-       gdb_test_no_output "set var libname = \"$solib_binfile_target\"" "set var libname = \"$solib_binfile_test_msg\""
-       gdb_test_no_output "set var count = $count"
+       incr count
+       gdb_test_no_output "set var argc=$count" "forging argc"
+       gdb_test_no_output "set var argv=fake_argv" "forging argv"
+       for {set i 1} {$i < $count} {incr i} {
+           set jit_solib_target [lindex $jit_solibs_target [expr $i-1]]
+           gdb_test_no_output "set var argv\[$i\]=\"${jit_solib_target}\"" \
+               "forging argv\[$i\]"
+       }
+
+       gdb_breakpoint [gdb_get_line_number "break here 0" $main_srcfile]
+       gdb_continue_to_breakpoint "break here 0"
+
 
        continue_to_test_location "break here 1" $reattach
 
@@ -146,31 +179,31 @@ proc one_jit_test {count match_str reattach} {
     }
 }
 
-if {[compile_jit_test jit.exp "" {}] < 0} {
+# Compile two shared libraries to use as JIT objects.
+set jit_solibs_target [compile_and_download_n_jit_so 2]
+if { $jit_solibs_target == -1 } {
     return
 }
-one_jit_test 1 "${hex}  jit_function_0000" 0
-one_jit_test 2 "${hex}  jit_function_0000\[\r\n\]+${hex}  jit_function_0001" 0
+
+# Compile the main code (which loads the JIT objects).
+if { [compile_jit_main "" {}] == 0 } {
+    one_jit_test [lindex $jit_solibs_target 0] "${hex}  jit_function_0001" 0
+    one_jit_test $jit_solibs_target "${hex}  jit_function_0001\[\r\n\]+${hex}  jit_function_0002" 0
+}
 
 # Test attaching to an inferior with some JIT libraries already
 # registered.  We reuse the normal test, and detach/reattach at
 # specific interesting points.
 if {[can_spawn_for_attach]} {
-    if {[compile_jit_test "jit.exp attach tests" \
-            "-attach" {additional_flags=-DATTACH=1}] < 0} {
-       return
-    }
-
-    with_test_prefix attach {
-       one_jit_test 2 "${hex}  jit_function_0000\[\r\n\]+${hex}  jit_function_0001" 1
+    if { [compile_jit_main "-attach" {additional_flags=-DATTACH=1}] == 0 } {
+       with_test_prefix attach {
+           one_jit_test $jit_solibs_target "${hex}  jit_function_0001\[\r\n\]+${hex}  jit_function_0002" 1
+       }
     }
 }
 
-with_test_prefix PIE {
-    if {[compile_jit_test "jit.exp PIE tests" \
-            "-pie" {additional_flags=-fPIE ldflags=-pie}] < 0} {
-       return
+if { [compile_jit_main "-pie" {additional_flags=-fPIE ldflags=-pie}] == 0 } {
+    with_test_prefix PIE {
+       one_jit_test [lindex $jit_solibs_target 0] "${hex}  jit_function_0001" 0
     }
-
-    one_jit_test 1 "${hex}  jit_function_0000" 0
 }