[RFC] backends: Add RISC-V object attribute printing

Message ID mvmedxojvmv.fsf@suse.de
State RFC
Headers
Series [RFC] backends: Add RISC-V object attribute printing |

Commit Message

Andreas Schwab Aug. 10, 2022, 9:27 a.m. UTC
  This does not work yet.  The RISC-V attribute tags use the same
convention as the GNU attributes: odd numbered tags take a string value,
even numbered ones an integer value, but print_attributes assumes the
ARM numbering scheme by default for non-GNU attributes.

---
 backends/ChangeLog     |  6 ++++
 backends/Makefile.am   |  3 +-
 backends/riscv_attrs.c | 80 ++++++++++++++++++++++++++++++++++++++++++
 backends/riscv_init.c  |  2 ++
 4 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 backends/riscv_attrs.c
  

Comments

Mark Wielaard Oct. 13, 2022, 2:53 p.m. UTC | #1
Hi Andreas,

On Wed, 2022-08-10 at 11:27 +0200, Andreas Schwab via Elfutils-devel
wrote:
> This does not work yet.  The RISC-V attribute tags use the same
> convention as the GNU attributes: odd numbered tags take a string
> value,
> even numbered ones an integer value, but print_attributes assumes the
> ARM numbering scheme by default for non-GNU attributes.

Yeah, I see this comment in print_attributes:

         /* GNU style tags have either a uleb128 value,
            when lowest bit is not set, or a string
            when the lowest bit is set.
            "compatibility" (32) is special.  It has
            both a string and a uleb128 value.  For
            non-gnu we assume 6 till 31 only take ints.
            XXX see arm backend, do we need a separate
            hook?  */

Maybe we need a flag in the backend to tell whether attributes follow
the "gnu_vendor" convention? So that could be checked at:

          bool gnu_vendor = (q - name == sizeof "gnu"
                             && !memcmp (name, "gnu", sizeof "gnu"));
          gnu_vendor |= ebl->has_gnu_attributes;

Or something similar?

Cheers,

Mark
  
Martin Liška Nov. 25, 2022, 4:29 p.m. UTC | #2
On 10/13/22 16:53, Mark Wielaard wrote:
> Hi Andreas,
> 
> On Wed, 2022-08-10 at 11:27 +0200, Andreas Schwab via Elfutils-devel
> wrote:
>> This does not work yet.  The RISC-V attribute tags use the same
>> convention as the GNU attributes: odd numbered tags take a string
>> value,
>> even numbered ones an integer value, but print_attributes assumes the
>> ARM numbering scheme by default for non-GNU attributes.
> 
> Yeah, I see this comment in print_attributes:
> 
>          /* GNU style tags have either a uleb128 value,
>             when lowest bit is not set, or a string
>             when the lowest bit is set.
>             "compatibility" (32) is special.  It has
>             both a string and a uleb128 value.  For
>             non-gnu we assume 6 till 31 only take ints.
>             XXX see arm backend, do we need a separate
>             hook?  */
> 
> Maybe we need a flag in the backend to tell whether attributes follow
> the "gnu_vendor" convention? So that could be checked at:
> 
>           bool gnu_vendor = (q - name == sizeof "gnu"
>                              && !memcmp (name, "gnu", sizeof "gnu"));
>           gnu_vendor |= ebl->has_gnu_attributes;
> 
> Or something similar?

Andreas: Can you please take a look at this?

Martin

> 
> Cheers,
> 
> Mark
  
Mark Wielaard Feb. 22, 2023, 10:56 p.m. UTC | #3
Hi,

On Fri, Nov 25, 2022 at 05:29:19PM +0100, Martin Liška wrote:
> On 10/13/22 16:53, Mark Wielaard wrote:
> > On Wed, 2022-08-10 at 11:27 +0200, Andreas Schwab via Elfutils-devel
> > wrote:
> >> This does not work yet.  The RISC-V attribute tags use the same
> >> convention as the GNU attributes: odd numbered tags take a string
> >> value,
> >> even numbered ones an integer value, but print_attributes assumes the
> >> ARM numbering scheme by default for non-GNU attributes.
> > 
> > Yeah, I see this comment in print_attributes:
> > 
> >          /* GNU style tags have either a uleb128 value,
> >             when lowest bit is not set, or a string
> >             when the lowest bit is set.
> >             "compatibility" (32) is special.  It has
> >             both a string and a uleb128 value.  For
> >             non-gnu we assume 6 till 31 only take ints.
> >             XXX see arm backend, do we need a separate
> >             hook?  */
> > 
> > Maybe we need a flag in the backend to tell whether attributes follow
> > the "gnu_vendor" convention? So that could be checked at:
> > 
> >           bool gnu_vendor = (q - name == sizeof "gnu"
> >                              && !memcmp (name, "gnu", sizeof "gnu"));
> >           gnu_vendor |= ebl->has_gnu_attributes;
> > 
> > Or something similar?
> 
> Andreas: Can you please take a look at this?

Has anybody had time to look at this?

Thanks,

Mark
  
Martin Liška Feb. 24, 2023, 8:55 a.m. UTC | #4
@Andreas: Can you take a look?

Martin

On 2/22/23 23:56, Mark Wielaard wrote:
> Hi,
> 
> On Fri, Nov 25, 2022 at 05:29:19PM +0100, Martin Liška wrote:
>> On 10/13/22 16:53, Mark Wielaard wrote:
>>> On Wed, 2022-08-10 at 11:27 +0200, Andreas Schwab via Elfutils-devel
>>> wrote:
>>>> This does not work yet.  The RISC-V attribute tags use the same
>>>> convention as the GNU attributes: odd numbered tags take a string
>>>> value,
>>>> even numbered ones an integer value, but print_attributes assumes the
>>>> ARM numbering scheme by default for non-GNU attributes.
>>>
>>> Yeah, I see this comment in print_attributes:
>>>
>>>          /* GNU style tags have either a uleb128 value,
>>>             when lowest bit is not set, or a string
>>>             when the lowest bit is set.
>>>             "compatibility" (32) is special.  It has
>>>             both a string and a uleb128 value.  For
>>>             non-gnu we assume 6 till 31 only take ints.
>>>             XXX see arm backend, do we need a separate
>>>             hook?  */
>>>
>>> Maybe we need a flag in the backend to tell whether attributes follow
>>> the "gnu_vendor" convention? So that could be checked at:
>>>
>>>           bool gnu_vendor = (q - name == sizeof "gnu"
>>>                              && !memcmp (name, "gnu", sizeof "gnu"));
>>>           gnu_vendor |= ebl->has_gnu_attributes;
>>>
>>> Or something similar?
>>
>> Andreas: Can you please take a look at this?
> 
> Has anybody had time to look at this?
> 
> Thanks,
> 
> Mark
  

Patch

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 5b0daffe..a642fe9e 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,9 @@ 
+2022-08-10  Andreas Schwab  <schwab@suse.de>
+
+	* Makefile.am (riscv_SRCS): Add riscv_attrs.c.
+	* riscv_init.c (riscv_init): Hook in riscv_check_object_attribute.
+	* riscv_attrs.c: New file.
+
 2022-08-09  Andreas Schwab  <schwab@suse.de>
 
 	* riscv_init.c (riscv_init): HOOK segment_type_name,
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 9566377f..1863f66a 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -91,7 +91,8 @@  m68k_corenote_no_Wpacked_not_aligned = yes
 bpf_SRCS = bpf_init.c bpf_regs.c bpf_symbol.c
 
 riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c \
-	     riscv_initreg.c riscv_corenote.c riscv64_corenote.c riscv_retval.c
+	     riscv_initreg.c riscv_corenote.c riscv64_corenote.c \
+	     riscv_retval.c riscv_attrs.c
 
 csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \
 	    csky_regs.c csky_initreg.c csky_corenote.c
diff --git a/backends/riscv_attrs.c b/backends/riscv_attrs.c
new file mode 100644
index 00000000..6947be6e
--- /dev/null
+++ b/backends/riscv_attrs.c
@@ -0,0 +1,80 @@ 
+/* Object attribute tags for RISC-V.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND riscv_
+#include "libebl_CPU.h"
+
+#define KNOWN_VALUES(...) do				\
+  {							\
+    static const char *table[] = { __VA_ARGS__ };	\
+    if (value < sizeof table / sizeof table[0])		\
+      *value_name = table[value];			\
+  } while (0)
+
+bool
+riscv_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+			      const char *vendor, int tag, uint64_t value,
+			      const char **tag_name, const char **value_name)
+{
+  if (!strcmp (vendor, "riscv"))
+    switch (tag)
+      {
+      case 4:
+	*tag_name = "RISCV_stack_align";
+	return true;
+
+      case 5:
+	*tag_name = "RISCV_arch";
+	return true;
+
+      case 6:
+	*tag_name = "RISCV_unaligned_access";
+	KNOWN_VALUES ("No unaligned access", "Unaligned access");
+	return true;
+
+      case 8:
+	*tag_name = "RISCV_priv_spec";
+	return true;
+
+      case 10:
+        *tag_name = "RISCV_priv_spec_minor";
+        return true;
+
+      case 12:
+        *tag_name = "RISCV_priv_spec_revision";
+        return true;
+      }
+
+  return false;
+}
diff --git a/backends/riscv_init.c b/backends/riscv_init.c
index f2d46082..e5e9e33e 100644
--- a/backends/riscv_init.c
+++ b/backends/riscv_init.c
@@ -69,6 +69,8 @@  riscv_init (Elf *elf,
   HOOK (eh, section_type_name);
   HOOK (eh, dynamic_tag_name);
   HOOK (eh, dynamic_tag_check);
+  HOOK (eh, check_object_attribute);
+  HOOK (eh, set_initial_registers_tid);
   if (eh->class == ELFCLASS64)
     eh->core_note = riscv64_core_note;
   else