[lld] [lld][ELF][AVR] Add range check for R_AVR_13_PCREL (PR #67636)
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 2 18:50:07 PDT 2023
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/67636
>From c2b7340214305f8e1ee1102307a42582ba9fcce3 Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Thu, 28 Sep 2023 14:49:26 +0800
Subject: [PATCH] [lld][ELF][AVR] Add range and alignment checks for AVR
relocations
Some large AVR programs (for devices without long jump) may
exceed 128KiB, and lld should report explicit errors other than
generate wrong executables silently.
---
lld/ELF/Arch/AVR.cpp | 2 ++
lld/test/ELF/avr-reloc-error.s | 33 +++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 lld/test/ELF/avr-reloc-error.s
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 4905d61796fa98f..de51d155a7c9f1c 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -238,6 +238,7 @@ void AVR::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
}
case R_AVR_13_PCREL: {
+ checkInt(loc, val, 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..293d2ce10b9cea1
--- /dev/null
+++ b/lld/test/ELF/avr-reloc-error.s
@@ -0,0 +1,33 @@
+; REQUIRES: avr
+; RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 %s -o %t.o
+; RUN: not ld.lld %t.o -o /dev/null -Ttext=0x1000 --defsym=callee=0xf00 2>&1 | \
+; RUN: FileCheck %s --check-prefix=CHECKA --implicit-check-not=R_AVR_13_PCREL
+; RUN: not ld.lld %t.o -o /dev/null -Ttext=0x1000 --defsym=callee=0x2048 2>&1 | \
+; RUN: FileCheck %s --check-prefix=CHECKB --implicit-check-not=R_AVR_CALL
+; RUN: not ld.lld %t.o -o /dev/null -Ttext=0x1000 --defsym=callee=0x100f 2>&1 | \
+; RUN: FileCheck %s --check-prefix=CHECKC
+
+.section .LDI,"ax", at progbits
+
+.globl __init
+__init:
+
+; CHECKA: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee'
+; CHECKB: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee'
+; CHECKB: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095]; references 'callee'
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} is not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_CALL: {{.*}} is not aligned to 2 bytes
+brne callee
+rjmp callee
+jmp callee
+
+; CHECKA: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee'
+; CHECKB: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee'
+; CHECKB: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095]; references 'callee'
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} is not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_CALL: {{.*}} is not aligned to 2 bytes
+breq callee
+rcall callee
+call callee
More information about the llvm-commits
mailing list