riscv64 TLS support.

Signed-off-by: Mao Han <han_mao@linux.alibaba.com>
Signed-off-by: Xia Lifang <lifang_xia@linux.alibaba.com>
Signed-off-by: Chen Guoyin <chenguoyin.cgy@linux.alibaba.com>
Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
Signed-off-by: Lu Xufan <luxufan@iscas.ac.cn>
Test: treehugger
Change-Id: I14efb4a03a3dc2ec736d7e47a3f8859c886eb9d6
diff --git a/linker/linker.cpp b/linker/linker.cpp
index d533ac3..9779c8d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -371,7 +371,7 @@
     char* static_tls = reinterpret_cast<char*>(__get_bionic_tcb()) - layout.offset_bionic_tcb();
     return static_tls + tls_mod.static_offset;
   } else if (should_alloc) {
-    const TlsIndex ti { si_tls->module_id, 0 };
+    const TlsIndex ti { si_tls->module_id, static_cast<size_t>(0 - TLS_DTV_OFFSET) };
     return TLS_GET_ADDR(&ti);
   } else {
     TlsDtv* dtv = __get_tcb_dtv(__get_bionic_tcb());
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 60fd776..aa1a208 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -51,6 +51,8 @@
   return EM_AARCH64;
 #elif defined(__i386__)
   return EM_386;
+#elif defined(__riscv)
+  return EM_RISCV;
 #elif defined(__x86_64__)
   return EM_X86_64;
 #endif
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index c7c7bfb..952dade 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -49,7 +49,9 @@
     case R_GENERIC_TLS_DTPMOD:
     case R_GENERIC_TLS_DTPREL:
     case R_GENERIC_TLS_TPREL:
+#if defined(R_GENERIC_TLSDESC)
     case R_GENERIC_TLSDESC:
+#endif
       return true;
     default:
       return false;
@@ -426,7 +428,7 @@
     case R_GENERIC_TLS_DTPREL:
       count_relocation_if<IsGeneral>(kRelocRelative);
       {
-        const ElfW(Addr) result = sym_addr + get_addend_rel();
+        const ElfW(Addr) result = sym_addr + get_addend_rel() - TLS_DTV_OFFSET;
         trace_reloc("RELO TLS_DTPREL %16p <- %16p %s",
                     rel_target, reinterpret_cast<void*>(result), sym_name);
         *static_cast<ElfW(Addr)*>(rel_target) = result;
diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h
index 93d899e..37a7880 100644
--- a/linker/linker_relocs.h
+++ b/linker/linker_relocs.h
@@ -73,6 +73,20 @@
 #define R_GENERIC_TLS_TPREL     R_386_TLS_TPOFF
 #define R_GENERIC_TLSDESC       R_386_TLS_DESC
 
+#elif defined (__riscv)
+
+#define R_GENERIC_JUMP_SLOT     R_RISCV_JUMP_SLOT
+#define R_GENERIC_ABSOLUTE      R_RISCV_64
+#define R_GENERIC_GLOB_DAT      R_RISCV_64
+#define R_GENERIC_RELATIVE      R_RISCV_RELATIVE
+#define R_GENERIC_IRELATIVE     R_RISCV_IRELATIVE
+#define R_GENERIC_COPY          R_RISCV_COPY
+#define R_GENERIC_TLS_DTPMOD    R_RISCV_TLS_DTPMOD64
+#define R_GENERIC_TLS_DTPREL    R_RISCV_TLS_DTPREL64
+#define R_GENERIC_TLS_TPREL     R_RISCV_TLS_TPREL64
+// TODO: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/94
+// #define R_GENERIC_TLSDESC       R_RISCV_TLS_DESC
+
 #elif defined (__x86_64__)
 
 #define R_GENERIC_JUMP_SLOT     R_X86_64_JUMP_SLOT