Skip to content

Commit c31b1f5

Browse files
VincentZWCdjdelorierh
authored andcommitted
riscv: support GNU indirect function
Enable riscv glibc to support GNU indirect function
1 parent 2cd361b commit c31b1f5

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

libc-abis

+1
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ IFUNC sparc64-*-linux*
4848
IFUNC sparc-*-linux*
4949
# Absolute (SHN_ABS) symbols working correctly.
5050
ABSOLUTE
51+
IFUNC riscv*-linux*

sysdeps/riscv/dl-irel.h

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* Machine-dependent ELF indirect relocation inline functions.
2+
RISC-V version.
3+
Copyright (C) 2020 Free Software Foundation, Inc.
4+
This file is part of the GNU C Library.
5+
6+
The GNU C Library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
The GNU C Library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with the GNU C Library; if not, see
18+
<https://www.gnu.org/licenses/>. */
19+
20+
#ifndef _DL_IREL_H
21+
#define _DL_IREL_H
22+
23+
#include <stdio.h>
24+
#include <unistd.h>
25+
#include <ldsodefs.h>
26+
#include <sysdep.h>
27+
28+
#define ELF_MACHINE_IRELA 1
29+
30+
static inline ElfW(Addr)
31+
__attribute ((always_inline))
32+
elf_ifunc_invoke (ElfW(Addr) addr)
33+
{
34+
/* The second argument is a void pointer to preserve the extension
35+
fexibility. */
36+
return ((ElfW(Addr) (*) (uint64_t, void *)) (addr))
37+
(GLRO(dl_hwcap), NULL);
38+
}
39+
40+
static inline void
41+
__attribute ((always_inline))
42+
elf_irela (const ElfW(Rela) *reloc)
43+
{
44+
ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
45+
const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
46+
47+
if (__glibc_likely (r_type == R_RISCV_IRELATIVE))
48+
{
49+
ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend);
50+
*reloc_addr = value;
51+
}
52+
else
53+
__libc_fatal ("Unexpected reloc type in static binary.\n");
54+
}
55+
56+
#endif

sysdeps/riscv/dl-machine.h

+22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <elf/elf.h>
2626
#include <sys/asm.h>
2727
#include <dl-tls.h>
28+
#include <dl-irel.h>
2829

2930
#ifndef _RTLD_PROLOGUE
3031
# define _RTLD_PROLOGUE(entry) \
@@ -176,6 +177,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
176177
if (sym_map != NULL)
177178
value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
178179

180+
if (sym != NULL
181+
&& __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
182+
&& __glibc_likely (sym->st_shndx != SHN_UNDEF)
183+
&& __glibc_likely (!skip_ifunc))
184+
value = elf_ifunc_invoke (value);
185+
186+
179187
switch (r_type)
180188
{
181189
#ifndef RTLD_BOOTSTRAP
@@ -251,6 +259,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
251259
}
252260
#endif
253261

262+
case R_RISCV_IRELATIVE:
263+
value = map->l_addr + reloc->r_addend;
264+
if (__glibc_likely (!skip_ifunc))
265+
value = elf_ifunc_invoke (value);
266+
*addr_field = value;
267+
break;
268+
254269
case R_RISCV_JUMP_SLOT:
255270
case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
256271
*addr_field = value;
@@ -292,6 +307,13 @@ elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
292307
else
293308
*reloc_addr = map->l_mach.plt;
294309
}
310+
else if (__glibc_unlikely (r_type == R_RISCV_IRELATIVE))
311+
{
312+
ElfW(Addr) value = map->l_addr + reloc->r_addend;
313+
if (__glibc_likely (!skip_ifunc))
314+
value = elf_ifunc_invoke (value);
315+
*reloc_addr = value;
316+
}
295317
else
296318
_dl_reloc_bad_type (map, r_type, 1);
297319
}

0 commit comments

Comments
 (0)