Simplify testing symbol sections
diff mbox series

Message ID CAC-ggsEmdWw4bcbm+_3CpS2a_CGnU_cCzw8u2_eoEWcitgStzg@mail.gmail.com
State New
Headers show
Series
  • Simplify testing symbol sections
Related show

Commit Message

Strager Neds Nov. 21, 2019, 6:08 a.m. UTC
While fixing some bugs in __attribute__((section)), I found it difficult
to write tests. Make testing easier: introduce the
scan-assembler-symbol-section and scan-symbol-section helpers. See
in-line documentation for details.

Testing:

* Run `make check` on x86_64-linux-gnu with --disable-multilib
  --enable-checking=release --enable-languages=c,c++. Observe no new
  failures in test results.
* Run `make check` on macOS x86_64-apple-darwin16.7.0 with
  --disable-multilib --enable-checking=release --enable-languages=c,c++.
  Observe no new failures in test results.
* Run test-framework.exp with CHECK_TEST_FRAMEWORK=1, and post-process
  results with test-framework.awk. Observe no new failures test
  results.

2019-11-12  Matthew Glazar <strager.nds@gmail.com>

* gcc/testsuite/lib/scanasm.exp (dg-scan): Extract file globbing
code ...
(dg_glob_remote): ... into this new procedure.
(scan-assembler-symbol-section): Define.
(scan-symbol-section): Define.
---
 gcc/testsuite/g++.dg/gomp/tls-5.C             |   2 +
 gcc/testsuite/g++.dg/opt/const4.C             |   3 +-
 gcc/testsuite/gcc.dg/20021029-1.c             |   1 +
 gcc/testsuite/gcc.dg/array-quals-1.c          |  20 ++
 gcc/testsuite/gcc.dg/darwin-sections.c        |   2 +
 gcc/testsuite/gcc.dg/pr25376.c                |   1 +
 .../dg-scan-symbol-section-1-exp-F.S          |  13 ++
 .../dg-scan-symbol-section-2-exp-F.S          |   9 +
 .../dg-scan-symbol-section-3-exp-F.S          |  10 +
 .../dg-scan-symbol-section-exp-P.S            |  50 +++++
 .../gcc.test-framework/test-framework.exp     |   3 +-
 gcc/testsuite/lib/scanasm.exp                 | 184 +++++++++++++++++-
 12 files changed, 292 insertions(+), 6 deletions(-)
 create mode 100644
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
 create mode 100644
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
 create mode 100644
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
 create mode 100644
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S

     unresolved "$testcase $name $printable_pattern"
@@ -73,6 +70,13 @@ proc dg-scan { name positive testcase output_file
orig_args } {
     }
 }

+proc dg_glob_remote { file_pattern } {
+    if { [is_remote host] } {
+    remote_upload host $file_pattern
+    }
+    return [glob -nocomplain $file_pattern]
+}
+
 # Look for a pattern in the .s file produced by the compiler.  See
 # dg-scan for details.

@@ -155,6 +159,178 @@ proc scan-not-hidden { args } {
     dg-scan "scan-not-hidden" 0 $testcase $output_file $args
 }

+# Check that symbols are emitted in the desired section.
+# Like scan-symbol-section, but using the assembly output generated by
+# the compiler.
+#
+# Example:
+#
+# // All numbered functions (func1, func2, etc.) must be in the .text
section or
+# // in a .text sub-section (like .text._func1).
+# { dg-final { scan-assembler-symbol-section {^_func[1-5]$} {^\.text($|\.)} } }
+
+proc scan-assembler-symbol-section { args } {
+    set testcase [testname-for-summary]
+    set filename [lindex $testcase 0]
+    set output_file "[file rootname [file tail $filename]].s"
+    set symbol_pattern [lindex $args 0]
+    set expected_section_pattern [lindex $args 1]
+    dg-scan-symbol-section \
+    "scan-assembler-symbol-section" \
+    $testcase \
+    $output_file \
+    $symbol_pattern \
+    $expected_section_pattern
+}
+
+# Check that symbols are emitted in the desired section.
+#
+# Symbols and sections are interpreted as regexp patterns.
+#
+# If no matching symbol is found, scan-symbol-section reports a FAILure.
+#
+# Usage:
+#
+# { dg-final { scan-symbol-section FILENAME SYMBOL SECTION } }
+#
+# Examples:
+#
+# // The my_var C symbol must be in the .data section (or in a
.data._my_var section
+# // if -ffunction-sections is in use).
+# { dg-final { scan-symbol-section "my-test.s" {^_my_var$}
{^\.data(\._my_var)?$} } }
+#
+# // All numbered functions (func1, func2, etc.) must be in the .text section
+# // (and not in any other section like .text._func1).
+# { dg-final { scan-symbol-section "my-test.s" {^_func[1-5]$} {^\.text$} } }
+#
+# Caveats:
+#
+# * Only ELF and Mach-O targets are supported. Other
+#   targets, like PE/COFF, might appear to work.
+# * For Mach-O targets, the section name matched by scan-symbol-section has one
+#   of two forms:
+#   * The Mach-O segment name followed by a comma (',') followed by the Mach-O
+#     section name. For example, "__TEXT,__text". (There is no whitespace
+#     between the Mach-O segment name and the Mach-O section name.)
+#   * ".const", ".data", or ".text". For example, the .text assembler directive
+#     causes the section name to be ".text" (not "__TEXT,__text"). (However, a
+#     directive such as .section __TEXT,__text will cause the section
name to be
+#     "__TEXT,__text".)
+# * Because scan-symbol-section parses assembly code, scan-symbol-section is
+#   unaware of section rewriting performed by the linker. For example, the
+#   sections .text._f1 and .text._f2 would normally be merged by binutils'
+#   linker into one section called .text, but scan-symbol-section reports the
+#   sections as .text._f1 and .text._f2 (and not .text).
+# * The symbol pattern matches any assembly label, including local labels which
+#   begin with `.L`.
+
+proc scan-symbol-section { args } {
+    set testcase [testname-for-summary]
+    set output_file [lindex $args 0]
+    set symbol_pattern [lindex $args 1]
+    set expected_section_pattern [lindex $args 2]
+    dg-scan-symbol-section \
+    "scan-symbol-section" \
+    $testcase \
+    $output_file \
+    $symbol_pattern \
+    $expected_section_pattern
+}
+
+# Check that symbols are emitted in the desired section.
+#
+# Avoid calling this function directly. In tests, use scan-symbol-section,
+# scan-assembler-symbol-section, or scan-lto-assembler-symbol-section instead.
+
+proc dg-scan-symbol-section { name testcase output_file
symbol_pattern expected_section_pattern } {
+    set printable_symbol_pattern [make_pattern_printable $symbol_pattern]
+    set printable_expected_section_pattern [make_pattern_printable
$expected_section_pattern]
+
+    set files [dg_glob_remote $output_file]
+    if { $files == "" } {
+    verbose -log "$testcase: output file does not exist"
+    unresolved "$testcase $name symbol $printable_symbol_pattern has
section $printable_expected_section_pattern"
+    return
+    }
+
+    parse_section_of_symbols $output_file section_by_symbol
+
+    set found_symbol 0
+    foreach symbol_name [lsort [array names section_by_symbol]] {
+        if { [regexp -- $symbol_pattern $symbol_name] } {
+            set section $section_by_symbol($symbol_name)
+            set description "$testcase $name symbol
$printable_symbol_pattern (found $symbol_name) has section
$printable_expected_section_pattern"
+            if { $section == "" } {
+                fail "$description (no section detected)"
+            } else {
+                set description "$description (found $section)"
+                if { [regexp -- $expected_section_pattern $section] } {
+                    pass $description
+                } else {
+                    fail $description
+                }
+            }
+            set found_symbol 1
+        }
+    }
+    if { ! $found_symbol } {
+        fail "$testcase $name symbol $printable_symbol_pattern
(symbol not found) has section $printable_expected_section_pattern"
+    }
+}
+
+# Extract a symbol and section names from pre-processed assembly source code.
+#
+# This function adds entries in the RESULT array where the key is the symbol's
+# name (including any leading underscores) and the value is the section's name
+# (including any leading periods).
+#
+# For example, given the following assembly source code in file.s:
+#
+#         .text
+#         .function _my_function
+# _my_function:
+#         nop
+#         .data
+# _my_data:
+#         .long 42
+#
+# Executing 'parse_section_of_symbols "file.s" symbols' would have the same
+# effect as the following code:
+#
+# set $result(_my_function) .text
+# set $result(_my_data) .data
+
+proc parse_section_of_symbols { filename result } {
+    upvar $result up_result
+
+    set section_pattern {^\s*(?:\.section\s+(.*)|(\.const|\.data|\.text)\s*)$}
+    set label_pattern {^(\S+):$}
+
+    set fd [open $filename r]
+    set current_section ""
+    while { [gets $fd line] >= 0 } {
+        if { [regexp -- $label_pattern $line dummy symbol_name] } {
+            set up_result($symbol_name) $current_section
+        } elseif { [regexp -- $section_pattern $line dummy
section_directive_arguments full_section_directive] } {
+            if { $full_section_directive eq "" } {
+                # Example: .section .text,"ax",progbits
+                # Example: .section __TEXT,__text
+                set arguments [split $section_directive_arguments ","]
+                set current_section [string trim [lindex $arguments 0]]
+                set arg_1 [string trim [lindex $arguments 1]]
+                if { [regexp {^_} $arg_1] } {
+                    # The second argument looks like a Mach-O section name.
+                    set current_section "$current_section,$arg_1"
+                }
+            } else {
+                # Example: .text
+                set current_section "$full_section_directive"
+            }
+        }
+    }
+    close $fd
+}
+
 # Look for a pattern in OUTPUT_FILE.  See dg-scan for details.

 proc scan-file { output_file args } {

Patch
diff mbox series

diff --git gcc/testsuite/g++.dg/gomp/tls-5.C gcc/testsuite/g++.dg/gomp/tls-5.C
index e83ff1179e6..a1d3120fbfb 100644
--- gcc/testsuite/g++.dg/gomp/tls-5.C
+++ gcc/testsuite/g++.dg/gomp/tls-5.C
@@ -1,6 +1,8 @@ 
 // The reference temp should be TLS, not normal data.
 // { dg-require-effective-target c++11 }
 // { dg-final { scan-assembler-not "\\.data" { target tls_native
xfail powerpc-*-aix* } } }
+// { dg-final { scan-assembler-symbol-section {^_?ir$} {^\.tbss} } }
+// { dg-final { scan-assembler-symbol-section {^_?_ZGR2ir_$} {^\.tdata} } }

 extern int&& ir;
 #pragma omp threadprivate (ir)
diff --git gcc/testsuite/g++.dg/opt/const4.C gcc/testsuite/g++.dg/opt/const4.C
index 883c24b55fc..51d5313a312 100644
--- gcc/testsuite/g++.dg/opt/const4.C
+++ gcc/testsuite/g++.dg/opt/const4.C
@@ -3,7 +3,8 @@ 
 // that have it.
 // { dg-do compile }

-const int a[] __attribute__ ((__used__)) = { 0, 1, 2, 3 };
+// { dg-final { scan-assembler-symbol-section {constant_variable}
{^\.(const|rodata)} } }
+const int constant_variable[] __attribute__ ((__used__)) = { 0, 1, 2, 3 };

 // The MMIX port always switches to the .data section at the end of a file.
 // { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail
powerpc*-*-aix* mmix-*-* } } }
diff --git gcc/testsuite/gcc.dg/20021029-1.c gcc/testsuite/gcc.dg/20021029-1.c
index f11a6e4a920..c8ae4aa60e2 100644
--- gcc/testsuite/gcc.dg/20021029-1.c
+++ gcc/testsuite/gcc.dg/20021029-1.c
@@ -3,6 +3,7 @@ 
 /* { dg-do compile { target fpic } } */
 /* { dg-options "-O2 -fpic" } */
 /* { dg-final { scan-assembler-not ".data.rel.ro.local" } } */
+/* { dg-final { scan-assembler-symbol-section {ar} {^\.(const|rodata)} } } */
 /* { dg-require-effective-target label_values } */
 /* { dg-require-effective-target indirect_jumps } */

diff --git gcc/testsuite/gcc.dg/array-quals-1.c
gcc/testsuite/gcc.dg/array-quals-1.c
index 3981c916021..819bd24af76 100644
--- gcc/testsuite/gcc.dg/array-quals-1.c
+++ gcc/testsuite/gcc.dg/array-quals-1.c
@@ -6,26 +6,46 @@ 
 /* { dg-options "-Wno-discarded-array-qualifiers" } */
 /* The MMIX port always switches to the .data section at the end of a file.  */
 /* { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail
powerpc*-*-aix* mmix-*-* x86_64-*-mingw* } } } */
+/* { dg-final { scan-assembler-symbol-section {^_?a$}
{^\.(const|rodata)} } } */
 static const int a[2] = { 1, 2 };
+/* { dg-final { scan-assembler-symbol-section {^_?a1$}
{^\.(const|rodata)} } } */
 const int a1[2] = { 1, 2 };
 typedef const int ci;
+/* { dg-final { scan-assembler-symbol-section {^_?b$}
{^\.(const|rodata)} } } */
 static ci b[2] = { 3, 4 };
+/* { dg-final { scan-assembler-symbol-section {^_?b1$}
{^\.(const|rodata)} } } */
 ci b1[2] = { 3, 4 };
 typedef int ia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?c$}
{^\.(const|rodata)} } } */
 static const ia c = { 5, 6 };
+/* { dg-final { scan-assembler-symbol-section {^_?c1$}
{^\.(const|rodata)} } } */
 const ia c1 = { 5, 6 };
 typedef const int cia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?d$}
{^\.(const|rodata)} } } */
 static cia d = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?d1$}
{^\.(const|rodata)} } } */
 cia d1 = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?e$}
{^\.(const|rodata)} } } */
 static cia e[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?e1$}
{^\.(const|rodata)} } } */
 cia e1[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?p$}
{^\.(const|rodata)} } } */
 void *const p = &a;
+/* { dg-final { scan-assembler-symbol-section {^_?q$}
{^\.(const|rodata)} } } */
 void *const q = &b;
+/* { dg-final { scan-assembler-symbol-section {^_?r$}
{^\.(const|rodata)} } } */
 void *const r = &c;
+/* { dg-final { scan-assembler-symbol-section {^_?s$}
{^\.(const|rodata)} } } */
 void *const s = &d;
+/* { dg-final { scan-assembler-symbol-section {^_?t$}
{^\.(const|rodata)} } } */
 void *const t = &e;
+/* { dg-final { scan-assembler-symbol-section {^_?p1$}
{^\.(const|rodata)} } } */
 void *const p1 = &a1;
+/* { dg-final { scan-assembler-symbol-section {^_?q1$}
{^\.(const|rodata)} } } */
 void *const q1 = &b1;
+/* { dg-final { scan-assembler-symbol-section {^_?r1$}
{^\.(const|rodata)} } } */
 void *const r1 = &c1;
+/* { dg-final { scan-assembler-symbol-section {^_?s1$}
{^\.(const|rodata)} } } */
 void *const s1 = &d1;
+/* { dg-final { scan-assembler-symbol-section {^_?t1$}
{^\.(const|rodata)} } } */
 void *const t1 = &e1;
diff --git gcc/testsuite/gcc.dg/darwin-sections.c
gcc/testsuite/gcc.dg/darwin-sections.c
index 79d48bd7da2..8d3a8f47b20 100644
--- gcc/testsuite/gcc.dg/darwin-sections.c
+++ gcc/testsuite/gcc.dg/darwin-sections.c
@@ -16,7 +16,9 @@  e_s ea;
 /* These should go into .data */
 char a = 0;
 short b = 0;
+/* { dg-final { scan-assembler-symbol-section {^_a$} {\.data} } } */
 /* { dg-final { scan-assembler ".globl _a.*.data.*.space\[\t \]1" } } */
+/* { dg-final { scan-assembler-symbol-section {^_b$} {\.data} } } */
 /* { dg-final { scan-assembler ".globl _b.*.data.*.space\[\t \]2" } } */

 /* These should go into __pu_bssN */
diff --git gcc/testsuite/gcc.dg/pr25376.c gcc/testsuite/gcc.dg/pr25376.c
index 3008b091dc2..25f1b66c9bd 100644
--- gcc/testsuite/gcc.dg/pr25376.c
+++ gcc/testsuite/gcc.dg/pr25376.c
@@ -7,3 +7,4 @@  void simple (void)
 }

 /* { dg-final { scan-assembler "my_named_section" } } */
+/* { dg-final { scan-assembler-symbol-section {simple$}
{^my_named_section$} } } */
diff --git gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
new file mode 100644
index 00000000000..70b69271f8f
--- /dev/null
+++ gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
@@ -0,0 +1,13 @@ 
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'FAIL' if a symbol has a different
+// section than expected.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section
"dg-scan-symbol-section-1-exp-F.i" {^_test_symbol_.*$} {nomatch} } }
+// The above assertion should fail with the following messages:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
scan-symbol-section symbol ^_test_symbol_.*$ (found _test_symbol_1)
has section nomatch (found .text)
+// FAIL: gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
scan-symbol-section symbol ^_test_symbol_.*$ (found _test_symbol_2)
has section nomatch (found .data)
+    .text
+_test_symbol_1:
+    .data
+_test_symbol_2:
diff --git gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
new file mode 100644
index 00000000000..01872751d4d
--- /dev/null
+++ gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
@@ -0,0 +1,9 @@ 
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'UNSUPPORTED' if a symbol has no
+// associated section.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section
"dg-scan-symbol-section-2-exp-F.i" {^_test_symbol$} {^\.text$} } }
+// The above assertion should fail with the following message:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
scan-symbol-section symbol ^_test_symbol$ (found _test_symbol) has
section ^\\.text$ (no section detected)
+_test_symbol:
diff --git gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
new file mode 100644
index 00000000000..87b09a33948
--- /dev/null
+++ gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
@@ -0,0 +1,10 @@ 
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'UNSUPPORTED' if a symbol has no
+// associated section.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section
"dg-scan-symbol-section-3-exp-F.i" {^_test_symbol$} {^\.text$} } }
+// The above assertion should fail with the following message:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
scan-symbol-section symbol ^_test_symbol$ (no symbol detected) has
section ^\\.text$
+    .text
+_test_wrong_symbol:
diff --git gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S
gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S
new file mode 100644
index 00000000000..1166b74b376
--- /dev/null
+++ gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S
@@ -0,0 +1,50 @@ 
+// Test the scan-symbol-section directive.
+
+// { dg-do preprocess }
+
+// The .section directive changes the section for all following symbols.
+    .section .text
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_function_1$} {^\.text$} } }
+_test_function_1:
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_function_2$} {^\.text$} } }
+_test_function_2:
+
+// For ELF targets, the .section directive can take multiple arguments.
+    .section .other_text_section,"ax",progbits
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_elf_function$} {^\.other_text_section$} } }
+_test_elf_function:
+
+// For Mach-O targets, the .section directive takes a segment name
and a section name.
+    .section __TEXT,__my_text_section
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_macho_function$} {^__TEXT,__my_text_section$} } }
+_test_macho_function:
+// Extra whitespace between .section arguments should be ignored.
+    .section  __DATA , __testsection
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_macho_var$} {^__DATA,__testsection$} } }
+_test_macho_var:
+
+// The .data directive sets the section for all following symbols to '.data'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_var_1$} {^\.data$} } }
+    .data
+_test_var_1:
+
+// The .text directive sets the section for all following symbols to '.text'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_function_3$} {^\.text$} } }
+    .text
+_test_function_3:
+
+// The .const directive sets the section for all following symbols to '.const'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_data_1$} {^\.const$} } }
+    .const
+_test_data_1:
+
+// Other directives do not affect the section of following symbols.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_var_2$} {^\.data$} } }
+    .data
+    .p2align 2
+    .size _test_var_2, 4
+_test_var_2:
+
+// Symbol name patterns can match multiple symbols, and section name patterns
+// can match multiple sections.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i"
{^_test_function_} {^(\.|__TEXT,).*text} } }
diff --git gcc/testsuite/gcc.test-framework/test-framework.exp
gcc/testsuite/gcc.test-framework/test-framework.exp
index db4b8665258..69a0aca0933 100644
--- gcc/testsuite/gcc.test-framework/test-framework.exp
+++ gcc/testsuite/gcc.test-framework/test-framework.exp
@@ -23,6 +23,7 @@  if { ![info exists env(CHECK_TEST_FRAMEWORK)] } {
 }

 load_lib gcc-dg.exp
+load_lib scanasm.exp

 proc dg-require-true { args } {
     verbose "dg-require-true" 2
@@ -59,7 +60,7 @@  set dg-do-what-default compile
 dg-init

 # Run tests from the source directory.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dg-*.c]] "" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dg-*.S
$srcdir/$subdir/dg-*.c]] "" ""

 # Skip generated tests unless CHECK_TEST_FRAMEWORK is 1.
 if { $env(CHECK_TEST_FRAMEWORK) != 1 } {
diff --git gcc/testsuite/lib/scanasm.exp gcc/testsuite/lib/scanasm.exp
index 0f1b246b8dc..e9ebf52d77e 100644
--- gcc/testsuite/lib/scanasm.exp
+++ gcc/testsuite/lib/scanasm.exp
@@ -52,10 +52,7 @@  proc dg-scan { name positive testcase output_file
orig_args } {
     set pattern [lindex $orig_args 0]
     set printable_pattern [make_pattern_printable $pattern]

-    if { [is_remote host] } {
-    remote_upload host "$output_file"
-    }
-    set files [glob -nocomplain $output_file]
+    set files [dg_glob_remote $output_file]
     if { $files == "" } {
     verbose -log "$testcase: output file does not exist"