[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
Wed Sep 27 23:56:01 PDT 2023


https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/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.

>From 2642cc7e67fdde3a4eef62be6ef7de278d0c0602 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 give explicit errors other than
generate wrong executables silently.
---
 lld/ELF/Arch/AVR.cpp      |  1 +
 lld/test/ELF/avr-errors.s | 27 +++++++++++++++++++++++++++
 2 files changed, 28 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..d5cba4c70e8564b 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));
diff --git a/lld/test/ELF/avr-errors.s b/lld/test/ELF/avr-errors.s
new file mode 100644
index 000000000000000..bbf88f887a4466b
--- /dev/null
+++ b/lld/test/ELF/avr-errors.s
@@ -0,0 +1,27 @@
+; REQUIRES: avr
+; RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 %s -o %t.o
+; RUN: not ld.lld %t.o -o %t 2>&1 -Ttext=0x1000 --defsym=callee0=0xf00 --defsym=callee1=0x2048 --defsym=callee2=0x100f | FileCheck %s
+
+.section .LDI,"ax", at progbits
+
+.globl __init
+__init:
+
+; CHECK:     relocation R_AVR_7_PCREL out of range: {{.*}} 'callee0'
+; CHECK-NOT: R_AVR_13_PCREL {{.*}} 'callee0'
+; CHECK-NOT: R_AVR_CALL {{.*}} 'callee0'
+brne  callee0
+rjmp  callee0
+jmp   callee0
+
+; CHECK:      relocation R_AVR_7_PCREL out of range: {{.*}} 'callee1'
+; CHECK:      relocation R_AVR_13_PCREL out of range: {{.*}} 'callee1'
+; CHECK-NOT:  R_AVR_CALL {{.*}} 'callee1'
+breq  callee1
+rcall callee1
+call  callee1
+
+; CHECK: improper alignment for relocation R_AVR_7_PCREL: {{.*}} not aligned to 2 bytes
+; CHECK: improper alignment for relocation R_AVR_13_PCREL: {{.*}} not aligned to 2 bytes
+brlt  callee2
+rcall callee2



More information about the llvm-commits mailing list