aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-09-26 14:20:27 -0700
committerTobias Hieta <tobias@hieta.se>2022-09-28 08:16:35 +0200
commit2eba4dd78e2a47a36a65617f17d5ea156cfb6448 (patch)
tree8fa463aebff0d0e0c3f9cab53862a1ae46e54b13 /lld
parent451e3b68306d0d8a9be9065420924530053ff29b (diff)
downloadllvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.zip
llvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.tar.gz
llvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.tar.bz2
[ELF] Rewrite R_RISCV_ALIGN nops when r.addend%4 != 0
For RVC, GNU assembler and LLVM integrated assembler add c.nop followed by a sequence of 4-byte nops. Even if remove % 4 == 0, we have to split one 4-byte nop and therefore need to write the code sequence, otherwise we create an incorrect c.unimp. (cherry picked from commit 78084d9e77b9a2017e2215491b71b37c2671c292)
Diffstat (limited to 'lld')
-rw-r--r--lld/ELF/Arch/RISCV.cpp9
-rw-r--r--lld/test/ELF/riscv-relax-align-rvc.s13
2 files changed, 18 insertions, 4 deletions
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 8fca1a6..56a516f 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -750,12 +750,13 @@ void elf::riscvFinalizeRelax(int passes) {
p += size;
// For R_RISCV_ALIGN, we will place `offset` in a location (among NOPs)
- // to satisfy the alignment requirement. If `remove` is a multiple of 4,
- // it is as if we have skipped some NOPs. Otherwise we are in the middle
- // of a 4-byte NOP, and we need to rewrite the NOP sequence.
+ // to satisfy the alignment requirement. If both `remove` and r.addend
+ // are multiples of 4, it is as if we have skipped some NOPs. Otherwise
+ // we are in the middle of a 4-byte NOP, and we need to rewrite the NOP
+ // sequence.
int64_t skip = 0;
if (r.type == R_RISCV_ALIGN) {
- if (remove % 4 != 0) {
+ if (remove % 4 || r.addend % 4) {
skip = r.addend - remove;
int64_t j = 0;
for (; j + 4 <= skip; j += 4)
diff --git a/lld/test/ELF/riscv-relax-align-rvc.s b/lld/test/ELF/riscv-relax-align-rvc.s
index 37758ed..01cbbd8b 100644
--- a/lld/test/ELF/riscv-relax-align-rvc.s
+++ b/lld/test/ELF/riscv-relax-align-rvc.s
@@ -50,6 +50,12 @@
# CHECK-NEXT: c.addi a0, 8
# CHECK-EMPTY:
+# CHECK: <.text2>:
+# CHECK-NEXT: addi a0, a1, 1
+# CHECK-NEXT: c.addi a0, 1
+# CHECK-NEXT: c.nop
+# CHECK-NEXT: c.addi a0, 2
+
.global _start
_start:
c.addi a0, 1
@@ -73,3 +79,10 @@ d:
c.addi a0, 8
.size d, . - d
.size _start, . - _start
+
+.section .text2,"ax"
+.balign 16
+ addi a0, a1, 1
+ c.addi a0, 1
+.balign 8
+ c.addi a0, 2