[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
Thu Sep 28 00:59:00 PDT 2023
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/67636
>From 90bd63a6f796986e111a49ffda5f051755dc4eb1 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 check for R_AVR_13_PCREL
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-errors.s | 33 +++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 lld/test/ELF/avr-errors.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-errors.s b/lld/test/ELF/avr-errors.s
new file mode 100644
index 000000000000000..8f96eb73daccd7d
--- /dev/null
+++ b/lld/test/ELF/avr-errors.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 %ta 2>&1 -Ttext=0x1000 --defsym=callee=0xf00 | \
+; RUN: FileCheck %s --check-prefix=CHECKA --implicit-check-not=R_AVR_13_PCREL
+; RUN: not ld.lld %t.o -o %ta 2>&1 -Ttext=0x1000 --defsym=callee=0x2048 | \
+; RUN: FileCheck %s --check-prefix=CHECKB --implicit-check-not=R_AVR_CALL
+; RUN: not ld.lld %t.o -o %ta 2>&1 -Ttext=0x1000 --defsym=callee=0x100f | \
+; 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];
+; CHECKB: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63];
+; CHECKB: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095];
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_CALL: {{.*}} 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];
+; CHECKB: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63];
+; CHECKB: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095];
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} not aligned to 2 bytes
+; CHECKC: error: {{.*}} improper alignment for relocation R_AVR_CALL: {{.*}} not aligned to 2 bytes
+breq callee
+rcall callee
+call callee
More information about the llvm-commits
mailing list