[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