[lld] 488a62f - [lld][ELF][AVR] Add range check for R_AVR_13_PCREL (#67636)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 6 03:20:08 PDT 2023
Author: Ben Shi
Date: 2023-10-06T18:20:03+08:00
New Revision: 488a62f86e4f1260a2b4667b177679a6eac643c4
URL: https://github.com/llvm/llvm-project/commit/488a62f86e4f1260a2b4667b177679a6eac643c4
DIFF: https://github.com/llvm/llvm-project/commit/488a62f86e4f1260a2b4667b177679a6eac643c4.diff
LOG: [lld][ELF][AVR] Add range check for R_AVR_13_PCREL (#67636)
Some large AVR programs (for devices without long jump) may exceed
128KiB, and lld should give explicit errors other than generate wrong
executables silently.
Added:
lld/test/ELF/avr-reloc-error.s
Modified:
lld/ELF/Arch/AVR.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 4905d61796fa98f..9211eabc9669a5e 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -231,13 +231,14 @@ 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, 7, rel);
+ checkInt(loc, val - 2, 7, 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));
@@ -255,6 +256,7 @@ void AVR::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
case R_AVR_CALL: {
+ checkAlignment(loc, val, 2, rel);
uint16_t hi = val >> 17;
uint16_t lo = val >> 1;
write16le(loc, read16le(loc) | ((hi >> 1) << 4) | (hi & 1));
diff --git a/lld/test/ELF/avr-reloc-error.s b/lld/test/ELF/avr-reloc-error.s
new file mode 100644
index 000000000000000..0a30f68d168e2f7
--- /dev/null
+++ b/lld/test/ELF/avr-reloc-error.s
@@ -0,0 +1,53 @@
+# REQUIRES: avr
+
+# 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: 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 | \
+# RUN: FileCheck %s --check-prefix=PCREL13
+# RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-abs.s -o avr-abs.o
+# RUN: not ld.lld avr-abs.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1009 --defsym=callee1=0x1010 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ABS
+
+#--- avr-pcrel-7.s
+
+.section .LDI,"ax", at progbits
+
+.globl __start
+__start:
+
+# PCREL7-NOT: callee0
+# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee1'
+# PCREL7: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes
+brne callee0
+breq callee1
+brlt callee2
+
+#--- avr-pcrel-13.s
+
+.section .LDI,"ax", at progbits
+
+.globl __start
+__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
+rjmp callee2
+
+#--- avr-abs.s
+
+.section .LDI,"ax", at progbits
+
+.globl __start
+__start:
+
+# ABS: error: {{.*}} improper alignment for relocation R_AVR_CALL: 0x1009 is not aligned to 2 bytes
+# ABS-NOT: 0x1010
+call callee0
+jmp callee1
More information about the llvm-commits
mailing list