summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2019-01-21 15:51:49 +0000
committerAlan Hayward <alan.hayward@arm.com>2019-01-21 15:51:49 +0000
commit73021deb50855f31bb312241899a464c62155f6a (patch)
tree244743e4b0361fb6426946c1dfe9567a1ec64f53
parenta6c9b4042921847ee52003811383e4b8bf5d5875 (diff)
downloadbinutils-gdb-73021deb50855f31bb312241899a464c62155f6a.tar.gz
AArch64 AAPCS: Empty structs have non zero size in C++
When gdb.base/infcall-nested-structs.c is complied as C++, the compiler will not pass structs containing empty structs via float arguments. This is because structs in C++ have a minimum size of 1, causing padding in the struct once compiled. The AAPCS does not allow structs with padding to be passed in float arguments. Add padding checks to AArch64 and add C++ compile variant to the test. Some of the tests fail on X86_64. This has been raised as bug gdb/24104. gdb/ChangeLog: * aarch64-tdep.c (aapcs_is_vfp_call_or_return_candidate_1): Check for padding. gdb/testsuite/ChangeLog: * gdb.base/infcall-nested-structs.exp: Test C++ in addition to C.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/aarch64-tdep.c8
-rw-r--r--gdb/testsuite/ChangeLog3
-rw-r--r--gdb/testsuite/gdb.base/infcall-nested-structs.exp58
4 files changed, 61 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ac3cf075216..e495ff97066 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-21 Alan Hayward <alan.hayward@arm.com>
+
+ * aarch64-tdep.c (aapcs_is_vfp_call_or_return_candidate_1): Check
+ for padding.
+
2019-01-16 Tom Tromey <tom@tromey.com>
* objfiles.h (struct minimal_symbol_iterator): Rename. Move
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index b0515639378..7c5d74858d1 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1232,6 +1232,14 @@ aapcs_is_vfp_call_or_return_candidate_1 (struct type *type,
return -1;
count += sub_count;
}
+
+ /* Ensure there is no padding between the fields (allowing for empty
+ zero length structs) */
+ int ftype_length = (*fundamental_type == nullptr)
+ ? 0 : TYPE_LENGTH (*fundamental_type);
+ if (count * ftype_length != TYPE_LENGTH (type))
+ return -1;
+
return count;
}
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ae07cc260ca..7d8c7908fe5 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,4 +1,7 @@
2019-01-21 Alan Hayward <alan.hayward@arm.com>
+ * gdb.base/infcall-nested-structs.exp: Test C++ in addition to C.
+
+2019-01-21 Alan Hayward <alan.hayward@arm.com>
* gdb.base/stack-protector.c: New test.
* gdb.base/stack-protector.exp: New file.
* gdb.cp/ovldbreak.exp: Only allow a single break line.
diff --git a/gdb/testsuite/gdb.base/infcall-nested-structs.exp b/gdb/testsuite/gdb.base/infcall-nested-structs.exp
index b04d9aaa847..d7d1e3e00d8 100644
--- a/gdb/testsuite/gdb.base/infcall-nested-structs.exp
+++ b/gdb/testsuite/gdb.base/infcall-nested-structs.exp
@@ -24,6 +24,20 @@ if [target_info exists gdb,cannot_call_functions] {
continue
}
+# Only test C++ if we are able. Always use C.
+if { [skip_cplus_tests] || [get_compiler_info "c++"] } {
+ set lang {c}
+} else {
+ set lang {c c++}
+}
+
+foreach l $lang {
+ set dir "$l"
+ remote_exec host "rm -rf [standard_output_file ${dir}]"
+ remote_exec host "mkdir -p [standard_output_file ${dir}]"
+}
+
+
set int_types { tc ts ti tl tll }
set float_types { tf td tld }
set complex_types { tfc tdc tldc }
@@ -31,6 +45,7 @@ set complex_types { tfc tdc tldc }
set compile_flags {debug}
if [support_complex_tests] {
lappend compile_flags "additional_flags=-DTEST_COMPLEX"
+ lappend compile_flags "additional_flags=-Wno-psabi"
}
# Given N (0..25), return the corresponding alphabetic letter in upper
@@ -44,7 +59,7 @@ proc I2A { n } {
# types of the struct fields within the source. Run up to main.
# Also updates the global "testfile" to reflect the most recent build.
-proc start_nested_structs_test { types } {
+proc start_nested_structs_test { lang types } {
global testfile
global srcfile
global binfile
@@ -53,9 +68,11 @@ proc start_nested_structs_test { types } {
global compile_flags
standard_testfile .c
+ set dir "$lang"
# Create the additional flags
set flags $compile_flags
+ lappend flags $lang
for {set n 0} {$n<[llength ${types}]} {incr n} {
set m [I2A ${n}]
@@ -64,7 +81,7 @@ proc start_nested_structs_test { types } {
append testfile "-" "$t"
}
- set binfile [standard_output_file ${testfile}]
+ set binfile [standard_output_file ${dir}/${testfile}]
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } {
unresolved "failed to compile"
return 0
@@ -99,13 +116,21 @@ proc start_nested_structs_test { types } {
# Assuming GDB is stopped at main within a test binary, run some tests
# passing structures, and reading return value structures.
-proc run_tests {} {
+proc run_tests { lang types } {
global gdb_prompt
foreach {name} {struct_01_01 struct_01_02 struct_01_03 struct_01_04
struct_02_01 struct_02_02 struct_02_03 struct_02_04
struct_04_01 struct_04_02 struct_04_03 struct_04_04
struct_05_01 struct_05_02 struct_05_03 struct_05_04} {
+
+ if { ( $lang == "c++"
+ && ( ( [regexp "struct_01_0(1|2|3)" $name match] && [regexp "^types-(td($|-)|tl(|l)(|-tf|-td|-tld)$)" $types match] )
+ || ( $name == "struct_01_02" && $types == "types-tfc" )
+ || ( $name == "struct_01_04" && [regexp "^types-(tf($|-)|ti(|-tf|-td|-tld)$)" $types match] )
+ || ( $name == "struct_02_01" && [regexp "^types-tf-t(c|s|i)" $types match] ) ) ) } {
+ setup_xfail gdb/24104 "x86_64-*-linux*"
+ }
gdb_test "p/d check_arg_${name} (ref_val_${name})" "= 1"
set refval [ get_valueof "" "ref_val_${name}" "" ]
@@ -113,8 +138,13 @@ proc run_tests {} {
set test "check return value ${name}"
if { ${refval} != "" } {
+
set answer [ get_valueof "" "rtn_str_${name} ()" "XXXX"]
verbose -log "Answer: ${answer}"
+
+ if { ($lang == "c++" && $name == "struct_02_01" && [regexp "^types-(tf-t(c|s|i)|t(c|s|i)-tf)" $types match] ) } {
+ setup_xfail gdb/24104 "x86_64-*-linux*"
+ }
gdb_assert [string eq ${answer} ${refval}] ${test}
} else {
unresolved $test
@@ -125,48 +155,50 @@ proc run_tests {} {
# Set up a test prefix, compile the test binary, run to main, and then
# run some tests.
-proc start_gdb_and_run_tests { types } {
+proc start_gdb_and_run_tests { lang types } {
set prefix "types"
foreach t $types {
append prefix "-" "${t}"
}
- with_test_prefix $prefix {
- if { [start_nested_structs_test $types] } {
- run_tests
+ foreach_with_prefix l $lang {
+ with_test_prefix $prefix {
+ if { [start_nested_structs_test $l $types] } {
+ run_tests $l $prefix
+ }
}
}
}
foreach ta $int_types {
- start_gdb_and_run_tests $ta
+ start_gdb_and_run_tests $lang $ta
}
if [support_complex_tests] {
foreach ta $complex_types {
- start_gdb_and_run_tests $ta
+ start_gdb_and_run_tests $lang $ta
}
}
if ![gdb_skip_float_test] {
foreach ta $float_types {
- start_gdb_and_run_tests $ta
+ start_gdb_and_run_tests $lang $ta
}
foreach ta $int_types {
foreach tb $float_types {
- start_gdb_and_run_tests [list $ta $tb]
+ start_gdb_and_run_tests $lang [list $ta $tb]
}
}
foreach ta $float_types {
foreach tb $int_types {
- start_gdb_and_run_tests [list $ta $tb]
+ start_gdb_and_run_tests $lang [list $ta $tb]
}
foreach tb $float_types {
- start_gdb_and_run_tests [list $ta $tb]
+ start_gdb_and_run_tests $lang [list $ta $tb]
}
}
}