• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision60eae0def70b8a2e768c6a5bec352da9d648b26c (tree)
Time2019-11-01 08:39:10
AuthorWaldemar Brodkorb <wbx@open...>
CommiterWaldemar Brodkorb

Log Message

riscv64: add shared library support

Change Summary

Incremental Difference

--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -480,7 +480,7 @@ config LDSO_LD_LIBRARY_PATH
480480
481481 config UCLIBC_CTOR_DTOR
482482 bool
483- default y
483+ default y if !TARGET_riscv64
484484 help
485485 If you wish to build uClibc with support for global constructor
486486 (ctor) and global destructor (dtor) support, then answer Y here.
--- a/extra/Configs/Config.riscv64
+++ b/extra/Configs/Config.riscv64
@@ -12,4 +12,3 @@ config FORCE_OPTIONS_FOR_ARCH
1212 default y
1313 select ARCH_LITTLE_ENDIAN
1414 select ARCH_HAS_MMU
15- select ARCH_HAS_NO_LDSO
--- a/include/elf.h
+++ b/include/elf.h
@@ -271,6 +271,7 @@ typedef struct
271271 #define EM_AARCH64 183 /* ARM AARCH64 */
272272 #define EM_MICROBLAZE 189 /* Xilinx Microblaze */
273273 #define EM_ARCV2 195 /* ARCv2 Cores */
274+#define EM_RISCV 243 /* RISC-V */
274275 #define EM_CSKY 252 /* C-SKY Cores */
275276
276277 /* NEXT FREE NUMBER: Increment this after adding your official arch number */
@@ -3725,6 +3726,72 @@ typedef Elf32_Addr Elf32_Conflict;
37253726 #define R_ARC_TLS_LE_S9 0x4a
37263727 #define R_ARC_TLS_LE_32 0x4b
37273728
3729+/* RISC-V ELF Flags */
3730+#define EF_RISCV_RVC 0x0001
3731+#define EF_RISCV_FLOAT_ABI 0x0006
3732+#define EF_RISCV_FLOAT_ABI_SOFT 0x0000
3733+#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002
3734+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
3735+#define EF_RISCV_FLOAT_ABI_QUAD 0x0006
3736+
3737+/* RISC-V relocations. */
3738+#define R_RISCV_NONE 0
3739+#define R_RISCV_32 1
3740+#define R_RISCV_64 2
3741+#define R_RISCV_RELATIVE 3
3742+#define R_RISCV_COPY 4
3743+#define R_RISCV_JUMP_SLOT 5
3744+#define R_RISCV_TLS_DTPMOD32 6
3745+#define R_RISCV_TLS_DTPMOD64 7
3746+#define R_RISCV_TLS_DTPREL32 8
3747+#define R_RISCV_TLS_DTPREL64 9
3748+#define R_RISCV_TLS_TPREL32 10
3749+#define R_RISCV_TLS_TPREL64 11
3750+#define R_RISCV_BRANCH 16
3751+#define R_RISCV_JAL 17
3752+#define R_RISCV_CALL 18
3753+#define R_RISCV_CALL_PLT 19
3754+#define R_RISCV_GOT_HI20 20
3755+#define R_RISCV_TLS_GOT_HI20 21
3756+#define R_RISCV_TLS_GD_HI20 22
3757+#define R_RISCV_PCREL_HI20 23
3758+#define R_RISCV_PCREL_LO12_I 24
3759+#define R_RISCV_PCREL_LO12_S 25
3760+#define R_RISCV_HI20 26
3761+#define R_RISCV_LO12_I 27
3762+#define R_RISCV_LO12_S 28
3763+#define R_RISCV_TPREL_HI20 29
3764+#define R_RISCV_TPREL_LO12_I 30
3765+#define R_RISCV_TPREL_LO12_S 31
3766+#define R_RISCV_TPREL_ADD 32
3767+#define R_RISCV_ADD8 33
3768+#define R_RISCV_ADD16 34
3769+#define R_RISCV_ADD32 35
3770+#define R_RISCV_ADD64 36
3771+#define R_RISCV_SUB8 37
3772+#define R_RISCV_SUB16 38
3773+#define R_RISCV_SUB32 39
3774+#define R_RISCV_SUB64 40
3775+#define R_RISCV_GNU_VTINHERIT 41
3776+#define R_RISCV_GNU_VTENTRY 42
3777+#define R_RISCV_ALIGN 43
3778+#define R_RISCV_RVC_BRANCH 44
3779+#define R_RISCV_RVC_JUMP 45
3780+#define R_RISCV_RVC_LUI 46
3781+#define R_RISCV_GPREL_I 47
3782+#define R_RISCV_GPREL_S 48
3783+#define R_RISCV_TPREL_I 49
3784+#define R_RISCV_TPREL_S 50
3785+#define R_RISCV_RELAX 51
3786+#define R_RISCV_SUB6 52
3787+#define R_RISCV_SET6 53
3788+#define R_RISCV_SET8 54
3789+#define R_RISCV_SET16 55
3790+#define R_RISCV_SET32 56
3791+#define R_RISCV_32_PCREL 57
3792+
3793+#define R_RISCV_NUM 58
3794+
37283795 #ifdef __cplusplus
37293796 }
37303797 #endif
--- /dev/null
+++ b/ldso/ldso/riscv64/dl-startup.h
@@ -0,0 +1,90 @@
1+/*
2+ * Architecture specific code used by dl-startup.c
3+ * Copyright (C) 2019 Waldemar Brodkorb <wbx@uclibc-ng.org>
4+ * Ported from GNU libc
5+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6+ */
7+
8+/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
9+
10+ The GNU C Library is free software; you can redistribute it and/or
11+ modify it under the terms of the GNU Lesser General Public License as
12+ published by the Free Software Foundation; either version 2.1 of the
13+ License, or (at your option) any later version.
14+
15+ The GNU C Library is distributed in the hope that it will be useful,
16+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+ Lesser General Public License for more details.
19+
20+ You should have received a copy of the GNU Lesser General Public
21+ License along with the GNU C Library; if not, see
22+ <https://www.gnu.org/licenses/>. */
23+
24+#include <features.h>
25+#include <sys/asm.h>
26+
27+#ifndef _RTLD_PROLOGUE
28+# define _RTLD_PROLOGUE(entry) \
29+ ".globl\t" __STRING (entry) "\n\t" \
30+ ".type\t" __STRING (entry) ", @function\n" \
31+ __STRING (entry) ":\n\t"
32+#endif
33+
34+#ifndef _RTLD_EPILOGUE
35+# define _RTLD_EPILOGUE(entry) \
36+ ".size\t" __STRING (entry) ", . - " __STRING (entry) "\n\t"
37+#endif
38+
39+#define STRINGXP(X) __STRING (X)
40+
41+__asm__(\
42+ ".text\n\
43+ " _RTLD_PROLOGUE (_start) "\
44+ mv a0, sp\n\
45+ jal _dl_start\n\
46+ # Stash user entry point in s0.\n\
47+ mv s0, a0\n\
48+ # See if we were run as a command with the executable file\n\
49+ # name as an extra leading argument.\n\
50+ lw a0, _dl_skip_args\n\
51+ # Load the original argument count.\n\
52+ " STRINGXP (REG_L) " a1, 0(sp)\n\
53+ # Subtract _dl_skip_args from it.\n\
54+ sub a1, a1, a0\n\
55+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
56+ sll a0, a0, " STRINGXP (PTRLOG) "\n\
57+ add sp, sp, a0\n\
58+ # Save back the modified argument count.\n\
59+ " STRINGXP (REG_S) " a1, 0(sp)\n\
60+ # Pass our finalizer function to _start.\n\
61+ lla a0, _dl_fini\n\
62+ # Jump to the user entry point.\n\
63+ jr s0\n\
64+ " _RTLD_EPILOGUE (_start) "\
65+ .previous" \
66+);
67+
68+/* Get a pointer to the argv array. On many platforms this can be just
69+ * the address of the first argument, on other platforms we need to
70+ * do something a little more subtle here. */
71+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1)
72+
73+/* Function calls are not safe until the GOT relocations have been done. */
74+#define NO_FUNCS_BEFORE_BOOTSTRAP
75+
76+/* Handle relocation of the symbols in the dynamic loader. */
77+static __always_inline
78+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
79+ ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Addr) *sym)
80+{
81+ switch (ELF_R_TYPE(rpnt->r_info)) {
82+ case R_RISCV_NONE:
83+ break;
84+ case R_RISCV_JUMP_SLOT:
85+ *reloc_addr = symbol_addr + rpnt->r_addend;
86+ break;
87+ default:
88+ _dl_exit(1);
89+ }
90+}
--- /dev/null
+++ b/ldso/ldso/riscv64/dl-syscalls.h
@@ -0,0 +1 @@
1+/* stub for arch-specific syscall issues */
--- /dev/null
+++ b/ldso/ldso/riscv64/dl-sysdep.h
@@ -0,0 +1,91 @@
1+/*
2+ * Various assembly language/system dependent hacks that are required
3+ * so that we can minimize the amount of platform specific code.
4+ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
5+ * Copyright (C) 2019 by Waldemar Brodkorb <wbx@uclibc-ng.org>
6+ * Ported from GNU C Library
7+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
8+ */
9+
10+/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
11+
12+ The GNU C Library is free software; you can redistribute it and/or
13+ modify it under the terms of the GNU Lesser General Public License as
14+ published by the Free Software Foundation; either version 2.1 of the
15+ License, or (at your option) any later version.
16+
17+ The GNU C Library is distributed in the hope that it will be useful,
18+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20+ Lesser General Public License for more details.
21+
22+ You should have received a copy of the GNU Lesser General Public
23+ License along with the GNU C Library; if not, see
24+ <https://www.gnu.org/licenses/>. */
25+
26+/* Define this if the system uses RELOCA. */
27+#define ELF_USES_RELOCA
28+
29+#include <elf.h>
30+#include <link.h>
31+
32+/* Initialization sequence for the GOT. */
33+#define INIT_GOT(GOT_BASE,MODULE) \
34+{ \
35+ GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
36+ GOT_BASE[1] = (unsigned long) MODULE; \
37+}
38+
39+/* Here we define the magic numbers that this dynamic loader should accept */
40+#define MAGIC1 EM_RISCV
41+#undef MAGIC2
42+
43+/* Used for error messages */
44+#define ELF_TARGET "RISC-V"
45+
46+struct elf_resolve;
47+unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
48+
49+#define ELF_MACHINE_JMP_SLOT R_RISCV_JUMP_SLOT
50+
51+#define elf_machine_type_class(type) \
52+ ((ELF_RTYPE_CLASS_PLT * ((type) == ELF_MACHINE_JMP_SLOT \
53+ || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_DTPREL32) \
54+ || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_DTPMOD32) \
55+ || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_TPREL32) \
56+ || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPREL64) \
57+ || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPMOD64) \
58+ || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64))) \
59+ | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
60+
61+
62+/* Return the link-time address of _DYNAMIC. */
63+static inline ElfW(Addr)
64+elf_machine_dynamic (void)
65+{
66+ extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__ ((visibility ("hidden")));
67+ return _GLOBAL_OFFSET_TABLE_;
68+}
69+
70+
71+/* Return the run-time load address of the shared object. */
72+static __always_inline ElfW(Addr) __attribute__ ((unused))
73+elf_machine_load_address (void)
74+{
75+ ElfW(Addr) load_addr;
76+ __asm__ ("lla %0, _DYNAMIC" : "=r" (load_addr));
77+ return load_addr - elf_machine_dynamic ();
78+}
79+
80+static __always_inline void
81+elf_machine_relative(Elf64_Addr load_off, const Elf64_Addr rel_addr,
82+ Elf64_Word relative_count)
83+{
84+ Elf64_Rela *rpnt = (Elf64_Rela*)rel_addr;
85+ --rpnt;
86+ do {
87+ Elf64_Addr *const reloc_addr = (Elf64_Addr*)(load_off + (++rpnt)->r_offset);
88+
89+ *reloc_addr = load_off + rpnt->r_addend;
90+ } while (--relative_count);
91+}
--- /dev/null
+++ b/ldso/ldso/riscv64/elfinterp.c
@@ -0,0 +1,279 @@
1+/* RISCV ELF shared library loader suppport
2+ *
3+ * Copyright (C) 2001-2004 Erik Andersen
4+ * Copyright (C) 2019 Waldemar Brodkorb <wbx@uclibc-ng.org>
5+ *
6+ * All rights reserved.
7+ *
8+ * Redistribution and use in source and binary forms, with or without
9+ * modification, are permitted provided that the following conditions
10+ * are met:
11+ * 1. Redistributions of source code must retain the above copyright
12+ * notice, this list of conditions and the following disclaimer.
13+ * 2. The name of the above contributors may not be
14+ * used to endorse or promote products derived from this software
15+ * without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
18+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+ * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
21+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27+ * SUCH DAMAGE.
28+ */
29+
30+/* Program to load an ELF binary on a linux system, and run it.
31+ References to symbols in sharable libraries can be resolved by either
32+ an ELF sharable library or a linux style of shared library. */
33+
34+#include "ldso.h"
35+
36+#if defined(USE_TLS) && USE_TLS
37+#include "dl-tls.h"
38+#include "tlsdeschtab.h"
39+#endif
40+
41+extern int _dl_linux_resolve(void);
42+
43+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
44+{
45+ ELF_RELOC *this_reloc;
46+ char *strtab;
47+ ElfW(Sym) *symtab;
48+ int symtab_index;
49+ char *rel_addr;
50+ char *new_addr;
51+ char **got_addr;
52+ ElfW(Addr) instr_addr;
53+ char *symname;
54+
55+ rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
56+ this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
57+ symtab_index = ELF_R_SYM(this_reloc->r_info);
58+
59+ symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
60+ strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
61+ symname = strtab + symtab[symtab_index].st_name;
62+
63+ /* Address of jump instruction to fix up */
64+ instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
65+ got_addr = (char **)instr_addr;
66+
67+ /* Get the address of the GOT entry */
68+ new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
69+ if (unlikely(!new_addr)) {
70+ _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
71+ _dl_exit(1);
72+ }
73+#if defined (__SUPPORT_LD_DEBUG__)
74+ if (_dl_debug_bindings) {
75+ _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
76+ if (_dl_debug_detail) _dl_dprintf(_dl_debug_file,
77+ "\tpatched %x ==> %x @ %x", *got_addr, new_addr, got_addr);
78+ }
79+ if (!_dl_debug_nofixups) {
80+ *got_addr = new_addr;
81+ }
82+#else
83+ *got_addr = new_addr;
84+#endif
85+ return (unsigned long)new_addr;
86+}
87+
88+static int
89+_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope,
90+ unsigned long rel_addr, unsigned long rel_size,
91+ int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope,
92+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
93+{
94+ unsigned int i;
95+ char *strtab;
96+ ElfW(Sym) *symtab;
97+ ELF_RELOC *rpnt;
98+ int symtab_index;
99+
100+ /* Parse the relocation information */
101+ rpnt = (ELF_RELOC *)rel_addr;
102+ rel_size = rel_size / sizeof(ELF_RELOC);
103+
104+ symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
105+ strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
106+
107+ for (i = 0; i < rel_size; i++, rpnt++) {
108+ int res;
109+
110+ symtab_index = ELF_R_SYM(rpnt->r_info);
111+
112+ debug_sym(symtab, strtab, symtab_index);
113+ debug_reloc(symtab, strtab, rpnt);
114+
115+ res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
116+
117+ if (res==0)
118+ continue;
119+
120+ _dl_dprintf(2, "\n%s: ", _dl_progname);
121+
122+ if (symtab_index)
123+ _dl_dprintf(2, "symbol '%s': ",
124+ strtab + symtab[symtab_index].st_name);
125+
126+ if (unlikely(res < 0)) {
127+ int reloc_type = ELF_R_TYPE(rpnt->r_info);
128+ _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
129+ _dl_exit(-res);
130+ } else if (unlikely(res > 0)) {
131+ _dl_dprintf(2, "can't resolve symbol\n");
132+ return res;
133+ }
134+ }
135+
136+ return 0;
137+}
138+
139+static int
140+_dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
141+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
142+{
143+ int reloc_type;
144+ int symtab_index;
145+ char *symname;
146+#if defined USE_TLS && USE_TLS
147+ struct elf_resolve *tls_tpnt = NULL;
148+#endif
149+ struct symbol_ref sym_ref;
150+ ElfW(Addr) *reloc_addr;
151+ ElfW(Addr) symbol_addr;
152+#if defined (__SUPPORT_LD_DEBUG__)
153+ ElfW(Addr) old_val;
154+#endif
155+
156+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
157+ reloc_type = ELF_R_TYPE(rpnt->r_info);
158+ symtab_index = ELF_R_SYM(rpnt->r_info);
159+ sym_ref.sym = &symtab[symtab_index];
160+ sym_ref.tpnt = NULL;
161+ symbol_addr = 0;
162+ symname = strtab + sym_ref.sym->st_name;
163+
164+ if (symtab_index) {
165+ symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
166+ elf_machine_type_class(reloc_type), &sym_ref);
167+
168+ /*
169+ * We want to allow undefined references to weak symbols - this might
170+ * have been intentional. We should not be linking local symbols
171+ * here, so all bases should be covered.
172+ */
173+ if (unlikely (!symbol_addr &&
174+ (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) &&
175+ (ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))) {
176+ return 1;
177+ }
178+ if (_dl_trace_prelink) {
179+ _dl_debug_lookup (symname, tpnt, &symtab[symtab_index],
180+ &sym_ref, elf_machine_type_class(reloc_type));
181+ }
182+#if defined USE_TLS && USE_TLS
183+ tls_tpnt = sym_ref.tpnt;
184+#endif
185+ } else {
186+ /*
187+ * Relocs against STN_UNDEF are usually treated as using a
188+ * symbol value of zero, and using the module containing the
189+ * reloc itself.
190+ */
191+ symbol_addr = sym_ref.sym->st_value;
192+#if defined USE_TLS && USE_TLS
193+ tls_tpnt = tpnt;
194+#endif
195+ }
196+
197+#if defined (__SUPPORT_LD_DEBUG__)
198+ old_val = *reloc_addr;
199+#endif
200+
201+ switch (reloc_type) {
202+ case R_RISCV_NONE:
203+ break;
204+ case R_RISCV_64: /* REL_SYMBOLIC */
205+ case R_RISCV_JUMP_SLOT: /* REL_PLT */
206+ *reloc_addr = symbol_addr + rpnt->r_addend;
207+ break;
208+ case R_RISCV_RELATIVE:
209+ *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
210+ break;
211+ case R_RISCV_COPY:
212+ _dl_memcpy((void *) reloc_addr,
213+ (void *) symbol_addr, sym_ref.sym->st_size);
214+ break;
215+ default:
216+ return -1; /*call _dl_exit(1) */
217+ }
218+
219+#if defined (__SUPPORT_LD_DEBUG__)
220+ if (_dl_debug_reloc && _dl_debug_detail) {
221+ _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
222+ old_val, *reloc_addr, reloc_addr);
223+ }
224+#endif
225+
226+ return 0;
227+}
228+
229+static int
230+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
231+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
232+{
233+ int reloc_type;
234+ ElfW(Addr) *reloc_addr;
235+#if defined (__SUPPORT_LD_DEBUG__)
236+ ElfW(Addr) old_val;
237+#endif
238+
239+ (void)scope;
240+ (void)strtab;
241+
242+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
243+ reloc_type = ELF_R_TYPE(rpnt->r_info);
244+
245+#if defined (__SUPPORT_LD_DEBUG__)
246+ old_val = *reloc_addr;
247+#endif
248+
249+ switch (reloc_type) {
250+ case R_RISCV_NONE:
251+ break;
252+ case R_RISCV_JUMP_SLOT:
253+ *reloc_addr += tpnt->loadaddr;
254+ break;
255+ default:
256+ return -1; /*call _dl_exit(1) */
257+ }
258+
259+#if defined (__SUPPORT_LD_DEBUG__)
260+ if (_dl_debug_reloc && _dl_debug_detail) {
261+ _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
262+ old_val, *reloc_addr, reloc_addr);
263+ }
264+#endif
265+
266+ return 0;
267+}
268+
269+void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
270+ unsigned long rel_addr, unsigned long rel_size)
271+{
272+ (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
273+}
274+
275+int _dl_parse_relocation_information(struct dyn_elf *rpnt,
276+ struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size)
277+{
278+ return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc);
279+}
--- /dev/null
+++ b/ldso/ldso/riscv64/resolve.S
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2019 by Waldemar Brodkorb <wbx@uclibc-ng.org>
3+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4+ * ported from GNU libc
5+ */
6+
7+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
8+
9+ The GNU C Library is free software; you can redistribute it and/or
10+ modify it under the terms of the GNU Lesser General Public License as
11+ published by the Free Software Foundation; either version 2.1 of the
12+ License, or (at your option) any later version.
13+
14+ The GNU C Library is distributed in the hope that it will be useful,
15+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+ Lesser General Public License for more details.
18+
19+ You should have received a copy of the GNU Lesser General Public
20+ License along with the GNU C Library. If not, see
21+ <https://www.gnu.org/licenses/>. */
22+
23+#include <features.h>
24+
25+#include <sysdep.h>
26+#include <sys/asm.h>
27+
28+/* Assembler veneer called from the PLT header code for lazy loading.
29+ The PLT header passes its own args in t0-t2. */
30+
31+#ifdef __riscv_float_abi_soft
32+# define FRAME_SIZE (-((-10 * SZREG) & ALMASK))
33+#else
34+# define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK))
35+#endif
36+
37+ENTRY (_dl_linux_resolve)
38+ # Save arguments to stack.
39+ addi sp, sp, -FRAME_SIZE
40+ REG_S ra, 9*SZREG(sp)
41+ REG_S a0, 1*SZREG(sp)
42+ REG_S a1, 2*SZREG(sp)
43+ REG_S a2, 3*SZREG(sp)
44+ REG_S a3, 4*SZREG(sp)
45+ REG_S a4, 5*SZREG(sp)
46+ REG_S a5, 6*SZREG(sp)
47+ REG_S a6, 7*SZREG(sp)
48+ REG_S a7, 8*SZREG(sp)
49+
50+#ifndef __riscv_float_abi_soft
51+ FREG_S fa0, (10*SZREG + 0*SZFREG)(sp)
52+ FREG_S fa1, (10*SZREG + 1*SZFREG)(sp)
53+ FREG_S fa2, (10*SZREG + 2*SZFREG)(sp)
54+ FREG_S fa3, (10*SZREG + 3*SZFREG)(sp)
55+ FREG_S fa4, (10*SZREG + 4*SZFREG)(sp)
56+ FREG_S fa5, (10*SZREG + 5*SZFREG)(sp)
57+ FREG_S fa6, (10*SZREG + 6*SZFREG)(sp)
58+ FREG_S fa7, (10*SZREG + 7*SZFREG)(sp)
59+#endif
60+
61+ # Update .got.plt and obtain runtime address of callee.
62+ slli a1, t1, 1
63+ mv a0, t0 # link map
64+ add a1, a1, t1 # reloc offset (== thrice the .got.plt offset)
65+ la a2, _dl_fixup
66+ jalr a2
67+ mv t1, a0
68+
69+ # Restore arguments from stack.
70+ REG_L ra, 9*SZREG(sp)
71+ REG_L a0, 1*SZREG(sp)
72+ REG_L a1, 2*SZREG(sp)
73+ REG_L a2, 3*SZREG(sp)
74+ REG_L a3, 4*SZREG(sp)
75+ REG_L a4, 5*SZREG(sp)
76+ REG_L a5, 6*SZREG(sp)
77+ REG_L a6, 7*SZREG(sp)
78+ REG_L a7, 8*SZREG(sp)
79+
80+#ifndef __riscv_float_abi_soft
81+ FREG_L fa0, (10*SZREG + 0*SZFREG)(sp)
82+ FREG_L fa1, (10*SZREG + 1*SZFREG)(sp)
83+ FREG_L fa2, (10*SZREG + 2*SZFREG)(sp)
84+ FREG_L fa3, (10*SZREG + 3*SZFREG)(sp)
85+ FREG_L fa4, (10*SZREG + 4*SZFREG)(sp)
86+ FREG_L fa5, (10*SZREG + 5*SZFREG)(sp)
87+ FREG_L fa6, (10*SZREG + 6*SZFREG)(sp)
88+ FREG_L fa7, (10*SZREG + 7*SZFREG)(sp)
89+#endif
90+
91+ addi sp, sp, FRAME_SIZE
92+
93+ # Invoke the callee.
94+ jr t1
95+END (_dl_linux_resolve)
96+
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -500,7 +500,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
500500 #endif
501501 }
502502 # endif
503-#endif
504503
505504 /* Note: It is possible that any initialization done above could
506505 * have resulted in errno being set nonzero, so set it to 0 before
@@ -512,6 +511,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
512511 /* Set h_errno to 0 as well */
513512 if (likely(not_null_ptr(__h_errno_location)))
514513 *(__h_errno_location()) = 0;
514+#endif
515515
516516 #if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__
517517 /* Memory for the cancellation buffer. */
--- a/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h
@@ -8,7 +8,7 @@
88 #undef __UCLIBC_ABORT_INSTRUCTION__
99
1010 /* can your target use syscall6() for mmap ? */
11-#undef __UCLIBC_MMAP_HAS_6_ARGS__
11+#define __UCLIBC_MMAP_HAS_6_ARGS__
1212
1313 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
1414
--- /dev/null
+++ b/libc/sysdeps/linux/riscv64/bits/uClibc_page.h
@@ -0,0 +1,34 @@
1+/* Copyright (C) 2004 Erik Andersen
2+ *
3+ * This library is free software; you can redistribute it and/or
4+ * modify it under the terms of the GNU Lesser General Public
5+ * License as published by the Free Software Foundation; either
6+ * version 2.1 of the License, or (at your option) any later version.
7+ *
8+ * The GNU C Library is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public
14+ * License along with the GNU C Library; see the file COPYING.LIB. If
15+ * not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+/* Supply an architecture specific value for PAGE_SIZE and friends. */
19+
20+#ifndef _UCLIBC_PAGE_H
21+#define _UCLIBC_PAGE_H
22+
23+/* PAGE_SHIFT determines the page size -- in this case 4096 */
24+#define PAGE_SHIFT 13
25+#define PAGE_SIZE (1UL << PAGE_SHIFT)
26+#define PAGE_MASK (~(PAGE_SIZE-1))
27+
28+/* Some architectures always use 12 as page shift for mmap2() eventhough the
29+ * real PAGE_SHIFT != 12. Other architectures use the same value as
30+ * PAGE_SHIFT...
31+ */
32+#define MMAP2_PAGE_SHIFT PAGE_SHIFT
33+
34+#endif /* _UCLIBC_PAGE_H */
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -122,6 +122,11 @@
122122 #define ELFCLASSM ELFCLASS32
123123 #endif
124124
125+#if defined(__riscv)
126+#define MATCH_MACHINE(x) (x == EM_RISCV)
127+#define ELFCLASSM ELFCLASS64
128+#endif
129+
125130 #if defined(__sh__)
126131 #define MATCH_MACHINE(x) (x == EM_SH)
127132 #define ELFCLASSM ELFCLASS32