gdb/aarch64: Use type_align instead of aarch64_type_align

Replaces use of aarch64_type_align with common type_align function.

Doing this fixes a bug in aarch64_type_align where static fields are
considered as part of the alignment calculation of a struct, which
results in arguments passed on the stack being misaligned.  This bug
is exposed in the new test gdb.cp/many-args.exp.

Part of the old aarch64_type_align is retained and used as the gdbarch
type align callback in order to correctly align vectors.

gdb/ChangeLog:

	* aarch64-tdep.c (aarch64_type_align): Only handle vector override
	case.
	(pass_on_stack): Use type_align.
	(aarch64_gdbarch_init): Register aarch64_type_align gdbarch
	function.

gdb/testsuite/ChangeLog:

	* gdb.cp/many-args.cc: New file.
	* gdb.cp/many-args.exp: New file.
This commit is contained in:
Andrew Burgess 2019-04-07 22:48:00 +01:00
parent 9e97ba436a
commit b907456c3e
5 changed files with 144 additions and 51 deletions

View File

@ -1,3 +1,11 @@
2019-04-23 Andrew Burgess <andrew.burgess@embecosm.com>
* aarch64-tdep.c (aarch64_type_align): Only handle vector override
case.
(pass_on_stack): Use type_align.
(aarch64_gdbarch_init): Register aarch64_type_align gdbarch
function.
2019-04-23 Tom Tromey <tromey@adacore.com>
* dwarf2read.c (line_header::file_name_at): Remove unused

View File

@ -1218,62 +1218,25 @@ typedef struct
DEF_VEC_O (stack_item_t);
/* Return the alignment (in bytes) of the given type. */
/* Implement the gdbarch type alignment method, overrides the generic
alignment algorithm for anything that is aarch64 specific. */
static int
aarch64_type_align (struct type *t)
static ULONGEST
aarch64_type_align (gdbarch *gdbarch, struct type *t)
{
int n;
int align;
int falign;
t = check_typedef (t);
switch (TYPE_CODE (t))
if (TYPE_CODE (t) == TYPE_CODE_ARRAY && TYPE_VECTOR (t))
{
default:
/* Should never happen. */
internal_error (__FILE__, __LINE__, _("unknown type alignment"));
return 4;
case TYPE_CODE_PTR:
case TYPE_CODE_ENUM:
case TYPE_CODE_INT:
case TYPE_CODE_FLT:
case TYPE_CODE_SET:
case TYPE_CODE_RANGE:
case TYPE_CODE_BITSTRING:
case TYPE_CODE_REF:
case TYPE_CODE_RVALUE_REF:
case TYPE_CODE_CHAR:
case TYPE_CODE_BOOL:
return TYPE_LENGTH (t);
case TYPE_CODE_ARRAY:
if (TYPE_VECTOR (t))
{
/* Use the natural alignment for vector types (the same for
scalar type), but the maximum alignment is 128-bit. */
if (TYPE_LENGTH (t) > 16)
return 16;
else
return TYPE_LENGTH (t);
}
/* Use the natural alignment for vector types (the same for
scalar type), but the maximum alignment is 128-bit. */
if (TYPE_LENGTH (t) > 16)
return 16;
else
return aarch64_type_align (TYPE_TARGET_TYPE (t));
case TYPE_CODE_COMPLEX:
return aarch64_type_align (TYPE_TARGET_TYPE (t));
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
align = 1;
for (n = 0; n < TYPE_NFIELDS (t); n++)
{
falign = aarch64_type_align (TYPE_FIELD_TYPE (t, n));
if (falign > align)
align = falign;
}
return align;
return TYPE_LENGTH (t);
}
/* Allow the common code to calculate the alignment. */
return 0;
}
/* Worker function for aapcs_is_vfp_call_or_return_candidate.
@ -1540,7 +1503,7 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type,
info->argnum++;
align = aarch64_type_align (type);
align = type_align (type);
/* PCS C.17 Stack should be aligned to the larger of 8 bytes or the
Natural alignment of the argument's type. */
@ -3370,6 +3333,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
set_gdbarch_type_align (gdbarch, aarch64_type_align);
/* Internal <-> external register number maps. */
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum);

View File

@ -1,3 +1,8 @@
2019-04-23 Andrew Burgess <andrew.burgess@embecosm.com>
* gdb.cp/many-args.cc: New file.
* gdb.cp/many-args.exp: New file.
2019-04-23 Tom de Vries <tdevries@suse.de>
PR gdb/24433

View File

@ -0,0 +1,76 @@
/* Copyright 2019 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <string.h>
/* Vector type will align on a 16-byte boundary. */
typedef int v4si __attribute__ ((vector_size (16)));
struct ss
{
static v4si static_field;
unsigned char aa;
bool operator== (const ss &rhs)
{
return (memcmp (&this->static_field, &rhs.static_field,
sizeof (this->static_field)) == 0
&& this->aa == rhs.aa);
}
};
v4si ss::static_field = { 1, 2, 3, 4 };
ss ref_val = { 'a' };
bool
check_val (ss v1, ss v2, ss v3, ss v4, ss v5, ss v6, ss v7, ss v8,
ss v9, ss v10, ss v11, ss v12, ss v13, ss v14, ss v15,
ss v16, ss v17, ss v18, ss v19, ss v20, ss v21, ss v22,
ss v23, ss v24, ss v25, ss v26, ss v27, ss v28, ss v29,
ss v30, ss v31, ss v32, ss v33, ss v34, ss v35, ss v36,
ss v37, ss v38, ss v39, ss v40)
{
return (v1 == ref_val && v2 == ref_val && v3 == ref_val && v4 == ref_val
&& v5 == ref_val && v6 == ref_val && v7 == ref_val
&& v8 == ref_val && v9 == ref_val && v10 == ref_val
&& v11 == ref_val && v12 == ref_val && v13 == ref_val
&& v14 == ref_val && v15 == ref_val && v16 == ref_val
&& v17 == ref_val && v18 == ref_val && v19 == ref_val
&& v20 == ref_val && v21 == ref_val && v22 == ref_val
&& v23 == ref_val && v24 == ref_val && v25 == ref_val
&& v26 == ref_val && v27 == ref_val && v28 == ref_val
&& v29 == ref_val && v30 == ref_val && v31 == ref_val
&& v32 == ref_val && v33 == ref_val && v34 == ref_val
&& v35 == ref_val && v36 == ref_val && v37 == ref_val
&& v38 == ref_val && v39 == ref_val && v40 == ref_val);
}
int
main ()
{
bool flag = check_val (ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val,
ref_val, ref_val, ref_val, ref_val, ref_val);
return (flag ? 0 : 1); /* break-here */
}

View File

@ -0,0 +1,40 @@
# Copyright 2019 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This tests GDB's ability to call an inferior function passing many
# structures by value. Other tests that call inferior functions with
# structures only pass one or two structures, and these are often
# passed in registers. This test passes so many structures it is
# hoped that some will need to be placed onto the stack.
if { [skip_cplus_tests] } { continue }
standard_testfile .cc
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
return -1
}
if ![runto_main] {
perror "couldn't run to breakpoint"
continue
}
gdb_breakpoint [gdb_get_line_number "break-here"]
gdb_continue_to_breakpoint "break-here"
gdb_test "p check_val (ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val, ref_val)" \
"= true" \
"check passing many structures"