OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [tools/] [riscv-gnu-toolchain-master/] [glibc/] [sysdeps/] [riscv/] [dl-machine.h] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 serginhofr
/* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
2
   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4
   This file is part of the GNU C Library.
5
   Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
6
 
7
   The GNU C Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Lesser General Public
9
   License as published by the Free Software Foundation; either
10
   version 2.1 of the License, or (at your option) any later version.
11
 
12
   The GNU C Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Lesser General Public License for more details.
16
 
17
   You should have received a copy of the GNU Lesser General Public
18
   License along with the GNU C Library; if not, write to the Free
19
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20
   02111-1307 USA.  */
21
 
22
/*  FIXME: Profiling of shared libraries is not implemented yet.  */
23
#ifndef dl_machine_h
24
#define dl_machine_h
25
 
26
#define ELF_MACHINE_NAME "RISC-V"
27
#define EM_RISCV 243
28
 
29
/* Relocs. */
30
#define R_RISCV_NONE          0
31
#define R_RISCV_32            1
32
#define R_RISCV_64            2
33
#define R_RISCV_RELATIVE      3
34
#define R_RISCV_COPY          4
35
#define R_RISCV_JUMP_SLOT     5
36
#define R_RISCV_TLS_DTPMOD32  6
37
#define R_RISCV_TLS_DTPMOD64  7
38
#define R_RISCV_TLS_DTPREL32  8
39
#define R_RISCV_TLS_DTPREL64  9
40
#define R_RISCV_TLS_TPREL32  10
41
#define R_RISCV_TLS_TPREL64  11
42
 
43
#include <entry.h>
44
 
45
#ifndef ENTRY_POINT
46
#error ENTRY_POINT needs to be defined for MIPS.
47
#endif
48
 
49
#include <sys/asm.h>
50
#include <dl-tls.h>
51
 
52
#ifndef _RTLD_PROLOGUE
53
# define _RTLD_PROLOGUE(entry)                                          \
54
        ".globl\t" __STRING(entry) "\n\t"                               \
55
        ".type\t" __STRING(entry) ", @function\n"                       \
56
        __STRING(entry) ":\n\t"
57
#endif
58
 
59
#ifndef _RTLD_EPILOGUE
60
# define _RTLD_EPILOGUE(entry)                                          \
61
        ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
62
#endif
63
 
64
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
65
   This only makes sense on MIPS when using PLTs, so choose the
66
   PLT relocation (not encountered when not using PLTs).  */
67
#define ELF_MACHINE_JMP_SLOT                    R_RISCV_JUMP_SLOT
68
#define elf_machine_type_class(type)                            \
69
  ((ELF_RTYPE_CLASS_PLT * ((type) == ELF_MACHINE_JMP_SLOT       \
70
     || (_RISCV_SZPTR == 32 && (type) == R_RISCV_TLS_DTPREL32)  \
71
     || (_RISCV_SZPTR == 32 && (type) == R_RISCV_TLS_DTPMOD32)  \
72
     || (_RISCV_SZPTR == 32 && (type) == R_RISCV_TLS_TPREL32)   \
73
     || (_RISCV_SZPTR == 64 && (type) == R_RISCV_TLS_DTPREL64)  \
74
     || (_RISCV_SZPTR == 64 && (type) == R_RISCV_TLS_DTPMOD64)  \
75
     || (_RISCV_SZPTR == 64 && (type) == R_RISCV_TLS_TPREL64))) \
76
   | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
77
 
78
#define ELF_MACHINE_NO_REL 1
79
#define ELF_MACHINE_NO_RELA 0
80
 
81
/* Return nonzero iff ELF header is compatible with the running host.  */
82
static inline int __attribute_used__
83
elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
84
{
85
  return ehdr->e_machine == EM_RISCV;
86
}
87
 
88
/* Return the link-time address of _DYNAMIC.  */
89
static inline ElfW(Addr)
90
elf_machine_dynamic (void)
91
{
92
  extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__((visibility("hidden")));
93
  return _GLOBAL_OFFSET_TABLE_;
94
}
95
 
96
#define STRINGXP(X) __STRING(X)
97
#define STRINGXV(X) STRINGV_(X)
98
#define STRINGV_(...) # __VA_ARGS__
99
 
100
/* Return the run-time load address of the shared object.  */
101
static inline ElfW(Addr)
102
elf_machine_load_address (void)
103
{
104
  ElfW(Addr) load_addr;
105
  asm ("lla %0, _DYNAMIC" : "=r"(load_addr));
106
  return load_addr - elf_machine_dynamic ();
107
}
108
 
109
/* Initial entry point code for the dynamic linker.
110
   The C function `_dl_start' is the real entry point;
111
   its return value is the user program's entry point. */
112
 
113
#define RTLD_START asm (\
114
        ".text\n\
115
        " _RTLD_PROLOGUE(ENTRY_POINT) "\
116
        move a0, sp\n\
117
        jal _dl_start\n\
118
        # Stash user entry point in s0.\n\
119
        move s0, a0\n\
120
        # See if we were run as a command with the executable file\n\
121
        # name as an extra leading argument.\n\
122
        lw a0, _dl_skip_args\n\
123
        # Load the original argument count.\n\
124
        " STRINGXP(REG_L) " a1, 0(sp)\n\
125
        # Subtract _dl_skip_args from it.\n\
126
        sub a1, a1, a0\n\
127
        # Adjust the stack pointer to skip _dl_skip_args words.\n\
128
        sll a0, a0, " STRINGXP (PTRLOG) "\n\
129
        add sp, sp, a0\n\
130
        # Save back the modified argument count.\n\
131
        " STRINGXP(REG_S) " a1, 0(sp)\n\
132
        # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
133
        " STRINGXP(REG_L) " a0, _rtld_local\n\
134
        add a2, sp, " STRINGXP (SZREG) "\n\
135
        sll a3, a1, " STRINGXP (PTRLOG) "\n\
136
        add a3, a3, a2\n\
137
        add a3, a3, " STRINGXP (SZREG) "\n\
138
        # Call the function to run the initializers.\n\
139
        jal _dl_init\n\
140
        # Pass our finalizer function to _start.\n\
141
        lla a0, _dl_fini\n\
142
        # Jump to the user entry point.\n\
143
        jr s0\n\
144
        " _RTLD_EPILOGUE(ENTRY_POINT) "\
145
        .previous" \
146
);
147
 
148
/* Names of the architecture-specific auditing callback functions.  */
149
# ifdef __riscv64
150
#  define ARCH_LA_PLTENTER mips_n64_gnu_pltenter
151
#  define ARCH_LA_PLTEXIT mips_n64_gnu_pltexit
152
# else
153
#  define ARCH_LA_PLTENTER mips_n32_gnu_pltenter
154
#  define ARCH_LA_PLTEXIT mips_n32_gnu_pltexit
155
# endif
156
 
157
/* Bias .got.plt entry by the offset requested by the PLT header. */
158
#define elf_machine_plt_value(map, reloc, value) (value)
159
#define elf_machine_fixup_plt(map, t, reloc, reloc_addr, value) \
160
  (*(ElfW(Addr) *)(reloc_addr) = (value))
161
 
162
#endif /* !dl_machine_h */
163
 
164
#ifdef RESOLVE_MAP
165
 
166
/* Perform a relocation described by R_INFO at the location pointed to
167
   by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
168
   MAP is the object containing the reloc.  */
169
 
170
auto inline void
171
__attribute__ ((always_inline))
172
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
173
                  const ElfW(Sym) *sym, const struct r_found_version *version,
174
                  void *const reloc_addr, int skip_ifunc)
175
{
176
  ElfW(Addr) r_info = reloc->r_info;
177
  const unsigned long int r_type = ELFW(R_TYPE) (r_info);
178
  ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
179
  const ElfW(Sym) *const __attribute__((unused)) refsym = sym;
180
  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
181
  ElfW(Addr) value = 0;
182
  if (sym_map != NULL)
183
    value = sym_map->l_addr + sym->st_value + reloc->r_addend;
184
 
185
  switch (r_type)
186
    {
187
#ifndef RTLD_BOOTSTRAP
188
    case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
189
      if (sym_map)
190
        *addr_field = sym_map->l_tls_modid;
191
      break;
192
 
193
    case __WORDSIZE == 64 ? R_RISCV_TLS_DTPREL64 : R_RISCV_TLS_DTPREL32:
194
      if (sym != NULL)
195
        *addr_field = TLS_DTPREL_VALUE (sym) + reloc->r_addend;
196
      break;
197
 
198
    case __WORDSIZE == 64 ? R_RISCV_TLS_TPREL64 : R_RISCV_TLS_TPREL32:
199
      if (sym != NULL)
200
        {
201
          CHECK_STATIC_TLS (map, sym_map);
202
          *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
203
        }
204
      break;
205
 
206
    case R_RISCV_COPY:
207
      {
208
        if (__builtin_expect (sym == NULL, 0))
209
          /* This can happen in trace mode if an object could not be
210
             found.  */
211
          break;
212
 
213
        /* Handle TLS copy relocations.  */
214
        if (__glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_TLS))
215
          {
216
            /* There's nothing to do if the symbol is in .tbss.  */
217
            if (__glibc_likely (sym->st_value >= sym_map->l_tls_initimage_size))
218
              break;
219
            value += (ElfW(Addr)) sym_map->l_tls_initimage - sym_map->l_addr;
220
          }
221
 
222
        size_t size = sym->st_size;
223
        if (__builtin_expect (sym->st_size != refsym->st_size, 0))
224
          {
225
            const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
226
            if (sym->st_size > refsym->st_size)
227
              size = refsym->st_size;
228
            if (sym->st_size > refsym->st_size || GLRO(dl_verbose))
229
              _dl_error_printf ("\
230
  %s: Symbol `%s' has different size in shared object, consider re-linking\n",
231
                                rtld_progname ?: "<program name unknown>",
232
                                strtab + refsym->st_name);
233
          }
234
 
235
        memcpy (reloc_addr, (void *)value, size);
236
        break;
237
      }
238
#endif
239
 
240
#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
241
    case R_RISCV_RELATIVE:
242
      {
243
# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
244
        /* This is defined in rtld.c, but nowhere in the static libc.a;
245
           make the reference weak so static programs can still link.
246
           This declaration cannot be done when compiling rtld.c
247
           (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
248
           common defn for _dl_rtld_map, which is incompatible with a
249
           weak decl in the same file.  */
250
#  ifndef SHARED
251
        weak_extern (GL(dl_rtld_map));
252
#  endif
253
        if (map != &GL(dl_rtld_map)) /* Already done in rtld itself.  */
254
# endif
255
          *addr_field = map->l_addr + reloc->r_addend;
256
      break;
257
    }
258
#endif
259
 
260
    case R_RISCV_JUMP_SLOT:
261
    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
262
      *addr_field = value;
263
      break;
264
 
265
    case R_RISCV_NONE:
266
      break;
267
 
268
    default:
269
      _dl_reloc_bad_type (map, r_type, 0);
270
      break;
271
    }
272
}
273
 
274
auto inline void
275
__attribute__((always_inline))
276
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
277
                          void *const reloc_addr)
278
{
279
  *(ElfW(Addr) *)reloc_addr = l_addr + reloc->r_addend;
280
}
281
 
282
auto inline void
283
__attribute__((always_inline))
284
elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
285
                      const ElfW(Rela) *reloc, int skip_ifunc)
286
{
287
  ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
288
  const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info);
289
 
290
  /* Check for unexpected PLT reloc type.  */
291
  if (__builtin_expect (r_type == R_RISCV_JUMP_SLOT, 1))
292
    {
293
      if (__builtin_expect (map->l_mach.plt, 0) == 0)
294
        {
295
          if (l_addr)
296
            *reloc_addr += l_addr;
297
        }
298
      else
299
        *reloc_addr = map->l_mach.plt;
300
    }
301
  else
302
    _dl_reloc_bad_type (map, r_type, 1);
303
}
304
 
305
/* Set up the loaded object described by L so its stub function
306
   will jump to the on-demand fixup code __dl_runtime_resolve.  */
307
 
308
auto inline int
309
__attribute__((always_inline))
310
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
311
{
312
#ifndef RTLD_BOOTSTRAP
313
  /* If using PLTs, fill in the first two entries of .got.plt.  */
314
  if (l->l_info[DT_JMPREL])
315
    {
316
      extern void _dl_runtime_resolve (void) __attribute__((visibility("hidden")));
317
      ElfW(Addr) *gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
318
      /* If a library is prelinked but we have to relocate anyway,
319
         we have to be able to undo the prelinking of .got.plt.
320
         The prelinker saved the address of .plt for us here.  */
321
      if (gotplt[1])
322
        l->l_mach.plt = gotplt[1] + l->l_addr;
323
      gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve;
324
      gotplt[1] = (ElfW(Addr)) l;
325
    }
326
#endif
327
 
328
  return lazy;
329
}
330
 
331
#endif /* RESOLVE_MAP */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.