[1/2] testsuite: Extend object-readelf beyond attributes
Commit Message
object-readelf in lib/lto.exp was hard-wired to use readelf -A,
limiting it to attribute checks. Extend it to accept a readelf option and
a regex, where the option selects the readelf flag and the regex is
matched against the output.
Add wrapper procedures for common use cases:
• attribute checks, and
• note checks.
Also add support for negative checks via an "is-negative" argument,
which requires that the regex is not present in the output.
gcc/ChangeLog:
* doc/sourcebuild.texi (Scan object metadata with readelf): Document
object-readelf-attributes, object-readelf-attributes-not,
object-readelf-notes, and object-readelf-notes-not as regex-based
checks with optional target/xfail selectors.
gcc/testsuite/ChangeLog:
* lib/lto.exp (object-readelf): Accept a readelf option and a single
regex; match against full readelf output. Keep positive/negative
behaviour via wrappers.
(object-readelf-attributes, object-readelf-attributes-not,
object-readelf-notes, object-readelf-notes-not): Implement as wrappers
over the generic matcher.
* gcc.dg-selftests/dg-final.exp (dg_final_directive_check_num_args):
Update for object-readelf-* wrappers to regex-style arguments (1..3).
* gcc.target/arm/lto/pr61123-enum-size_0.c: Update to use
object-readelf-attributes with a single regex.
---
gcc/doc/sourcebuild.texi | 23 ++++++
gcc/testsuite/gcc.dg-selftests/dg-final.exp | 5 +-
.../gcc.target/arm/lto/pr61123-enum-size_0.c | 2 +-
gcc/testsuite/lib/lto.exp | 77 ++++++++++---------
4 files changed, 68 insertions(+), 39 deletions(-)
@@ -3729,6 +3729,29 @@ stands for zero or more unmatched lines; the whitespace after
@end table
+@subsubsection Scan object metadata with readelf
+
+These commands inspect the linked test output file with @command{readelf}.
+They are mainly intended for LTO tests.
+
+These commands take a single @var{regex} and test whether it is present
+in (or absent from, for @samp{-not}) the corresponding @command{readelf}
+output.
+
+@table @code
+@item object-readelf-attributes @var{regex} [@{ target/xfail @var{selector} @}]
+Runs @command{readelf -A} and checks that @var{regex} matches.
+
+@item object-readelf-attributes-not @var{regex} [@{ target/xfail @var{selector} @}]
+Runs @command{readelf -A} and checks that @var{regex} does not match.
+
+@item object-readelf-notes @var{regex} [@{ target/xfail @var{selector} @}]
+Runs @command{readelf -n} and checks that @var{regex} matches.
+
+@item object-readelf-notes-not @var{regex} [@{ target/xfail @var{selector} @}]
+Runs @command{readelf -n} and checks that @var{regex} does not match.
+@end table
+
@subsubsection Scan optimization dump files
These commands are available for @var{kind} of @code{tree}, @code{ltrans-tree},
@@ -94,7 +94,10 @@ proc dg_final_directive_check_num_args {} {
verify_args scan-lang-dump 2 3
- verify_args object-readelf 2 3
+ verify_args object-readelf-attributes 1 3
+ verify_args object-readelf-attributes-not 1 3
+ verify_args object-readelf-notes 1 3
+ verify_args object-readelf-notes-not 1 3
verify_args scan-assembler-times 2 3
verify_args scan-assembler-dem 1 2
@@ -20,4 +20,4 @@ foo1 (struct debug_ABI_enum_size *x)
return sizeof (x->es);
}
-/* { dg-final { object-readelf Tag_ABI_enum_size int { target arm_eabi } } } */
+/* { dg-final { object-readelf-attributes {Tag_ABI_enum_size:\s+int} { target arm_eabi } } } */
@@ -915,23 +915,21 @@ proc lto-execute { src1 sid } {
initialize_prune_notes
}
-# Call pass if object readelf is ok, otherwise fail.
-# example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */
-proc object-readelf { args } {
+proc object-readelf { option is_negative directive args } {
global readelf
global base_dir
- upvar 2 execname execname
+ upvar 3 execname execname
- if { [llength $args] < 2 } {
- error "object-readelf: too few arguments"
+ if { [llength $args] < 1 } {
+ error "$directive: too few arguments"
return
}
- if { [llength $args] > 3 } {
- error "object-readelf: too many arguments"
+ if { [llength $args] > 2 } {
+ error "$directive: too many arguments"
return
}
- if { [llength $args] >= 3 } {
- switch [dg-process-target [lindex $args 2]] {
+ if { [llength $args] >= 2 } {
+ switch [dg-process-target [lindex $args 1]] {
"S" { }
"N" { return }
"F" { setup_xfail "*-*-*" }
@@ -939,7 +937,7 @@ proc object-readelf { args } {
}
}
- # Find size like we find g++ in g++.exp.
+ # Find readelf like we find g++ in g++.exp.
if ![info exists readelf] {
set readelf [findfile $base_dir/../../../binutils/readelf \
$base_dir/../../../binutils/readelf \
@@ -949,47 +947,52 @@ proc object-readelf { args } {
verbose -log "readelf is $readelf"
}
- set what [lindex $args 0]
- set with [lindex $args 1]
+ set regex [lindex $args 0]
if ![file_on_host exists $execname] {
verbose -log "$execname does not exist"
- unresolved "object-readelf $what "
+ unresolved "$directive $regex "
return
}
- set output [remote_exec host "$readelf -A" "$execname"]
+ set output [remote_exec host "$readelf $option" "$execname"]
set status [lindex $output 0]
if { $status != 0 } {
- verbose -log "object-readelf: $readelf failed"
- unresolved "object-readelf $what $execname"
+ verbose -log "$directive: $readelf failed"
+ unresolved "$directive $regex $execname"
return
}
set text [lindex $output 1]
- set lines [split $text "\n"]
+ set match [regexp -- $regex $text]
- set done 0
- set i 0
- while { !$done } {
- set line_tex [lindex $lines $i]
- if { [llength ${line_tex}] > 1} {
- incr i
- if [regexp -- $what $line_tex] {
- set match [regexp -- $with $line_tex]
- set done 1
- }
- } else {
- set done 1
- }
- }
-
- verbose -log "$what size is $with;"
- if { $match == 1 } {
- pass "object-readelf $what size is correct."
+ if { ($is_negative && $match == 0) || (!$is_negative && $match == 1) } {
+ pass "$directive $regex pattern is correct."
} else {
- fail "object-readelf $what size is incorrect."
+ fail "$directive $regex pattern is incorrect."
}
}
+# Call pass if regex ($args 0) matches readelf -A output, otherwise fail.
+# example: /* { dg-final { object-readelf-attributes {Tag_ABI_enum_size:\s+int} } } */
+proc object-readelf-attributes { args } {
+ object-readelf "-A" 0 object-readelf-attributes {*}$args
+}
+
+# Call pass if regex ($args 0) does not match readelf -A output, otherwise fail.
+# example: /* { dg-final { object-readelf-attributes {Tag_ABI_enum_size:\s+int} } } */
+proc object-readelf-attributes-not { args } {
+ object-readelf "-A" 1 object-readelf-attributes-not {*}$args
+}
+# Call pass if regex ($args 0) matches readelf -n output, otherwise fail.
+# example: /* { dg-final { object-readelf-notes {AArch64 feature:\s+BTI,\s+PAC,\s+GCS} } } */
+proc object-readelf-notes { args } {
+ object-readelf "-n" 0 object-readelf-notes {*}$args
+}
+
+# Call pass if regex ($args 0) does not match readelf -n output, otherwise fail.
+# example: /* { dg-final { object-readelf-notes-not {AArch64 feature:\s+BTI,\s+PAC,\s+GCS} } } */
+proc object-readelf-notes-not { args } {
+ object-readelf "-n" 1 object-readelf-notes-not {*}$args
+}