[v3,4/9,gdb/testsuite] use args as lib list for jit-elf tests

Message ID 20200331171356.26126-4-mihails.strasuns@intel.com
State New
Headers show
Series
  • [v3,1/9,gdb/testsuite] allow more registers in reader test
Related show

Commit Message

Pedro Alves via Gdb-patches March 31, 2020, 5:13 p.m.
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

Change-Id: Ie8f85ec6358604c14557b0417d6621b2f8942033
Signed-off-by: Mihails Strasuns <mihails.strasuns@intel.com>

---
 gdb/testsuite/gdb.base/jit-elf-main.c |  55 +++++-------
 gdb/testsuite/gdb.base/jit-elf-so.exp | 115 ++++++++++++++++----------
 gdb/testsuite/gdb.base/jit-elf.exp    |  99 +++++++++++-----------
 3 files changed, 141 insertions(+), 128 deletions(-)

-- 
2.25.2

Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Gary Kershaw
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

Comments

Simon Marchi April 18, 2020, 2:58 a.m. | #1
On 2020-03-31 1:13 p.m., Mihails Strasuns via Gdb-patches wrote:
> @@ -106,49 +106,38 @@ 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);

> +  char* fake_argv[10]; // used as backing storage for GDB to populate argv


Space goes before the start: `char *fake_argv`.  For comments, please follow the
usual style:

- Capital letter and period (two spaces after the final period).
- On the line before, not the same line.
- /* */, not //

> @@ -146,31 +149,23 @@ proc one_jit_test {count match_str reattach} {

>      }

>  }

>  

> -if {[compile_jit_test jit.exp "" {}] < 0} {

> -    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_jit_main "" {}

> +compile_n_jit_so 2


I mentioned ealier: if we fail to compile the test program, we don't want to execute the rest
of the test case.  That's what the previous code did.  Can you keep that?

Simon
Pedro Alves via Gdb-patches April 20, 2020, 7:35 a.m. | #2
> -----Original Message-----

> From: Simon Marchi <simark@simark.ca>

> Sent: Saturday, April 18, 2020 4:58 AM

> To: Strasuns, Mihails <mihails.strasuns@intel.com>; gdb-

> patches@sourceware.org

> Subject: Re: [PATCH v3 4/9] [gdb/testsuite] use args as lib list for jit-elf tests



> > @@ -146,31 +149,23 @@ proc one_jit_test {count match_str reattach} {

> >      }

> >  }

> >

> > -if {[compile_jit_test jit.exp "" {}] < 0} {

> > -    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_jit_main "" {}

> > +compile_n_jit_so 2

> 

> I mentioned ealier: if we fail to compile the test program, we don't want to

> execute the rest of the test case.  That's what the previous code did.  Can

> you keep that?

> 

> Simon


I have added it as a separate patch in the series (see "[PATCH v3 9/9] [gdb/testsuite] handle compilation failures in jit-elf-helpers") as it seemed more incremental / easier to read.  Is that ok?

BR,
Mihails
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Gary Kershaw
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
Simon Marchi April 20, 2020, 1:08 p.m. | #3
On 2020-04-20 3:35 a.m., Strasuns, Mihails wrote:
>> -----Original Message-----

>> From: Simon Marchi <simark@simark.ca>

>> Sent: Saturday, April 18, 2020 4:58 AM

>> To: Strasuns, Mihails <mihails.strasuns@intel.com>; gdb-

>> patches@sourceware.org

>> Subject: Re: [PATCH v3 4/9] [gdb/testsuite] use args as lib list for jit-elf tests

> 

> 

>>> @@ -146,31 +149,23 @@ proc one_jit_test {count match_str reattach} {

>>>      }

>>>  }

>>>

>>> -if {[compile_jit_test jit.exp "" {}] < 0} {

>>> -    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_jit_main "" {}

>>> +compile_n_jit_so 2

>>

>> I mentioned ealier: if we fail to compile the test program, we don't want to

>> execute the rest of the test case.  That's what the previous code did.  Can

>> you keep that?

>>

>> Simon

> 

> I have added it as a separate patch in the series (see "[PATCH v3 9/9] [gdb/testsuite] handle compilation failures in jit-elf-helpers") as it seemed more incremental / easier to read.  Is that ok?


I don't know, the code before this patch does the checks already, which you remove in this
patch.  Is there some difficulty in just keeping it?

Simon
Simon Marchi April 20, 2020, 1:53 p.m. | #4
On 2020-04-20 9:08 a.m., Simon Marchi wrote:
> On 2020-04-20 3:35 a.m., Strasuns, Mihails wrote:

>>> -----Original Message-----

>>> From: Simon Marchi <simark@simark.ca>

>>> Sent: Saturday, April 18, 2020 4:58 AM

>>> To: Strasuns, Mihails <mihails.strasuns@intel.com>; gdb-

>>> patches@sourceware.org

>>> Subject: Re: [PATCH v3 4/9] [gdb/testsuite] use args as lib list for jit-elf tests

>>

>>

>>>> @@ -146,31 +149,23 @@ proc one_jit_test {count match_str reattach} {

>>>>      }

>>>>  }

>>>>

>>>> -if {[compile_jit_test jit.exp "" {}] < 0} {

>>>> -    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_jit_main "" {}

>>>> +compile_n_jit_so 2

>>>

>>> I mentioned ealier: if we fail to compile the test program, we don't want to

>>> execute the rest of the test case.  That's what the previous code did.  Can

>>> you keep that?

>>>

>>> Simon

>>

>> I have added it as a separate patch in the series (see "[PATCH v3 9/9] [gdb/testsuite] handle compilation failures in jit-elf-helpers") as it seemed more incremental / easier to read.  Is that ok?

> 

> I don't know, the code before this patch does the checks already, which you remove in this

> patch.  Is there some difficulty in just keeping it?


I gave it a shot yesterday, and this is how I think the patch could look like
(I haven't updated the commit message and ChangeLog).  Of course, the rest
of the series would need to be adapted.

From memory, the things that I changed, are:

- Check if compilation succeeded, skip corresponding portion of test if not
- The naming was a bit unclear (e.g. srcfile vs srcfile2), I tried to give clear
  consistent names to everything
- Setting globals in some procedures and reading them in other procedures is really
  hard to follow.  Things that are pretty much static can initialized at the top
  of the file and used throughout.  Otherwise, procedures should return values, which
  can then be passed to other procedures as arguments.
- Add comments to functions, specifying their parameters and what they return in case
  of success/failure.  I just realized that I haven't added a comment to one_jit_test,
  it would be a good idea to have one.

Feel free to pick and choose things from this version of the patch.

Simon


From d4afd233ba57c1700a940d3de3ba0e146eaba925 Mon Sep 17 00:00:00 2001
From: Mihails Strasuns via Gdb-patches <gdb-patches@sourceware.org>

Date: Tue, 31 Mar 2020 19:13:51 +0200
Subject: [PATCH] use args as lib list for jit-elf tests

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

Change-Id: Ie8f85ec6358604c14557b0417d6621b2f8942033
Signed-off-by: Mihails Strasuns <mihails.strasuns@intel.com>

---
 gdb/testsuite/gdb.base/jit-elf-main.c |  56 ++++-----
 gdb/testsuite/gdb.base/jit-elf-so.exp | 171 +++++++++++++++++++-------
 gdb/testsuite/gdb.base/jit-elf.exp    | 154 ++++++++++++++---------
 3 files changed, 240 insertions(+), 141 deletions(-)

diff --git a/gdb/testsuite/gdb.base/jit-elf-main.c b/gdb/testsuite/gdb.base/jit-elf-main.c
index fe0f540d6f40..c324b967261d 100644
--- a/gdb/testsuite/gdb.base/jit-elf-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-main.c
@@ -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));
diff --git a/gdb/testsuite/gdb.base/jit-elf-so.exp b/gdb/testsuite/gdb.base/jit-elf-so.exp
index 526414f43cfd..3dd7bc8c8536 100644
--- a/gdb/testsuite/gdb.base/jit-elf-so.exp
+++ b/gdb/testsuite/gdb.base/jit-elf-so.exp
@@ -26,48 +26,97 @@ 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}]
+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 +128,30 @@ 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\""
+	gdb_test "set var argc=[expr $count + 1]"
+	gdb_test "set var argv=fake_argv"
+	for {set i 1} {$i <= $count} {incr i} {
+	    set binfile_target [lindex $solib_binfiles_target [expr $i-1]]
+	    gdb_test "set var argv\[$i\]=\"${binfile_target}\""
+	}

-	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"
-
-	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,20 +162,41 @@ 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\":"
     }
 }

-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
+}

-# 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 the "real" main for this test.
+if { [compile_jit_dlmain {shlib_load}] < 0 } {
+    return
+}
+
+# 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"
+}
diff --git a/gdb/testsuite/gdb.base/jit-elf.exp b/gdb/testsuite/gdb.base/jit-elf.exp
index 71d3e37dfb82..29638bd2c084 100644
--- a/gdb/testsuite/gdb.base/jit-elf.exp
+++ b/gdb/testsuite/gdb.base/jit-elf.exp
@@ -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,19 @@ 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 "set var argc=$count"
+	gdb_test "set var argv=fake_argv"
+	for {set i 1} {$i < $count} {incr i} {
+	    set jit_solib_target [lindex $jit_solibs_target [expr $i-1]]
+	    gdb_test "set var argv\[$i\]=\"${jit_solib_target}\""
+	}
+
+	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 +178,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
 }
-- 
2.26.1

Patch

diff --git a/gdb/testsuite/gdb.base/jit-elf-main.c b/gdb/testsuite/gdb.base/jit-elf-main.c
index fe0f540d6f..66c6e10f24 100644
--- a/gdb/testsuite/gdb.base/jit-elf-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-main.c
@@ -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,38 @@  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);
+  char* fake_argv[10]; // used as backing storage for GDB to populate argv
 
   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));
diff --git a/gdb/testsuite/gdb.base/jit-elf-so.exp b/gdb/testsuite/gdb.base/jit-elf-so.exp
index 526414f43c..bcd72eb2bf 100644
--- a/gdb/testsuite/gdb.base/jit-elf-so.exp
+++ b/gdb/testsuite/gdb.base/jit-elf-so.exp
@@ -26,45 +26,68 @@  if {[get_compiler_info]} {
     return 1
 }
 
-#
-# test running programs
-#
-
-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
+# Compile the testcase program.
+# OPTIONS is passed to gdb_compile when compiling the program.
+proc compile_jit_main {options} {
+    global srcdir subdir srcfile2 binfile2
+    set testfile jit-elf-main
+    set srcfile2 ${testfile}.c
+    set binfile2 [standard_output_file $testfile.so]
+    set options [concat \
+	$options \
+	debug]
+    if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" \
+	    $options] != "" } {
+	untested "Failure to compile jit-elf-main"
+    }
 }
 
-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 library.
+proc compile_jit_dlmain {options} {
+    global srcdir subdir testfile srcfile binfile
+    set testfile jit-elf-dlmain
+    set srcfile ${testfile}.c
+    set binfile [standard_output_file $testfile]
+    set options [concat \
+	$options \
+	debug]
+    if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+	    executable $options] != "" } {
+	untested "Failure to compile jit-elf-main"
+    }
 }
 
-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"
+proc compile_n_jit_so {count} {
+    global srcdir subdir solib_binfile_targets
+    set solib_binfile_targets {}
+    set solib_testfile jit-elf-solib
+
+    for {set i 1} {$i <= $count} {incr i} {
+	set solib_binfile [standard_output_file ${solib_testfile}.$i.so]
+	set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c"
+	set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}.$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 ${solib_srcfile} ${solib_binfile} {}] != "" } {
+	    untested "Failure to compile ${solib_binfile_test_msg}"
+	}
 
-# 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 ${solib_binfile}]
+	lappend solib_binfile_targets $path
+    }
 }
 
-set solib_binfile_target [gdb_remote_download target ${solib_binfile}]
+compile_jit_main {additional_flags="-DMAIN=jit_dl_main"}
+compile_jit_dlmain {shlib_load}
+compile_n_jit_so 2
 
 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 testfile srcfile2 binfile2 solib_binfile_targets
 
 	clean_restart $testfile
 	gdb_load_shlib $binfile2
@@ -81,9 +104,16 @@  proc one_jit_test {count match_str} {
 
 	gdb_breakpoint [gdb_get_line_number "break here before-dlopen" ]
 	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 = \"$binfile2\""
+	incr count
+	gdb_test "set var argc=$count"
+	gdb_test "set var argv=fake_argv"
+	for {set i 1} {$i < $count} {incr i} {
+	    gdb_test "set var argv\[$i\]=\"[lindex $solib_binfile_targets [expr $i-1]]\""
+	}
 
 	gdb_breakpoint [gdb_get_line_number "break here after-dlopen" ]
 	gdb_continue_to_breakpoint "break here after-dlopen"
@@ -91,10 +121,6 @@  proc one_jit_test {count match_str} {
 	gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here 0} $srcfile2]"
 	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"
-
 	gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here 1} $srcfile2]"
 	gdb_continue_to_breakpoint "break here 1"
 
@@ -114,12 +140,15 @@  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"
-
-# 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"
+one_jit_test 1 "${hex}  jit_function_0001"
+one_jit_test 2 "${hex}  jit_function_0001\[\r\n\]+${hex}  jit_function_0002"
+
+foreach solib $solib_binfile_targets {
+    # 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"
+}
diff --git a/gdb/testsuite/gdb.base/jit-elf.exp b/gdb/testsuite/gdb.base/jit-elf.exp
index 71d3e37dfb..afc1ac9f96 100644
--- a/gdb/testsuite/gdb.base/jit-elf.exp
+++ b/gdb/testsuite/gdb.base/jit-elf.exp
@@ -23,42 +23,41 @@  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
-
+proc compile_jit_main {binsuffix options} {
+    global srcdir subdir testfile srcfile binfile
     set testfile jit-elf-main
     set srcfile ${testfile}.c
     set binfile [standard_output_file $testfile$binsuffix]
+    set options [concat \
+	$options \
+	debug]
     if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
-	      executable [concat debug $options]] != "" } {
-	untested $testname
-	return -1
-    }
-
-    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
+	  executable $options] != "" } {
+	      untested "Failure to compile jit-elf-main"
     }
+}
 
-    set solib_binfile_target [gdb_remote_download target ${solib_binfile}]
+proc compile_n_jit_so {count} {
+    global srcdir subdir solib_binfile_targets
+    set solib_binfile_targets {}
+    set solib_testfile jit-elf-solib
+
+    for {set i 1} {$i <= $count} {incr i} {
+	set solib_binfile [standard_output_file ${solib_testfile}.$i.so]
+	set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c"
+	set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}.$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 ${solib_srcfile} ${solib_binfile} {}] != "" } {
+	    untested "Failure to compile ${solib_binfile_test_msg}"
+	}
 
-    return 0
+	set path [gdb_remote_download target ${solib_binfile}]
+	lappend solib_binfile_targets $path
+    }
 }
 
 # Detach, restart GDB, and re-attach to the program.
@@ -105,7 +104,7 @@  proc continue_to_test_location {location reattach} {
 
 proc one_jit_test {count match_str reattach} {
     with_test_prefix "one_jit_test-$count" {
-	global verbose testfile solib_binfile_target solib_binfile_test_msg
+	global verbose testfile solib_binfile_targets
 
 	clean_restart $testfile
 
@@ -119,14 +118,18 @@  proc one_jit_test {count match_str reattach} {
 	    return
 	}
 
+	# Poke desired values directly into inferior instead of using "set args"
+	# because "set args" does not work under gdbserver.
+	incr count
+	gdb_test "set var argc=$count"
+	gdb_test "set var argv=fake_argv"
+	for {set i 1} {$i < $count} {incr i} {
+	    gdb_test "set var argv\[$i\]=\"[lindex $solib_binfile_targets [expr $i-1]]\""
+	}
+
 	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"
 
 	continue_to_test_location "break here 1" $reattach
 
@@ -146,31 +149,23 @@  proc one_jit_test {count match_str reattach} {
     }
 }
 
-if {[compile_jit_test jit.exp "" {}] < 0} {
-    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_jit_main "" {}
+compile_n_jit_so 2
+
+one_jit_test 1 "${hex}  jit_function_0001" 0
+one_jit_test 2 "${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
-    }
-
+    compile_jit_main "-attach" {additional_flags=-DATTACH=1}
     with_test_prefix attach {
-	one_jit_test 2 "${hex}  jit_function_0000\[\r\n\]+${hex}  jit_function_0001" 1
+	one_jit_test 2 "${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
-    }
-
-    one_jit_test 1 "${hex}  jit_function_0000" 0
+    compile_jit_main "-pie" {additional_flags=-fPIE ldflags=-pie}
+    one_jit_test 1 "${hex}  jit_function_0001" 0
 }