From 4ce0a519c19cb4e8629213db8baeab5f16df68cf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Jun 2019 07:53:06 +0000 Subject: [PATCH] [ELF][RISCV] Treat R_RISCV_{ADD,SET,SUB}* as link-time constants R_RISCV_{ADD,SET,SUB}* are used for local label computation. Add a new RelExpr member R_RISCV_ADD to represent them. R_RISCV_ADD is treated as a link-time constant because otherwise R_RISCV_{ADD,SET,SUB}* are not allowed in -pie/-shared mode. In glibc Scrt1.o, .rela.eh_frame contains such relocations. Because .eh_frame is not writable, we get this error: ld.lld: error: can't create dynamic relocation R_RISCV_ADD32 against symbol: .L0 in readonly segment; recompil object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output >>> defined in ..../riscv64-linux-gnu/lib/Scrt1.o With D63076 and this patch, I can run -pie/-shared programs linked against glibc. Note llvm-mc cannot currently produce R_RISCV_SET* so they are not tested. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D63183 llvm-svn: 363128 --- lld/ELF/Arch/RISCV.cpp | 14 ++++++++++++++ lld/ELF/InputSection.cpp | 1 + lld/ELF/Relocations.cpp | 5 +++-- lld/ELF/Relocations.h | 1 + lld/test/ELF/riscv-reloc-add.s | 26 ++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/riscv-reloc-add.s 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