diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 20d0ae08530a..9355a746156c 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -62,6 +62,20 @@ uint32_t RISCV::calcEFlags() const { RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S, const uint8_t *Loc) const { switch (Type) { + case R_RISCV_ADD8: + case R_RISCV_ADD16: + case R_RISCV_ADD32: + case R_RISCV_ADD64: + case R_RISCV_SET6: + case R_RISCV_SET8: + case R_RISCV_SET16: + case R_RISCV_SET32: + case R_RISCV_SUB6: + case R_RISCV_SUB8: + case R_RISCV_SUB16: + case R_RISCV_SUB32: + case R_RISCV_SUB64: + return R_RISCV_ADD; case R_RISCV_JAL: case R_RISCV_BRANCH: case R_RISCV_CALL: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 2939842ba0ee..d077c017ca71 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -632,6 +632,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, case R_DTPREL: case R_RELAX_TLS_LD_TO_LE_ABS: case R_RELAX_GOT_PC_NOPIC: + case R_RISCV_ADD: return Sym.getVA(A); case R_ADDEND: return A; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 31ca03e06566..702cac3843a4 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -401,8 +401,9 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC32_PLTREL, - R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_TLSDESC_CALL, R_TLSDESC_PC, - R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E)) + R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_TLSDESC_CALL, + R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, + R_TLSIE_HINT>(E)) return true; // These never do, except if the entire file is position dependent or if diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index a95856662a1a..dd0405698242 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -96,6 +96,7 @@ enum RelExpr { R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_PPC64_TOCBASE, + R_RISCV_ADD, R_RISCV_PC_INDIRECT, }; diff --git a/lld/test/ELF/riscv-reloc-add.s b/lld/test/ELF/riscv-reloc-add.s new file mode 100644 index 000000000000..64772c82935c --- /dev/null +++ b/lld/test/ELF/riscv-reloc-add.s @@ -0,0 +1,26 @@ +# REQUIRES: riscv +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s -o %t.32.o +# RUN: ld.lld -pie %t.32.o -o %t.32 +# RUN: llvm-readelf -x .rodata %t.32 | FileCheck --check-prefix=HEX %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o %t.64.o +# RUN: ld.lld -shared %t.64.o -o %t.64 +# RUN: llvm-readelf -x .rodata %t.64 | FileCheck --check-prefix=HEX %s + +# HEX: section '.rodata': +# HEX-NEXT: 0x{{[0-9a-f]+}} 04000000 00000000 04000000 040004 + +## R_RISCV_ADD* and R_RISCV_SUB* are link-time constants, otherwise they are +## not allowed in -pie/-shared mode. + +.global _start +_start: +.L0: + ret +.L1: + +.rodata +.dword .L1 - .L0 +.word .L1 - .L0 +.half .L1 - .L0 +.byte .L1 - .L0