aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF
diff options
context:
space:
mode:
authorAyke <aykevanlaethem@gmail.com>2024-05-23 03:18:32 +0200
committerGitHub <noreply@github.com>2024-05-23 09:18:32 +0800
commit5ae8567640e495296acc0e20c966548aec401119 (patch)
tree24a42d84b2a2ab7e92ab5e80f20b5c3f5b8aa06b /lld/ELF
parentb91b8fea8c58e9b414e291df677b12ca44197784 (diff)
downloadllvm-5ae8567640e495296acc0e20c966548aec401119.zip
llvm-5ae8567640e495296acc0e20c966548aec401119.tar.gz
llvm-5ae8567640e495296acc0e20c966548aec401119.tar.bz2
Fix R_AVR_7_PCREL and R_AVR_13_PCREL range checking (#92695)
Fix incorrect range check of R_AVR_7_PCREL. R_AVR_7_PCREL has 7 bits available, but it works in instruction words and the actual range is [-128, 126]. Disable range check of R_AVR_13_PCREL. This matches the behavior of avr-ld, and is needed for devices like the ATtiny85 which only have rjmp/rcall but have 8KiB flash memory.
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/Arch/AVR.cpp3
1 files changed, 1 insertions, 2 deletions
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 9211eab..2275f86 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -231,14 +231,13 @@ 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 - 2, 7, rel);
+ checkInt(loc, val - 2, 8, 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));