diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp index 9211eabc9669a..2275f86942871 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)); diff --git a/lld/test/ELF/avr-reloc-error.s b/lld/test/ELF/avr-reloc-error.s index 0a30f68d168e2..f177e44f753fa 100644 --- a/lld/test/ELF/avr-reloc-error.s +++ b/lld/test/ELF/avr-reloc-error.s @@ -3,7 +3,7 @@ # RUN: rm -rf %t && split-file %s %t && cd %t # RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-7.s -o avr-pcrel-7.o -# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1044 --defsym=callee2=0x100f 2>&1 | \ +# RUN: not ld.lld avr-pcrel-7.o -o /dev/null -Ttext=0x1000 --defsym=callee0=0x1040 --defsym=callee1=0x1084 --defsym=callee2=0x100f 2>&1 | \ # RUN: FileCheck %s --check-prefix=PCREL7 # RUN: llvm-mc -filetype=obj -triple=avr -mcpu=atmega328 avr-pcrel-13.s -o avr-pcrel-13.o # 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 @@ __start: # PCREL7-NOT: callee0 -# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-64, 63]; references 'callee1' +# PCREL7: error: {{.*}} relocation R_AVR_7_PCREL out of range: {{.*}} is not in [-128, 127]; references 'callee1' # PCREL7: error: {{.*}} improper alignment for relocation R_AVR_7_PCREL: {{.*}} is not aligned to 2 bytes brne callee0 breq callee1 @@ -34,7 +34,6 @@ brlt callee2 __start: # PCREL13-NOT: callee0 -# PCREL13: error: {{.*}} relocation R_AVR_13_PCREL out of range: {{.*}} is not in [-4096, 4095]; references 'callee1' # PCREL13: error: {{.*}} improper alignment for relocation R_AVR_13_PCREL: {{.*}} is not aligned to 2 bytes rjmp callee0 rcall callee1 diff --git a/lld/test/ELF/avr-reloc.s b/lld/test/ELF/avr-reloc.s index 172c0e03ba74b..ec088eaa149d0 100644 --- a/lld/test/ELF/avr-reloc.s +++ b/lld/test/ELF/avr-reloc.s @@ -82,6 +82,12 @@ sbic b, 1 ; R_AVR_PORT5 ; CHECK-NEXT: rjmp .-36 ; CHECK-NEXT: breq .+26 ; CHECK-NEXT: breq .-40 +; CHECK-NEXT: rjmp .-4096 +; CHECK-NEXT: rjmp .+4094 +; CHECK-NEXT: rjmp .+4094 +; CHECK-NEXT: rjmp .-4096 +; CHECK-NEXT: breq .-128 +; CHECK-NEXT: breq .+126 ; HEX-LABEL: section .PCREL: ; HEX-NEXT: 0fc0eecf 69f061f3 foo: @@ -89,6 +95,12 @@ rjmp foo + 32 ; R_AVR_13_PCREL rjmp foo - 32 ; R_AVR_13_PCREL breq foo + 32 ; R_AVR_7_PCREL breq foo - 32 ; R_AVR_7_PCREL +rjmp 1f - 4096 $ 1: ; R_AVR_13_PCREL +rjmp 1f + 4094 $ 1: ; R_AVR_13_PCREL +rjmp 1f - 4098 $ 1: ; R_AVR_13_PCREL (overflow) +rjmp 1f + 4096 $ 1: ; R_AVR_13_PCREL (overflow) +breq 1f - 128 $ 1: ; R_AVR_7_PCREL +breq 1f + 126 $ 1: ; R_AVR_7_PCREL .section .LDSSTS,"ax",@progbits ; CHECK-LABEL: section .LDSSTS: