public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: PR27925 Add support for LP64 and LP64F ABIs return values
@ 2021-09-29 18:56 William Cohen
  0 siblings, 0 replies; only message in thread
From: William Cohen @ 2021-09-29 18:56 UTC (permalink / raw)
  To: elfutils-devel; +Cc: William Cohen

The RISC-V Linux kernel is compiled without floating point (the LP64
ABI) and elfutils could not obtain return value locations for
functions in the kernel.  This issue was noticed when Systemtap
generated RISC-V kernel modules for scripts that used $return target
variables in function return probes. This patch adds the needed
support to provide return value information for the LP64 and LP64F
ABIs.

Signed-off-by: William Cohen <wcohen@redhat.com>
---
 backends/riscv_init.c   | 20 ++++++++---
 backends/riscv_retval.c | 73 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/backends/riscv_init.c b/backends/riscv_init.c
index 551e7bb6..8389d8cd 100644
--- a/backends/riscv_init.c
+++ b/backends/riscv_init.c
@@ -41,6 +41,12 @@
 extern __typeof (EBLHOOK (return_value_location))
   riscv_return_value_location_lp64d attribute_hidden;
 
+extern __typeof (EBLHOOK (return_value_location))
+  riscv_return_value_location_lp64f attribute_hidden;
+
+extern __typeof (EBLHOOK (return_value_location))
+  riscv_return_value_location_lp64 attribute_hidden;
+
 extern __typeof (EBLHOOK (core_note)) riscv64_core_note attribute_hidden;
 
 Ebl *
@@ -63,10 +69,16 @@ riscv_init (Elf *elf,
     eh->core_note = riscv64_core_note;
   else
     HOOK (eh, core_note);
-  if (eh->class == ELFCLASS64
-      && ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI)
-	  == EF_RISCV_FLOAT_ABI_DOUBLE))
-    eh->return_value_location = riscv_return_value_location_lp64d;
+  if (eh->class == ELFCLASS64){
+    if ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI)
+	== EF_RISCV_FLOAT_ABI_DOUBLE)
+      eh->return_value_location = riscv_return_value_location_lp64d;
+    else if ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI)
+	== EF_RISCV_FLOAT_ABI_SINGLE)
+      eh->return_value_location = riscv_return_value_location_lp64f;
+    else
+      eh->return_value_location = riscv_return_value_location_lp64;
+  }
 
   return eh;
 }
diff --git a/backends/riscv_retval.c b/backends/riscv_retval.c
index 35b6010b..95d9b453 100644
--- a/backends/riscv_retval.c
+++ b/backends/riscv_retval.c
@@ -40,6 +40,7 @@
 #define BACKEND riscv_
 #include "libebl_CPU.h"
 
+
 static int
 dwarf_bytesize_aux (Dwarf_Die *die, Dwarf_Word *sizep)
 {
@@ -125,8 +126,9 @@ pass_by_flattened_arg (const Dwarf_Op **locp __attribute__ ((unused)),
 }
 
 int
-riscv_return_value_location_lp64d (Dwarf_Die *functypedie,
-				   const Dwarf_Op **locp)
+riscv_return_value_location_lp64ifd (int fp,
+				  Dwarf_Die *functypedie,
+				  const Dwarf_Op **locp)
 {
   /* Start with the function's type, and get the DW_AT_type attribute,
      which is the type of the return value.  */
@@ -211,8 +213,25 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie,
 	      switch (size)
 		{
 		case 4: /* single */
+		  switch (fp){
+		  case EF_RISCV_FLOAT_ABI_DOUBLE:
+		  case EF_RISCV_FLOAT_ABI_SINGLE:
+		    return pass_in_fpr_lp64d (locp, size);
+		  case EF_RISCV_FLOAT_ABI_SOFT:
+		    return pass_in_gpr_lp64 (locp, size);
+		  default:
+		    return -2;
+		  }
 		case 8: /* double */
-		  return pass_in_fpr_lp64d (locp, size);
+		  switch (fp){
+		  case EF_RISCV_FLOAT_ABI_DOUBLE:
+		    return pass_in_fpr_lp64d (locp, size);
+		  case EF_RISCV_FLOAT_ABI_SINGLE:
+		  case EF_RISCV_FLOAT_ABI_SOFT:
+		    return pass_in_gpr_lp64 (locp, size);
+		  default:
+		    return -2;
+		  }
 
 		case 16: /* quad */
 		  return pass_in_gpr_lp64 (locp, size);
@@ -227,10 +246,27 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie,
 	      switch (size)
 		{
 		case 8: /* float _Complex */
-		  return pass_in_fpr_lp64f (locp, size);
+		  switch (fp){
+		  case EF_RISCV_FLOAT_ABI_DOUBLE:
+		  case EF_RISCV_FLOAT_ABI_SINGLE:
+		    return pass_in_fpr_lp64f (locp, size);
+		  case EF_RISCV_FLOAT_ABI_SOFT:
+		    /* Double the size so the vals are two registers. */
+		    return pass_in_gpr_lp64 (locp, size*2);
+		  default:
+		    return -2;
+		  }
 
 		case 16: /* double _Complex */
-		  return pass_in_fpr_lp64d (locp, size);
+		  switch (fp){
+		  case EF_RISCV_FLOAT_ABI_DOUBLE:
+		    return pass_in_fpr_lp64d (locp, size);
+		  case EF_RISCV_FLOAT_ABI_SINGLE:
+		  case EF_RISCV_FLOAT_ABI_SOFT:
+		    return pass_in_gpr_lp64 (locp, size);
+		  default:
+		    return -2;
+		  }
 
 		case 32: /* long double _Complex */
 		  return pass_by_ref (locp);
@@ -249,3 +285,30 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie,
   *locp = NULL;
   return 0;
 }
+
+int
+riscv_return_value_location_lp64d (Dwarf_Die *functypedie,
+				   const Dwarf_Op **locp)
+{
+  return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_DOUBLE,
+					   functypedie,
+					   locp);
+}
+
+int
+riscv_return_value_location_lp64f (Dwarf_Die *functypedie,
+				   const Dwarf_Op **locp)
+{
+  return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_SINGLE,
+					   functypedie,
+					   locp);
+}
+
+int
+riscv_return_value_location_lp64 (Dwarf_Die *functypedie,
+				   const Dwarf_Op **locp)
+{
+  return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_SOFT,
+					   functypedie,
+					   locp);
+}
-- 
2.31.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-09-29 18:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-29 18:56 [PATCH] RISC-V: PR27925 Add support for LP64 and LP64F ABIs return values William Cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).