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:
parent
9e97ba436a
commit
b907456c3e
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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"
|
Loading…
Reference in New Issue