From patchwork Wed Sep 13 17:26:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tatsuyuki Ishi X-Patchwork-Id: 75885 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F08A73858428 for ; Wed, 13 Sep 2023 17:27:11 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by sourceware.org (Postfix) with ESMTPS id C43F83858402 for ; Wed, 13 Sep 2023 17:26:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C43F83858402 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-68cb5278e3fso1341b3a.1 for ; Wed, 13 Sep 2023 10:26:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694626002; x=1695230802; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hrRW4vc0oZaPQySWT8L5fzBmgbMHtX5Xx3FM7xJLtvY=; b=nPjuUSnbz3qNzpU83fjo0ECk7SIqzq3VNsvS/TI4iG6NafJ+2qTU+O2VZySIe00s55 PBhBPQ+dbFZ8X066yKMcJm1eoS2/I5m4RMGxHNCRZpXGV8HHQfly5r+bMWsbo03Y7G2l IwGRvEssw6FGV3dP3LNF90oWr5xAnGh9y2zqRiczsHXPSvk+V+0A5LxJ+rszsNOcA9/z jHWHZ7WBYR2YLfEtHFQwNOBvCxCDismMytuGLXyehr+kGnoTkqoA9swb2d01wHQu0aQV QD9Q9ZK/NJG2J61Ru691zHtwP9zpma9lK7RLKIwobqpETEVPo/zO4gx8+QvESGHU6LFp sOfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694626003; x=1695230803; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hrRW4vc0oZaPQySWT8L5fzBmgbMHtX5Xx3FM7xJLtvY=; b=KYWimAiBFXhRh5oRRQq97Y69wotnbSHIe+y50WT0ssDvDkLlsIFIWskh7Oi1jPKQZY p/HuexH2UU3YbvWCdonAVBtie8KM/r0K/WHeMlRkNFy5BPz3xoxVSjLas4zsq93rJS7O 9lzOXxzx3Q8De9tvbLDm9yDNnLoXTqU7EwQ78kYOTYenbQOcnN2rrgQ7JZOdww4lcz+E oqjhJO5N9fQ9xs/FsnSbWYeATGswsKoOen+IjpJXDfZEWI2hTBw0sBHedDLiURy5B6Mp uL5g+s4ZJ9kAImwI3nGW+AOsMX3s+SiQoaJTpA8l1/Ose4y7Z9BoACJZ8+2/NmXkku6m 7L9Q== X-Gm-Message-State: AOJu0Yzon1qcFwp8MN8ME/HHNdlxGZOSkzqM0Y0/VqaJTlGqYHKS23S4 iPQf1B/DEhUm9SYzjtFyeR/DgIWOFefp6KmK X-Google-Smtp-Source: AGHT+IGfv+D2hTyv0CNytP5Auy35NNxAg0VLrqp6+u3pQJr21UKJA2jyZN8TSoLa6h1GzzK/RZBCyQ== X-Received: by 2002:a05:6a21:a595:b0:13f:65ca:52a2 with SMTP id gd21-20020a056a21a59500b0013f65ca52a2mr3558362pzc.5.1694626002406; Wed, 13 Sep 2023 10:26:42 -0700 (PDT) Received: from localhost (zz20184013906F627101.userreverse.dion.ne.jp. [111.98.113.1]) by smtp.gmail.com with ESMTPSA id x47-20020a056a000bef00b0068a538cc7adsm9385392pfu.52.2023.09.13.10.26.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Sep 2023 10:26:41 -0700 (PDT) From: Tatsuyuki Ishi To: ishitatsuyuki@gmail.com Cc: libc-alpha@sourceware.org, rui314@gmail.com, ruiu@bluewhale.systems, schwab@linux-m68k.org Subject: [PATCH v3] RISC-V: Implement TLS Descriptors. Date: Thu, 14 Sep 2023 02:26:33 +0900 Message-ID: <20230913172633.39229-1-ishitatsuyuki@gmail.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230817181228.122674-2-ishitatsuyuki@gmail.com> References: <20230817181228.122674-2-ishitatsuyuki@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org This is mostly based off AArch64 implementation, with some adaptations to different TLS DTV offsets and calling conventions. No regression in binutils and gcc tests for rv64gc, tested alongside the gcc and binutils implementation (posted at the same time). --- v2: Fix end-of-file newlines. v3: Fix segfaulting on the slow path of TLSDESC resolver. Fix handling of lazy relocations. This contribution is made on behalf of Blue Whale Systems, which has copyright assignment on file with the FSF. sysdeps/riscv/Makefile | 8 ++ sysdeps/riscv/dl-lookupcfg.h | 27 +++++ sysdeps/riscv/dl-machine.h | 48 ++++++++- sysdeps/riscv/dl-tlsdesc.S | 203 +++++++++++++++++++++++++++++++++++ sysdeps/riscv/dl-tlsdesc.h | 49 +++++++++ sysdeps/riscv/linkmap.h | 1 + sysdeps/riscv/tlsdesc.c | 38 +++++++ sysdeps/riscv/tlsdesc.sym | 19 ++++ 8 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 sysdeps/riscv/dl-lookupcfg.h create mode 100644 sysdeps/riscv/dl-tlsdesc.S create mode 100644 sysdeps/riscv/dl-tlsdesc.h create mode 100644 sysdeps/riscv/tlsdesc.c create mode 100644 sysdeps/riscv/tlsdesc.sym diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile index 8fb10b164f..bb4bcd29b2 100644 --- a/sysdeps/riscv/Makefile +++ b/sysdeps/riscv/Makefile @@ -2,6 +2,14 @@ ifeq ($(subdir),misc) sysdep_headers += sys/asm.h endif +ifeq ($(subdir),elf) +sysdep-dl-routines += tlsdesc dl-tlsdesc +endif + +ifeq ($(subdir),csu) +gen-as-const-headers += tlsdesc.sym +endif + # RISC-V's assembler also needs to know about PIC as it changes the definition # of some assembler macros. ASFLAGS-.os += $(pic-ccflag) diff --git a/sysdeps/riscv/dl-lookupcfg.h b/sysdeps/riscv/dl-lookupcfg.h new file mode 100644 index 0000000000..d7fe73636b --- /dev/null +++ b/sysdeps/riscv/dl-lookupcfg.h @@ -0,0 +1,27 @@ +/* Configuration of lookup functions. + Copyright (C) 2006-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define DL_UNMAP_IS_SPECIAL + +#include_next + +struct link_map; + +extern void _dl_unmap (struct link_map *map); + +#define DL_UNMAP(map) _dl_unmap (map) diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index c0c9bd93ad..eb0c874e72 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,8 @@ || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_TPREL32) \ || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPREL64) \ || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPMOD64) \ - || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64))) \ + || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64)) \ + || ((type) == R_RISCV_TLSDESC)) \ | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY))) /* Return nonzero iff ELF header is compatible with the running host. */ @@ -219,6 +221,32 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } break; + case R_RISCV_TLSDESC: + struct tlsdesc *td = (struct tlsdesc *) addr_field; + if (sym == NULL) + { + td->entry = _dl_tlsdesc_undefweak; + td->arg = reloc->r_addend; + } + else + { +# ifndef SHARED + CHECK_STATIC_TLS (map, sym_map); +# else + if (!TRY_STATIC_TLS (map, sym_map)) + { + td->entry = _dl_tlsdesc_dynamic; + td->arg = _dl_make_tlsdesc_dynamic (sym_map, sym->st_value + reloc->r_addend); + } + else +# endif + { + td->entry = _dl_tlsdesc_return; + td->arg = (void *)(TLS_TPREL_VALUE(sym_map, sym) + reloc->r_addend); + } + } + break; + case R_RISCV_COPY: { if (__glibc_unlikely (sym == NULL)) @@ -289,6 +317,24 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], else *reloc_addr = map->l_mach.plt; } + else if (__glibc_likely (r_type == R_RISCV_TLSDESC)) + { + const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); + const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]); + const ElfW (Sym) *sym = &symtab[symndx]; + const struct r_found_version *version = NULL; + + if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + { + const ElfW (Half) *vernum = + (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); + version = &map->l_versions[vernum[symndx] & 0x7fff]; + } + + /* Always initialize TLS descriptors completely, because lazy + initialization requires synchronization at every TLS access. */ + elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc); + } else if (__glibc_unlikely (r_type == R_RISCV_IRELATIVE)) { ElfW(Addr) value = map->l_addr + reloc->r_addend; diff --git a/sysdeps/riscv/dl-tlsdesc.S b/sysdeps/riscv/dl-tlsdesc.S new file mode 100644 index 0000000000..bf241ef76a --- /dev/null +++ b/sysdeps/riscv/dl-tlsdesc.S @@ -0,0 +1,203 @@ +/* Thread-local storage handling in the ELF dynamic linker. + RISC-V version. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#ifdef __riscv_float_abi_soft +# define FRAME_SIZE (-((-12 * SZREG) & ALMASK)) +#else +# define FRAME_SIZE (-((-12 * SZREG - 20 * SZFREG) & ALMASK)) +#endif + + .text + + /* Compute the thread pointer offset for symbols in the static + TLS block. The offset is the same for all threads. + Prototype: + _dl_tlsdesc_return (tlsdesc *) ; + */ +ENTRY (_dl_tlsdesc_return) + REG_L a0, TLSDESC_ARG(a0) + jr t0 +END (_dl_tlsdesc_return) + + /* Handler for undefined weak TLS symbols. + Prototype: + _dl_tlsdesc_undefweak (tlsdesc *); + + The second word of the descriptor contains the addend. + Return the addend minus the thread pointer. This ensures + that when the caller adds on the thread pointer it gets back + the addend. */ + +ENTRY (_dl_tlsdesc_undefweak) + REG_L a0, TLSDESC_ARG(a0) + sub a0, a0, tp + jr t0 +END (_dl_tlsdesc_undefweak) + +#ifdef SHARED + /* Handler for dynamic TLS symbols. + Prototype: + _dl_tlsdesc_dynamic (tlsdesc *) ; + + The second word of the descriptor points to a + tlsdesc_dynamic_arg structure. + + Returns the offset between the thread pointer and the + object referenced by the argument. + + unsigned long + _dl_tlsdesc_dynamic (struct tlsdesc *tdp) + { + struct tlsdesc_dynamic_arg *td = tdp->arg; + dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + TCBHEAD_DTV); + if (__builtin_expect (td->gen_count <= dtv[0].counter + && (dtv[td->tlsinfo.ti_module].pointer.val + != TLS_DTV_UNALLOCATED), + 1)) + return dtv[td->tlsinfo.ti_module].pointer.val + + td->tlsinfo.ti_offset + - __thread_pointer; + + return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; + } + */ + +ENTRY (_dl_tlsdesc_dynamic) + /* Save just enough registers to support fast path, if we fall + into slow path we will save additional registers. */ + add sp, sp, -3*SZREG + REG_S t0, 0*SZREG(sp) + REG_S t1, 1*SZREG(sp) + REG_S t2, 2*SZREG(sp) + + /* t0 = dtv */ + REG_L t0, TCBHEAD_DTV(tp) + /* a0 = tdp->arg */ + REG_L a0, TLSDESC_ARG(a0) + /* t1 = td->gen_count */ + REG_L t1, TLSDESC_GEN_COUNT(a0) + /* t2 = dtv[0].counter */ + REG_L t2, DTV_COUNTER(t0) + bltu t2, t1, .Lslow + /* t1 = td->tlsinfo.ti_module */ + REG_L t1, TLSDESC_MODID(a0) + slli t1, t1, PTRLOG + 1 /* sizeof(dtv_t) == sizeof(void*) * 2 */ + add t1, t1, t0 + /* t1 = dtv[td->tlsinfo.ti_module].pointer.val */ + REG_L t1, 0(t1) + li t2, TLS_DTV_UNALLOCATED + beq t1, t2, .Lslow + /* t2 = td->tlsinfo.ti_offset */ + REG_L t2, TLSDESC_MODOFF(a0) + add a0, t1, t2 +.Lret: + sub a0, a0, tp + REG_L t0, 0*SZREG(sp) + REG_L t1, 1*SZREG(sp) + REG_L t2, 2*SZREG(sp) + add sp, sp, 3*SZREG + jr t0 +.Lslow: + /* This is the slow path. We need to call __tls_get_addr() which + means we need to save and restore all the register that the + callee will trash. */ + + /* Save the remaining registers that we must treat as caller save. */ + addi sp, sp, -FRAME_SIZE + REG_S ra, 0*SZREG(sp) + REG_S a1, 1*SZREG(sp) + REG_S a2, 2*SZREG(sp) + REG_S a3, 3*SZREG(sp) + REG_S a4, 4*SZREG(sp) + REG_S a5, 5*SZREG(sp) + REG_S a6, 6*SZREG(sp) + REG_S a7, 7*SZREG(sp) + REG_S t3, 8*SZREG(sp) + REG_S t4, 9*SZREG(sp) + REG_S t5, 10*SZREG(sp) + REG_S t6, 11*SZREG(sp) +#ifndef __riscv_float_abi_soft + FREG_S ft0, (12*SZREG + 0*SZFREG)(sp) + FREG_S ft1, (12*SZREG + 1*SZFREG)(sp) + FREG_S ft2, (12*SZREG + 2*SZFREG)(sp) + FREG_S ft3, (12*SZREG + 3*SZFREG)(sp) + FREG_S ft4, (12*SZREG + 4*SZFREG)(sp) + FREG_S ft5, (12*SZREG + 5*SZFREG)(sp) + FREG_S ft6, (12*SZREG + 6*SZFREG)(sp) + FREG_S ft7, (12*SZREG + 7*SZFREG)(sp) + FREG_S fa0, (12*SZREG + 8*SZFREG)(sp) + FREG_S fa1, (12*SZREG + 9*SZFREG)(sp) + FREG_S fa2, (12*SZREG + 10*SZFREG)(sp) + FREG_S fa3, (12*SZREG + 11*SZFREG)(sp) + FREG_S fa4, (12*SZREG + 12*SZFREG)(sp) + FREG_S fa5, (12*SZREG + 13*SZFREG)(sp) + FREG_S fa6, (12*SZREG + 14*SZFREG)(sp) + FREG_S fa7, (12*SZREG + 15*SZFREG)(sp) + FREG_S ft8, (12*SZREG + 16*SZFREG)(sp) + FREG_S ft9, (12*SZREG + 17*SZFREG)(sp) + FREG_S ft10, (12*SZREG + 18*SZFREG)(sp) + FREG_S ft11, (12*SZREG + 19*SZFREG)(sp) +#endif + + call __tls_get_addr + addi a0, a0, -TLS_DTV_OFFSET + + REG_L ra, 0*SZREG(sp) + REG_L a1, 1*SZREG(sp) + REG_L a2, 2*SZREG(sp) + REG_L a3, 3*SZREG(sp) + REG_L a4, 4*SZREG(sp) + REG_L a5, 5*SZREG(sp) + REG_L a6, 6*SZREG(sp) + REG_L a7, 7*SZREG(sp) + REG_L t3, 8*SZREG(sp) + REG_L t4, 9*SZREG(sp) + REG_L t5, 10*SZREG(sp) + REG_L t6, 11*SZREG(sp) +#ifndef __riscv_float_abi_soft + FREG_L ft0, (12*SZREG + 0*SZFREG)(sp) + FREG_L ft1, (12*SZREG + 1*SZFREG)(sp) + FREG_L ft2, (12*SZREG + 2*SZFREG)(sp) + FREG_L ft3, (12*SZREG + 3*SZFREG)(sp) + FREG_L ft4, (12*SZREG + 4*SZFREG)(sp) + FREG_L ft5, (12*SZREG + 5*SZFREG)(sp) + FREG_L ft6, (12*SZREG + 6*SZFREG)(sp) + FREG_L ft7, (12*SZREG + 7*SZFREG)(sp) + FREG_L fa0, (12*SZREG + 8*SZFREG)(sp) + FREG_L fa1, (12*SZREG + 9*SZFREG)(sp) + FREG_L fa2, (12*SZREG + 10*SZFREG)(sp) + FREG_L fa3, (12*SZREG + 11*SZFREG)(sp) + FREG_L fa4, (12*SZREG + 12*SZFREG)(sp) + FREG_L fa5, (12*SZREG + 13*SZFREG)(sp) + FREG_L fa6, (12*SZREG + 14*SZFREG)(sp) + FREG_L fa7, (12*SZREG + 15*SZFREG)(sp) + FREG_L ft8, (12*SZREG + 16*SZFREG)(sp) + FREG_L ft9, (12*SZREG + 17*SZFREG)(sp) + FREG_L ft10, (12*SZREG + 18*SZFREG)(sp) + FREG_L ft11, (12*SZREG + 19*SZFREG)(sp) +#endif + addi sp, sp, FRAME_SIZE + j .Lret +END (_dl_tlsdesc_dynamic) +#endif diff --git a/sysdeps/riscv/dl-tlsdesc.h b/sysdeps/riscv/dl-tlsdesc.h new file mode 100644 index 0000000000..c7d1bb6d2e --- /dev/null +++ b/sysdeps/riscv/dl-tlsdesc.h @@ -0,0 +1,49 @@ +/* Thread-local storage descriptor handling in the ELF dynamic linker. + RISC-V version. + Copyright (C) 2011-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _DL_TLSDESC_H +# define _DL_TLSDESC_H 1 + +#include + +/* Type used to represent a TLS descriptor in the GOT. */ +struct tlsdesc +{ + ptrdiff_t (*entry) (struct tlsdesc *); + void *arg; +}; + +/* Type used as the argument in a TLS descriptor for a symbol that + needs dynamic TLS offsets. */ +struct tlsdesc_dynamic_arg +{ + tls_index tlsinfo; + size_t gen_count; +}; + +extern unsigned long attribute_hidden + _dl_tlsdesc_return(struct tlsdesc *), + _dl_tlsdesc_undefweak(struct tlsdesc *); + +# ifdef SHARED +extern void *_dl_make_tlsdesc_dynamic (struct link_map *, size_t); +extern unsigned long attribute_hidden _dl_tlsdesc_dynamic(struct tlsdesc *); +# endif + +#endif /* _DL_TLSDESC_H */ diff --git a/sysdeps/riscv/linkmap.h b/sysdeps/riscv/linkmap.h index ac170bb342..2fa3f6d43f 100644 --- a/sysdeps/riscv/linkmap.h +++ b/sysdeps/riscv/linkmap.h @@ -1,4 +1,5 @@ struct link_map_machine { ElfW(Addr) plt; /* Address of .plt. */ + void *tlsdesc_table; /* Address of TLS descriptor hash table. */ }; diff --git a/sysdeps/riscv/tlsdesc.c b/sysdeps/riscv/tlsdesc.c new file mode 100644 index 0000000000..a76aaa9fc5 --- /dev/null +++ b/sysdeps/riscv/tlsdesc.c @@ -0,0 +1,38 @@ +/* Manage TLS descriptors. RISC-V version. + Copyright (C) 2005-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +/* Unmap the dynamic object, but also release its TLS descriptor table + if there is one. */ + +void +_dl_unmap (struct link_map *map) +{ + _dl_unmap_segments (map); + +#ifdef SHARED + if (map->l_mach.tlsdesc_table) + htab_delete (map->l_mach.tlsdesc_table); +#endif +} diff --git a/sysdeps/riscv/tlsdesc.sym b/sysdeps/riscv/tlsdesc.sym new file mode 100644 index 0000000000..652e72ea58 --- /dev/null +++ b/sysdeps/riscv/tlsdesc.sym @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include +#include + +-- + +-- Abuse tls.h macros to derive offsets relative to the thread register. + +TLSDESC_ARG offsetof(struct tlsdesc, arg) +TLSDESC_GEN_COUNT offsetof(struct tlsdesc_dynamic_arg, gen_count) +TLSDESC_MODID offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module) +TLSDESC_MODOFF offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset) +TCBHEAD_DTV offsetof(tcbhead_t, dtv) - sizeof(tcbhead_t) - TLS_TCB_OFFSET +DTV_COUNTER offsetof(dtv_t, counter) +TLS_DTV_UNALLOCATED TLS_DTV_UNALLOCATED +TLS_DTV_OFFSET TLS_DTV_OFFSET