[RFC] RISC-V: Set rvc elf_flags according to mapping symbols
Nelson Chu
nelson@rivosinc.com
Fri Oct 24 01:57:07 GMT 2025
According to riscv psabi mentions rvc elf_flags,
This bit is set when the binary targets the C ABI, which allows instructions
to be aligned to 16-bit boundaries (the base RV32 and RV64 ISAs only allow
32-bit instruction alignment).
There are several ways to enable/disable c/zca extension for current assembler.
The following list the setting orders,
1. --with-arch configure option
2. -march option
3. .attribute directive
4. .option arch/rvc/norvc
Once the c/zca extensions are enabled in the above four cases, the current
assembler will set rvc elf_flags, even if the code hasn't been affected by
c/zca at all. For example,
% cat a.s
.text
.option norvc
norvc_func:
nop
% riscv64-unknown-elf-as -march=rv32ic a.s -o a.o
% riscv64-unknown-elf-objdump -d a.o
...
Disassembly of section .text:
00000000 <norvc_func>:
0: 00000013 nop
% riscv64-unknown-elf-readelf -hs a.o
ELF Header:
...
Flags: 0x1, RVC, soft-float ABI
...
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1 .text
2: 00000000 0 SECTION LOCAL DEFAULT 2 .data
3: 00000000 0 SECTION LOCAL DEFAULT 3 .bss
4: 00000000 0 NOTYPE LOCAL DEFAULT 1 norvc_func
5: 00000000 0 NOTYPE LOCAL DEFAULT 1 $xrv32i2p1
6: 00000000 0 SECTION LOCAL DEFAULT 4 .riscv.attributes
The above a object is actually a norvc object, which only allows 32-bit
instructions, but the rvc elf_flags was turned on by the -march option.
It also happens when we build toolchain by --with-arch with c, but -march
or later .attribute and .option directives doesn't allow c.
I think there are several ways can resolve the problem, checking the mapping
symbols to make sure if there are any c extensions may be the easier way.
Passed gcc/binutils regressions of riscv-gnu-toolchain at least.
---
gas/config/tc-riscv.c | 17 ++++++++++++++---
.../gas/riscv/elf-header-flags-norvc.d | 8 ++++++++
.../gas/riscv/elf-header-flags-norvc.s | 5 +++++
gas/testsuite/gas/riscv/elf-header-flags-rvc.d | 8 ++++++++
gas/testsuite/gas/riscv/elf-header-flags-rvc.s | 5 +++++
5 files changed, 40 insertions(+), 3 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/elf-header-flags-norvc.d
create mode 100644 gas/testsuite/gas/riscv/elf-header-flags-norvc.s
create mode 100644 gas/testsuite/gas/riscv/elf-header-flags-rvc.d
create mode 100644 gas/testsuite/gas/riscv/elf-header-flags-rvc.s
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index df60c206b82..984bd29c74a 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -288,9 +288,6 @@ static struct riscv_set_options riscv_opts =
static void
riscv_set_rvc (bool rvc_value)
{
- if (rvc_value)
- elf_flags |= EF_RISCV_RVC;
-
if (start_assemble && subseg_text_p (now_seg)
&& riscv_opts.rvc && !rvc_value)
{
@@ -723,6 +720,20 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
}
while (next != NULL);
}
+
+ symbolS *s = symbol_rootP;
+ for (; s != NULL; s = symbol_next (s))
+ {
+ const char *name = S_GET_NAME (s);
+ if (name != NULL
+ && strncmp (name, "$xrv", 4) == 0
+ && (strstr (name, "_c") != NULL
+ || strstr (name, "_zca") != NULL))
+ {
+ elf_flags |= EF_RISCV_RVC;
+ break;
+ }
+ }
}
/* The default target format to use. */
diff --git a/gas/testsuite/gas/riscv/elf-header-flags-norvc.d b/gas/testsuite/gas/riscv/elf-header-flags-norvc.d
new file mode 100644
index 00000000000..b398835b592
--- /dev/null
+++ b/gas/testsuite/gas/riscv/elf-header-flags-norvc.d
@@ -0,0 +1,8 @@
+#as: -march=rv32ic
+#readelf: -h
+#source: elf-header-flags-norvc.s
+
+ELF Header:
+#...
+[ ]+Flags:[ ]+0x0
+#...
diff --git a/gas/testsuite/gas/riscv/elf-header-flags-norvc.s b/gas/testsuite/gas/riscv/elf-header-flags-norvc.s
new file mode 100644
index 00000000000..00d6e01ef00
--- /dev/null
+++ b/gas/testsuite/gas/riscv/elf-header-flags-norvc.s
@@ -0,0 +1,5 @@
+ .text
+ .option norvc
+ .global _start
+_start:
+ nop
diff --git a/gas/testsuite/gas/riscv/elf-header-flags-rvc.d b/gas/testsuite/gas/riscv/elf-header-flags-rvc.d
new file mode 100644
index 00000000000..074234d1abf
--- /dev/null
+++ b/gas/testsuite/gas/riscv/elf-header-flags-rvc.d
@@ -0,0 +1,8 @@
+#as: -march=rv32i
+#readelf: -h
+#source: elf-header-flags-rvc.s
+
+ELF Header:
+#...
+[ ]+Flags:[ ]+0x1, RVC.*
+#...
diff --git a/gas/testsuite/gas/riscv/elf-header-flags-rvc.s b/gas/testsuite/gas/riscv/elf-header-flags-rvc.s
new file mode 100644
index 00000000000..5ca03c87448
--- /dev/null
+++ b/gas/testsuite/gas/riscv/elf-header-flags-rvc.s
@@ -0,0 +1,5 @@
+ .text
+ .option rvc
+ .global _start
+_start:
+ nop
--
2.39.5 (Apple Git-154)
More information about the Binutils
mailing list