[lld] 5ae8567 - Fix R_AVR_7_PCREL and R_AVR_13_PCREL range checking (#92695)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 22 18:18:36 PDT 2024
Author: Ayke
Date: 2024-05-23T09:18:32+08:00
New Revision: 5ae8567640e495296acc0e20c966548aec401119
URL: https://github.com/llvm/llvm-project/commit/5ae8567640e495296acc0e20c966548aec401119
DIFF: https://github.com/llvm/llvm-project/commit/5ae8567640e495296acc0e20c966548aec401119.diff
LOG: Fix R_AVR_7_PCREL and R_AVR_13_PCREL range checking (#92695)
Fix incorrect range check of R_AVR_7_PCREL. R_AVR_7_PCREL has 7 bits
available, but it works in instruction words and the actual range is [-128, 126].
Disable range check of R_AVR_13_PCREL. This matches the behavior of avr-ld,
and is needed for devices like the ATtiny85 which only have rjmp/rcall but have
8KiB flash memory.
Added:
Modified:
lld/ELF/Arch/AVR.cpp
lld/test/ELF/avr-reloc-error.s
lld/test/ELF/avr-reloc.s
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 9211eabc9669a..2275f86942871 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -231,14 +231,13 @@ void AVR::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// Since every jump destination is word aligned we gain an extra bit
case R_AVR_7_PCREL: {
- checkInt(loc, val - 2, 7, rel);
+ checkInt(loc, val - 2, 8, rel);
checkAlignment(loc, val, 2, rel);
const uint16_t target = (val - 2) >> 1;
write16le(loc, (read16le(loc) & 0xfc07) | ((target & 0x7f) << 3));
break;
}
case R_AVR_13_PCREL: {
- checkInt(loc, val - 2, 13, rel);
checkAlignment(loc, val, 2, rel);
const uint16_t target = (val - 2) >> 1;
write16le(loc, (read16le(loc) & 0xf000) | (target & 0xfff));
diff --git a/lld/test/ELF/avr-reloc-error.s b/lld/test/ELF/avr-reloc-error.s
index 0a30f68d168e2..f177e44f753fa 100644
--- a/lld/test/ELF/avr-reloc-error.s
+++ b/lld/test/ELF/avr-reloc-error.s
@@ -3,7 +3,7 @@
# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-7.s -o avr-pcrel-7.o
-# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1044 --defsym=callee2=0x100f 2>&1 | \
+# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1084 --defsym=callee2=0x100f 2>&1 | \
# RUN: FileCheck %s --check-prefix=PCREL7
# RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-13.s -o avr-pcrel-13.o
# RUN: not ld.lld avr-pcrel-13.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x2000 --defsym=callee1=0x2004 --defsym=callee2=0x100f 2>&1 | \
@@ -20,7 +20,7 @@
__start:
# PCREL7-NOT: callee0
-# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee1'
+# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-128, 127]; references 'callee1'
# PCREL7: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes
brne callee0
breq callee1
@@ -34,7 +34,6 @@ brlt callee2
__start:
# PCREL13-NOT: callee0
-# PCREL13: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095]; references 'callee1'
# PCREL13: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} is not aligned to 2 bytes
rjmp callee0
rcall callee1
diff --git a/lld/test/ELF/avr-reloc.s b/lld/test/ELF/avr-reloc.s
index 172c0e03ba74b..ec088eaa149d0 100644
--- a/lld/test/ELF/avr-reloc.s
+++ b/lld/test/ELF/avr-reloc.s
@@ -82,6 +82,12 @@ sbic b, 1 ; R_AVR_PORT5
; CHECK-NEXT: rjmp .-36
; CHECK-NEXT: breq .+26
; CHECK-NEXT: breq .-40
+; CHECK-NEXT: rjmp .-4096
+; CHECK-NEXT: rjmp .+4094
+; CHECK-NEXT: rjmp .+4094
+; CHECK-NEXT: rjmp .-4096
+; CHECK-NEXT: breq .-128
+; CHECK-NEXT: breq .+126
; HEX-LABEL: section .PCREL:
; HEX-NEXT: 0fc0eecf 69f061f3
foo:
@@ -89,6 +95,12 @@ rjmp foo + 32 ; R_AVR_13_PCREL
rjmp foo - 32 ; R_AVR_13_PCREL
breq foo + 32 ; R_AVR_7_PCREL
breq foo - 32 ; R_AVR_7_PCREL
+rjmp 1f - 4096 $ 1: ; R_AVR_13_PCREL
+rjmp 1f + 4094 $ 1: ; R_AVR_13_PCREL
+rjmp 1f - 4098 $ 1: ; R_AVR_13_PCREL (overflow)
+rjmp 1f + 4096 $ 1: ; R_AVR_13_PCREL (overflow)
+breq 1f - 128 $ 1: ; R_AVR_7_PCREL
+breq 1f + 126 $ 1: ; R_AVR_7_PCREL
.section .LDSSTS,"ax", at progbits
; CHECK-LABEL: section .LDSSTS:
More information about the llvm-commits
mailing list