[dwarf] Mark all functions as prototyped except C functions.

This makes sure that the types of the arguments are taken into account
when performing an inferior function call to a non-C (or C-like)
function.  In particular, this makes sure that the arguments are
appropriatly converted to the correct type.

For instance, on x86_64-linux, with the following Ada code:

   procedure Set_Float (F : Float) is
   begin
      Global_Float := F;
   end Set_Float;

The following sequence shows that Float arguments are incorrectly
passed (Ada's Float type is the equivalent of type "float" in C):

    (gdb) call set_float (2.0)
    (gdb) print global_float
    $1 = 0.0

Putting a breakpoint inside set_float to inspect the value of
register xmm0 gives the first hint of the problem:

    (gdb) p $xmm0
    $2 = (v4_float => (0 => 0.0, 2.0, 0.0, 0.0),
          v2_double => (0 => 2.0, 0.0),
    [...]

It shows that the argument was passed as a double.

The code responsible for doing appropriate type conversions
for the arguments (value_arg_coerce) found that our function
was not prototyped, and thus could not use typing information
for the arguments. Instead, it defaulted to the value of "set
coerce-float-to-double", which by default is true, to determine
the argument type.

This patch fixes the problem by setting the PROTOTYPE flag
for all functions of any language except C and Objective C.

gdb/ChangeLog:

        * dwarf2read.c (prototyped_function_p): New function.
        (read_subroutine_type): Use it.

gdb/testsuite/ChangeLog:

        * gdb.ada/float_param: New testcase.
This commit is contained in:
Joel Brobecker 2013-05-20 09:45:13 +00:00
parent 1c432e72b0
commit 4d804846db
7 changed files with 174 additions and 12 deletions

View File

@ -1,3 +1,8 @@
2013-05-20 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (prototyped_function_p): New function.
(read_subroutine_type): Use it.
2013-05-20 Joel Brobecker <brobecker@adacore.com>
* rs6000-aix-tdep.c: De-indent some example code provided

View File

@ -12600,6 +12600,38 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, type, cu);
}
/* Assuming that DIE corresponds to a function, returns nonzero
if the function is prototyped. */
static int
prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if (attr && (DW_UNSND (attr) != 0))
return 1;
/* The DWARF standard implies that the DW_AT_prototyped attribute
is only meaninful for C, but the concept also extends to other
languages that allow unprototyped functions (Eg: Objective C).
For all other languages, assume that functions are always
prototyped. */
if (cu->language != language_c
&& cu->language != language_objc
&& cu->language != language_opencl)
return 1;
/* RealView does not emit DW_AT_prototyped. We can not distinguish
prototyped and unprototyped functions; default to prototyped,
since that is more common in modern code (and RealView warns
about unprototyped functions). */
if (producer_is_realview (cu->producer))
return 1;
return 0;
}
/* Handle DIES due to C code like:
struct foo
@ -12627,18 +12659,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
ftype = lookup_function_type (type);
/* All functions in C++, Pascal and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
|| cu->language == language_cplus
|| cu->language == language_java
|| cu->language == language_pascal)
TYPE_PROTOTYPED (ftype) = 1;
else if (producer_is_realview (cu->producer))
/* RealView does not emit DW_AT_prototyped. We can not
distinguish prototyped and unprototyped functions; default to
prototyped, since that is more common in modern code (and
RealView warns about unprototyped functions). */
if (prototyped_function_p (die, cu))
TYPE_PROTOTYPED (ftype) = 1;
/* Store the calling convention in the type if it's available in

View File

@ -1,3 +1,7 @@
2013-05-20 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/float_param: New testcase.
2013-05-17 Doug Evans <dje@google.com>
* gdb.base/maint.exp: Update test for "maint check-psymtabs".

View File

@ -0,0 +1,43 @@
# Copyright 2013 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/>.
load_lib "ada.exp"
if { [skip_ada_tests] } { return -1 }
standard_ada_testfile foo
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
return -1
}
clean_restart ${testfile}
set bp_location [gdb_get_line_number "START" ${testdir}/foo.adb]
runto "foo.adb:$bp_location"
gdb_test_no_output "call set_float(2.0)"
gdb_test "print global_float" \
" = 2\\.0"
gdb_test_no_output "call set_double(1, 3.0)"
gdb_test "print global_double" \
" = 3\\.0"
gdb_test_no_output "call set_long_double(1, global_small_struct, 4.0)"
gdb_test "print global_long_double" \
" = 4\\.0"

View File

@ -0,0 +1,23 @@
-- Copyright 2013 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/>.
with Pck; use Pck;
procedure Foo is
begin
Set_Float (1.0); -- START
Set_Double (1, 1.0);
Set_Long_Double (1, (I => 2), 1.0);
end Foo;

View File

@ -0,0 +1,35 @@
-- Copyright 2013 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/>.
package body Pck is
procedure Set_Float (F : Float) is
begin
Global_Float := F;
end Set_Float;
procedure Set_Double (Dummy : Integer; D : Long_Float) is
begin
Global_Double := D;
end Set_Double;
procedure Set_Long_Double (Dummy : Integer;
DS : Small_Struct;
LD : Long_Long_Float) is
begin
Global_Long_Double := LD;
end Set_Long_Double;
end Pck;

View File

@ -0,0 +1,31 @@
-- Copyright 2013 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/>.
package Pck is
Global_Float : Float := 0.0;
Global_Double : Long_Float := 0.0;
Global_Long_Double : Long_Long_Float := 0.0;
type Small_Struct is record
I : Integer;
end record;
Global_Small_Struct : Small_Struct := (I => 0);
procedure Set_Float (F : Float);
procedure Set_Double (Dummy : Integer; D : Long_Float);
procedure Set_Long_Double (Dummy : Integer;
DS: Small_Struct;
LD : Long_Long_Float);
end Pck;