!164 [sync] PR-163: [backport] fix riscv64 aggregate type return value location retrieval …

From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
This commit is contained in:
openeuler-ci-bot 2025-04-27 03:02:38 +00:00 committed by Gitee
commit 4a18b123ee
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 166 additions and 1 deletions

View File

@ -0,0 +1,157 @@
Signed-off-by: malachite <malachiten@outlook.com>
diff --git a/backends/riscv_retval.c b/backends/riscv_retval.c
index 0a1e02f..50c451a 100644
--- a/backends/riscv_retval.c
+++ b/backends/riscv_retval.c
@@ -1,6 +1,7 @@
/* Function return value location for Linux/RISC-V ABI.
Copyright (C) 2018 Sifive, Inc.
Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2024 Mark J. Wielaard <mark@klomp.org>
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -105,23 +106,123 @@ pass_in_fpr_lp64d (const Dwarf_Op **locp, Dwarf_Word size)
return size <= 8 ? 1 : 4;
}
+/* Checks if we can "flatten" the given type, Only handles the simple
+ cases where we have a struct with one or two the same base type
+ elements. */
static int
-flatten_aggregate_arg (Dwarf_Die *typedie __attribute__ ((unused)),
- Dwarf_Die *arg0 __attribute__ ((unused)),
- Dwarf_Die *arg1 __attribute__ ((unused)))
+flatten_aggregate_arg (Dwarf_Die *typedie,
+ Dwarf_Word size,
+ Dwarf_Die *arg0,
+ Dwarf_Die *arg1)
{
- /* ??? */
+ int tag0, tag1;
+ Dwarf_Die member;
+ Dwarf_Word encoding0, encoding1;
+ Dwarf_Attribute attr;
+ Dwarf_Word size0, size1;
+
+ if (size < 8 || size > 16)
+ return 0;
+
+ if (dwarf_child (typedie, arg0) != 0)
+ return 0;
+
+ tag0 = dwarf_tag (arg0);
+ while (tag0 != -1 && tag0 != DW_TAG_member)
+ {
+ if (dwarf_siblingof (arg0, arg0) != 0)
+ return 0;
+ tag0 = dwarf_tag (arg0);
+ }
+
+ if (tag0 != DW_TAG_member)
+ return 0;
+
+ /* Remember where we are. */
+ member = *arg0;
+
+ tag0 = dwarf_peeled_die_type (arg0, arg0);
+ if (tag0 != DW_TAG_base_type)
+ return 0;
+
+ if (dwarf_attr_integrate (arg0, DW_AT_encoding, &attr) == NULL
+ || dwarf_formudata (&attr, &encoding0) != 0)
+ return 0;
+
+ if (dwarf_bytesize_aux (arg0, &size0) != 0)
+ return 0;
+
+ if (size == size0)
+ return 1; /* This one member is the whole size. */
+
+ if (size != 2 * size0)
+ return 0; /* We only handle two of the same. */
+
+ /* Look for another member with the same encoding. */
+ if (dwarf_siblingof (&member, arg1) != 0)
+ return 0;
+
+ tag1 = dwarf_tag (arg1);
+ while (tag1 != -1 && tag1 != DW_TAG_member)
+ {
+ if (dwarf_siblingof (arg1, arg1) != 0)
+ return 0;
+ tag1 = dwarf_tag (arg1);
+ }
+
+ if (tag1 != DW_TAG_member)
+ return 0;
+
+ tag1 = dwarf_peeled_die_type (arg1, arg1);
+ if (tag1 != DW_TAG_base_type)
+ return 0; /* We can only handle two equal base types for now. */
+
+ if (dwarf_attr_integrate (arg1, DW_AT_encoding, &attr) == NULL
+ || dwarf_formudata (&attr, &encoding1) != 0
+ || encoding0 != encoding1)
+ return 0; /* We can only handle two of the same for now. */
+
+ if (dwarf_bytesize_aux (arg1, &size1) != 0)
+ return 0;
+
+ if (size0 != size1)
+ return 0; /* We can only handle two of the same for now. */
+
return 1;
}
+/* arg0 and arg1 should be the peeled die types found by
+ flatten_aggregate_arg. */
static int
-pass_by_flattened_arg (const Dwarf_Op **locp __attribute__ ((unused)),
- Dwarf_Word size __attribute__ ((unused)),
- Dwarf_Die *arg0 __attribute__ ((unused)),
- Dwarf_Die *arg1 __attribute__ ((unused)))
+pass_by_flattened_arg (const Dwarf_Op **locp,
+ Dwarf_Word size,
+ Dwarf_Die *arg0,
+ Dwarf_Die *arg1 __attribute__((unused)))
{
- /* ??? */
- return -2;
+ /* For now we just assume arg0 and arg1 are the same type and
+ encoding. */
+ Dwarf_Word encoding;
+ Dwarf_Attribute attr;
+
+ if (dwarf_attr_integrate (arg0, DW_AT_encoding, &attr) == NULL
+ || dwarf_formudata (&attr, &encoding) != 0)
+ return -1;
+
+ switch (encoding)
+ {
+ case DW_ATE_boolean:
+ case DW_ATE_signed:
+ case DW_ATE_unsigned:
+ case DW_ATE_unsigned_char:
+ case DW_ATE_signed_char:
+ return pass_in_gpr_lp64 (locp, size);
+
+ case DW_ATE_float:
+ return pass_in_fpr_lp64d (locp, size);
+
+ default:
+ return -1;
+ }
}
int
@@ -158,7 +259,7 @@ riscv_return_value_location_lp64ifd (int fp, Dwarf_Die *functypedie,
provided the floating-point real is no more than FLEN bits wide and
the integer is no more than XLEN bits wide. */
if (tag == DW_TAG_structure_type
- && flatten_aggregate_arg (&typedie, &arg0, &arg1))
+ && flatten_aggregate_arg (&typedie, size, &arg0, &arg1))
return pass_by_flattened_arg (locp, size, &arg0, &arg1);
/* Aggregates larger than 2*XLEN bits are passed by reference. */
else if (size > 16)

View File

@ -1,7 +1,7 @@
# -*- rpm-spec from http://elfutils.org/ -*-
Name: elfutils
Version: 0.190
Release: 9
Release: 10
Summary: A collection of utilities and DSOs to handle ELF files and DWARF data
URL: http://elfutils.org/
License: GPLv3+ and (GPLv2+ or LGPLv3+)
@ -12,6 +12,7 @@ Patch1: Fix-issue-of-moving-files-by-ar-or-br.patch
Patch2: CVE-2024-25260.patch
Patch3: Backport-fix-handling-of-corefiles-with-non-contiguous-segments.patch
Patch4: add-sw_64-support.patch
Patch5: backport-fix-riscv64-return-value-location-retrieval-implementation.patch
Patch6000: backport-CVE-2025-1352.patch
Patch6001: backport-CVE-2025-1365.patch
@ -185,6 +186,7 @@ such servers to download those files on demand.
%ifarch sw_64
%patch4 -p1
%endif
%patch5 -p1
%patch6000 -p1
%patch6001 -p1
@ -346,6 +348,12 @@ exit 0
%systemd_postun_with_restart debuginfod.service
%changelog
* Thu Apr 10 2025 yuanchicheng <chicheng.oerv@isrc.iscas.ac.cn> - 0.190-10
- Type: bugfix
- CVE: NA
- SUG: NA
- DESC: backport-fix-riscv64-return-value-location-retrieval-implementation.patch
* Wed Mar 12 2025 mahailiang <mahailiang@uniontech.com> - 0.190-9
- add sw_64 support