Skip to content

Commit b60ee41

Browse files
committed
[lld][AVR] Fix range of R_AVR_7_PCREL
R_AVR_7_PCREL has 7 bits available, but because it works in instruction words the actual range is 256 bytes (-128..126 bytes). This fixes a bug introduced in #67636 that caused code generated by the compiler to be rejected by the linker. There is still a bug in the compiler: it can use one more bit for R_AVR_7_PCREL than it currently does. But that should be fixed separately.
1 parent 7273ad1 commit b60ee41

File tree

3 files changed

+7
-3
lines changed

3 files changed

+7
-3
lines changed

lld/ELF/Arch/AVR.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ void AVR::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
231231

232232
// Since every jump destination is word aligned we gain an extra bit
233233
case R_AVR_7_PCREL: {
234-
checkInt(loc, val - 2, 7, rel);
234+
checkInt(loc, val - 2, 8, rel);
235235
checkAlignment(loc, val, 2, rel);
236236
const uint16_t target = (val - 2) >> 1;
237237
write16le(loc, (read16le(loc) & 0xfc07) | ((target & 0x7f) << 3));

lld/test/ELF/avr-reloc-error.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# RUN: rm -rf %t && split-file %s %t && cd %t
44

55
# RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-7.s -o avr-pcrel-7.o
6-
# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1044 --defsym=callee2=0x100f 2>&1 | \
6+
# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1084 --defsym=callee2=0x100f 2>&1 | \
77
# RUN: FileCheck %s --check-prefix=PCREL7
88
# RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-13.s -o avr-pcrel-13.o
99
# RUN: not ld.lld avr-pcrel-13.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x2000 --defsym=callee1=0x2004 --defsym=callee2=0x100f 2>&1 | \
@@ -20,7 +20,7 @@
2020
__start:
2121

2222
# PCREL7-NOT: callee0
23-
# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee1'
23+
# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-128, 127]; references 'callee1'
2424
# PCREL7: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes
2525
brne callee0
2626
breq callee1

lld/test/ELF/avr-reloc.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,17 @@ sbic b, 1 ; R_AVR_PORT5
8282
; CHECK-NEXT: rjmp .-36
8383
; CHECK-NEXT: breq .+26
8484
; CHECK-NEXT: breq .-40
85+
; CHECK-NEXT: breq .-128
86+
; CHECK-NEXT: breq .+126
8587
; HEX-LABEL: section .PCREL:
8688
; HEX-NEXT: 0fc0eecf 69f061f3
8789
foo:
8890
rjmp foo + 32 ; R_AVR_13_PCREL
8991
rjmp foo - 32 ; R_AVR_13_PCREL
9092
breq foo + 32 ; R_AVR_7_PCREL
9193
breq foo - 32 ; R_AVR_7_PCREL
94+
breq 1f - 128 $ 1: ; R_AVR_7_PCREL
95+
breq 1f + 126 $ 1: ; R_AVR_7_PCREL
9296

9397
.section .LDSSTS,"ax",@progbits
9498
; CHECK-LABEL: section .LDSSTS:

0 commit comments

Comments
 (0)