Patches objdump (XCC)
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.14.1-riscv.patch
1 diff --git a/glibc-2.14.1/scripts/config.sub b/glibc-2.14.1/scripts/config.sub
2 index 459eb41..46a0794 100755
3 --- a/glibc-2.14.1/scripts/config.sub
4 +++ glibc-2.14.1/scripts/config.sub
5 @@ -290,6 +290,7 @@ case $basic_machine in
6         | pdp10 | pdp11 | pj | pjl \
7         | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
8         | pyramid \
9 +       | riscv \
10         | rx \
11         | score \
12         | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
13 diff --git a/glibc-2.14.1/sysdeps/riscv/Implies b/glibc-2.14.1/sysdeps/riscv/Implies
14 new file mode 100644
15 index 0000000..3c3d8e7
16 --- /dev/null
17 +++ glibc-2.14.1/sysdeps/riscv/Implies
18 @@ -0,0 +1,5 @@
19 +ieee754/flt-32
20 +ieee754/dbl-64
21 +
22 +# This needs to change to support rv32
23 +riscv/rv64
24 diff --git a/glibc-2.14.1/sysdeps/riscv/Makefile b/glibc-2.14.1/sysdeps/riscv/Makefile
25 new file mode 100644
26 index 0000000..b21eb39
27 --- /dev/null
28 +++ glibc-2.14.1/sysdeps/riscv/Makefile
29 @@ -0,0 +1,9 @@
30 +ifeq ($(subdir),misc)
31 +sysdep_headers += sys/asm.h sgidefs.h
32 +endif
33 +
34 +ifeq ($(subdir),rt)
35 +librt-sysdep_routines += rt-sysdep
36 +endif
37 +
38 +ASFLAGS-.os += $(pic-ccflag)
39 diff --git a/glibc-2.14.1/sysdeps/riscv/Versions b/glibc-2.14.1/sysdeps/riscv/Versions
40 new file mode 100644
41 index 0000000..f705634
42 --- /dev/null
43 +++ glibc-2.14.1/sysdeps/riscv/Versions
44 @@ -0,0 +1,5 @@
45 +libc {
46 +  GLIBC_2.0 {
47 +    __memcpy_g;
48 +  }
49 +}
50 diff --git a/glibc-2.14.1/sysdeps/riscv/__longjmp.S b/glibc-2.14.1/sysdeps/riscv/__longjmp.S
51 new file mode 100644
52 index 0000000..2b8e8e1
53 --- /dev/null
54 +++ glibc-2.14.1/sysdeps/riscv/__longjmp.S
55 @@ -0,0 +1,67 @@
56 +/* Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004
57 +       Free Software Foundation, Inc.
58 +   This file is part of the GNU C Library.
59 +
60 +   The GNU C Library is free software; you can redistribute it and/or
61 +   modify it under the terms of the GNU Lesser General Public
62 +   License as published by the Free Software Foundation; either
63 +   version 2.1 of the License, or (at your option) any later version.
64 +
65 +   The GNU C Library is distributed in the hope that it will be useful,
66 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
67 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
68 +   Lesser General Public License for more details.
69 +
70 +   You should have received a copy of the GNU Lesser General Public
71 +   License along with the GNU C Library; if not, write to the Free
72 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
73 +   02111-1307 USA.  */
74 +
75 +#include <sysdep.h>
76 +#include <sys/asm.h>
77 +
78 +ENTRY (__longjmp)
79 +       REG_L ra,  0*SZREG(a0)
80 +       REG_L s0,  1*SZREG(a0)
81 +       REG_L s1,  2*SZREG(a0)
82 +       REG_L s2,  3*SZREG(a0)
83 +       REG_L s3,  4*SZREG(a0)
84 +       REG_L s4,  5*SZREG(a0)
85 +       REG_L s5,  6*SZREG(a0)
86 +       REG_L s6,  7*SZREG(a0)
87 +       REG_L s7,  8*SZREG(a0)
88 +       REG_L s8,  9*SZREG(a0)
89 +       REG_L s9, 10*SZREG(a0)
90 +       REG_L s10,11*SZREG(a0)
91 +       REG_L s11,12*SZREG(a0)
92 +       REG_L sp, 13*SZREG(a0)
93 +       REG_L tp, 14*SZREG(a0)
94 +
95 +#ifdef __riscv_hard_float
96 +       REG_L a3, 15*SZREG(a0)
97 +
98 +       fld  fs0, 16*SZREG+ 0*8(a0)
99 +       fld  fs1, 16*SZREG+ 1*8(a0)
100 +       fld  fs2, 16*SZREG+ 2*8(a0)
101 +       fld  fs3, 16*SZREG+ 3*8(a0)
102 +       fld  fs4, 16*SZREG+ 4*8(a0)
103 +       fld  fs5, 16*SZREG+ 5*8(a0)
104 +       fld  fs6, 16*SZREG+ 6*8(a0)
105 +       fld  fs7, 16*SZREG+ 7*8(a0)
106 +       fld  fs8, 16*SZREG+ 8*8(a0)
107 +       fld  fs9, 16*SZREG+ 9*8(a0)
108 +       fld  fs10,16*SZREG+10*8(a0)
109 +       fld  fs11,16*SZREG+11*8(a0)
110 +       fld  fs12,16*SZREG+12*8(a0)
111 +       fld  fs13,16*SZREG+13*8(a0)
112 +       fld  fs14,16*SZREG+14*8(a0)
113 +       fld  fs15,16*SZREG+15*8(a0)
114 +
115 +       mtfsr a3
116 +#endif
117 +
118 +       sltu a3, a1, 1    # a3 = (a1 == 0)
119 +       add  v0, a3, a1   # v0 = (a1 == 0 ? 1 : a1)
120 +       ret
121 +
122 +END(__longjmp)
123 diff --git a/glibc-2.14.1/sysdeps/riscv/abort-instr.h b/glibc-2.14.1/sysdeps/riscv/abort-instr.h
124 new file mode 100644
125 index 0000000..a901452
126 --- /dev/null
127 +++ glibc-2.14.1/sysdeps/riscv/abort-instr.h
128 @@ -0,0 +1,2 @@
129 +/* An instruction which should crash any program is a breakpoint.  */
130 +#define ABORT_INSTRUCTION asm ("unimp")
131 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/atomic.h b/glibc-2.14.1/sysdeps/riscv/bits/atomic.h
132 new file mode 100644
133 index 0000000..6711b84
134 --- /dev/null
135 +++ glibc-2.14.1/sysdeps/riscv/bits/atomic.h
136 @@ -0,0 +1,119 @@
137 +/* Low-level functions for atomic operations. Mips version.
138 +   Copyright (C) 2005 Free Software Foundation, Inc.
139 +   This file is part of the GNU C Library.
140 +
141 +   The GNU C Library is free software; you can redistribute it and/or
142 +   modify it under the terms of the GNU Lesser General Public
143 +   License as published by the Free Software Foundation; either
144 +   version 2.1 of the License, or (at your option) any later version.
145 +
146 +   The GNU C Library is distributed in the hope that it will be useful,
147 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
148 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
149 +   Lesser General Public License for more details.
150 +
151 +   You should have received a copy of the GNU Lesser General Public
152 +   License along with the GNU C Library; if not, write to the Free
153 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
154 +   02111-1307 USA.  */
155 +
156 +#ifndef _MIPS_BITS_ATOMIC_H
157 +#define _MIPS_BITS_ATOMIC_H 1
158 +
159 +#include <inttypes.h>
160 +#include <sgidefs.h>
161 +
162 +typedef int32_t atomic32_t;
163 +typedef uint32_t uatomic32_t;
164 +typedef int_fast32_t atomic_fast32_t;
165 +typedef uint_fast32_t uatomic_fast32_t;
166 +
167 +typedef int64_t atomic64_t;
168 +typedef uint64_t uatomic64_t;
169 +typedef int_fast64_t atomic_fast64_t;
170 +typedef uint_fast64_t uatomic_fast64_t;
171 +
172 +typedef intptr_t atomicptr_t;
173 +typedef uintptr_t uatomicptr_t;
174 +typedef intmax_t atomic_max_t;
175 +typedef uintmax_t uatomic_max_t;
176 +
177 +/* Atomic compare and exchange. */
178 +
179 +#define atomic_compare_and_exchange_val_acq(mem, newval, oldval)         \
180 +  ({ __sync_synchronize();                      \
181 +     __sync_val_compare_and_swap(mem, oldval, newval); })
182 +
183 +#define atomic_compare_and_exchange_val_rel(mem, newval, oldval)         \
184 +  ({ typeof(*mem) __prev;                       \
185 +     __prev = __sync_val_compare_and_swap(mem, value);  \
186 +     __sync_synchronize();                      \
187 +     __prev; })
188 +
189 +/* Atomic exchange (without compare).  */
190 +
191 +#define atomic_exchange_acq(mem, value)         \
192 +  ({ __sync_synchronize();                      \
193 +     __sync_lock_test_and_set(mem, value); })
194 +
195 +#define atomic_exchange_rel(mem, value)         \
196 +  ({ typeof(*mem) __prev;                       \
197 +     __prev = __sync_lock_test_and_set(mem, value);  \
198 +     __sync_synchronize();                      \
199 +     __prev; })
200 +
201 +
202 +/* Atomically add value and return the previous (unincremented) value.  */
203 +
204 +/* ??? Barrier semantics for atomic_exchange_and_add appear to be 
205 +   undefined.  Use full barrier for now, as that's safe.  */
206 +#define atomic_exchange_and_add(mem, value)             \
207 +  ({ typeof(*mem) __prev;                               \
208 +     __sync_synchronize();                              \
209 +     __prev = __sync_fetch_and_add(mem, value);         \
210 +     __sync_synchronize();                              \
211 +     __prev; })
212 +
213 +#define catomic_exchange_and_add(mem, value)           \
214 +  atomic_exchange_and_add(mem, value)
215 +
216 +#define atomic_bit_test_set(mem, bit)                   \
217 +  ({ typeof(*mem) __prev;                               \
218 +     typeof(*mem) __mask = (typeof(*mem))1 << (bit);    \
219 +     __sync_synchronize();                              \
220 +     __prev = __sync_fetch_and_or(mem, __mask);         \
221 +     __sync_synchronize();                              \
222 +     __prev & __mask; })
223 +
224 +#define asm_maxmin(which, size, res, mem, value) \
225 +  asm ("amo" which "." size "\t%0, %1, 0(%2)" : "=r"(res) : "r"(value), "r"(mem) : "memory")
226 +
227 +#define atomic_max(mem, value)                         \
228 +  ({  typeof(*mem) __prev;                             \
229 +      __sync_synchronize();                                    \
230 +      if (sizeof(*mem) == 4)                           \
231 +       asm_maxmin("maxu", "s", __prev, mem, value);    \
232 +      else if(sizeof(*mem) == 8)                       \
233 +       asm_maxmin("maxu", "d", __prev, mem, value);    \
234 +      else                                             \
235 +       abort();                                        \
236 +     __sync_synchronize();                              \
237 +     __prev; })
238 +
239 +#define catomic_max(mem, value) atomic_max(mem, value)
240 +
241 +#define atomic_min(mem, value)                         \
242 +  ({  typeof(*mem) __prev;                             \
243 +      __sync_synchronize();                                    \
244 +      if (sizeof(*mem) == 4)                           \
245 +       asm_maxmin("minu", "s", __prev, mem, value);    \
246 +      else if(sizeof(*mem) == 8)                       \
247 +       asm_maxmin("minu", "d", __prev, mem, value);    \
248 +      else                                             \
249 +       abort();                                        \
250 +     __sync_synchronize();                              \
251 +     __prev; })
252 +
253 +#define atomic_full_barrier() __sync_synchronize()
254 +
255 +#endif /* bits/atomic.h */
256 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/dlfcn.h b/glibc-2.14.1/sysdeps/riscv/bits/dlfcn.h
257 new file mode 100644
258 index 0000000..a5b5bf5
259 --- /dev/null
260 +++ glibc-2.14.1/sysdeps/riscv/bits/dlfcn.h
261 @@ -0,0 +1,66 @@
262 +/* System dependent definitions for run-time dynamic loading.
263 +   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2004
264 +       Free Software Foundation, Inc.
265 +   This file is part of the GNU C Library.
266 +
267 +   The GNU C Library is free software; you can redistribute it and/or
268 +   modify it under the terms of the GNU Lesser General Public
269 +   License as published by the Free Software Foundation; either
270 +   version 2.1 of the License, or (at your option) any later version.
271 +
272 +   The GNU C Library is distributed in the hope that it will be useful,
273 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
274 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
275 +   Lesser General Public License for more details.
276 +
277 +   You should have received a copy of the GNU Lesser General Public
278 +   License along with the GNU C Library; if not, write to the Free
279 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
280 +   02111-1307 USA.  */
281 +
282 +#ifndef _DLFCN_H
283 +# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
284 +#endif
285 +
286 +/* The MODE argument to `dlopen' contains one of the following: */
287 +#define RTLD_LAZY      0x0001  /* Lazy function call binding.  */
288 +#define RTLD_NOW       0x0002  /* Immediate function call binding.  */
289 +#define RTLD_BINDING_MASK  0x3 /* Mask of binding time value.  */
290 +#define RTLD_NOLOAD    0x00008 /* Do not load the object.  */
291 +#define RTLD_DEEPBIND  0x00010 /* Use deep binding.  */
292 +
293 +/* If the following bit is set in the MODE argument to `dlopen',
294 +   the symbols of the loaded object and its dependencies are made
295 +   visible as if the object were linked directly into the program.  */
296 +#define RTLD_GLOBAL    0x0004
297 +
298 +/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
299 +   The implementation does this by default and so we can define the
300 +   value to zero.  */
301 +#define RTLD_LOCAL      0
302 +
303 +/* Do not delete object when closed.  */
304 +#define RTLD_NODELETE  0x01000
305 +
306 +#ifdef __USE_GNU
307 +/* To support profiling of shared objects it is a good idea to call
308 +   the function found using `dlsym' using the following macro since
309 +   these calls do not use the PLT.  But this would mean the dynamic
310 +   loader has no chance to find out when the function is called.  The
311 +   macro applies the necessary magic so that profiling is possible.
312 +   Rewrite
313 +       foo = (*fctp) (arg1, arg2);
314 +   into
315 +        foo = DL_CALL_FCT (fctp, (arg1, arg2));
316 +*/
317 +# define DL_CALL_FCT(fctp, args) \
318 +  (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
319 +
320 +__BEGIN_DECLS
321 +
322 +/* This function calls the profiling functions.  */
323 +extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
324 +
325 +__END_DECLS
326 +
327 +#endif
328 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/endian.h b/glibc-2.14.1/sysdeps/riscv/bits/endian.h
329 new file mode 100644
330 index 0000000..0119a54
331 --- /dev/null
332 +++ glibc-2.14.1/sysdeps/riscv/bits/endian.h
333 @@ -0,0 +1,13 @@
334 +/* The MIPS architecture has selectable endianness.
335 +   This file is for a machine using big-endian mode.  */
336 +
337 +#ifndef _ENDIAN_H
338 +# error "Never use <bits/endian.h> directly; include <endian.h> instead."
339 +#endif
340 +
341 +#if __RISCVEB
342 +# define __BYTE_ORDER __BIG_ENDIAN
343 +#endif
344 +#if __RISCVEL
345 +# define __BYTE_ORDER __LITTLE_ENDIAN
346 +#endif
347 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/fenv.h b/glibc-2.14.1/sysdeps/riscv/bits/fenv.h
348 new file mode 100644
349 index 0000000..24e0694
350 --- /dev/null
351 +++ glibc-2.14.1/sysdeps/riscv/bits/fenv.h
352 @@ -0,0 +1,77 @@
353 +/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
354 +   This file is part of the GNU C Library.
355 +
356 +   The GNU C Library is free software; you can redistribute it and/or
357 +   modify it under the terms of the GNU Lesser General Public
358 +   License as published by the Free Software Foundation; either
359 +   version 2.1 of the License, or (at your option) any later version.
360 +
361 +   The GNU C Library is distributed in the hope that it will be useful,
362 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
363 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
364 +   Lesser General Public License for more details.
365 +
366 +   You should have received a copy of the GNU Lesser General Public
367 +   License along with the GNU C Library; if not, write to the Free
368 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
369 +   02111-1307 USA.  */
370 +
371 +#ifndef _FENV_H
372 +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
373 +#endif
374 +
375 +
376 +/* Define bits representing the exception.  We use the bit positions
377 +   of the appropriate bits in the FPU control word.  */
378 +enum
379 +  {
380 +    FE_INEXACT = 0x04,
381 +#define FE_INEXACT     FE_INEXACT
382 +    FE_UNDERFLOW = 0x08,
383 +#define FE_UNDERFLOW   FE_UNDERFLOW
384 +    FE_OVERFLOW = 0x10,
385 +#define FE_OVERFLOW    FE_OVERFLOW
386 +    FE_DIVBYZERO = 0x20,
387 +#define FE_DIVBYZERO   FE_DIVBYZERO
388 +    FE_INVALID = 0x40,
389 +#define FE_INVALID     FE_INVALID
390 +  };
391 +
392 +#define FE_ALL_EXCEPT \
393 +       (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
394 +
395 +/* The MIPS FPU supports all of the four defined rounding modes.  We
396 +   use again the bit positions in the FPU control word as the values
397 +   for the appropriate macros.  */
398 +enum
399 +  {
400 +    FE_TONEAREST = 0x0,
401 +#define FE_TONEAREST   FE_TONEAREST
402 +    FE_TOWARDZERO = 0x1,
403 +#define FE_TOWARDZERO  FE_TOWARDZERO
404 +    FE_UPWARD = 0x2,
405 +#define FE_UPWARD      FE_UPWARD
406 +    FE_DOWNWARD = 0x3
407 +#define FE_DOWNWARD    FE_DOWNWARD
408 +  };
409 +
410 +
411 +/* Type representing exception flags.  */
412 +typedef unsigned short int fexcept_t;
413 +
414 +
415 +/* Type representing floating-point environment.  This function corresponds
416 +   to the layout of the block written by the `fstenv'.  */
417 +typedef struct
418 +  {
419 +    unsigned int __fp_control_register;
420 +  }
421 +fenv_t;
422 +
423 +/* If the default argument is used we use this value.  */
424 +#define FE_DFL_ENV     ((__const fenv_t *) -1)
425 +
426 +#ifdef __USE_GNU
427 +/* Floating-point environment where none of the exception is masked.  */
428 +# define FE_NOMASK_ENV  ((__const fenv_t *) -2)
429 +#endif
430 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/ipctypes.h b/glibc-2.14.1/sysdeps/riscv/bits/ipctypes.h
431 new file mode 100644
432 index 0000000..0956e7d
433 --- /dev/null
434 +++ glibc-2.14.1/sysdeps/riscv/bits/ipctypes.h
435 @@ -0,0 +1,32 @@
436 +/* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM.  MIPS version
437 +   Copyright (C) 2002 Free Software Foundation, Inc.
438 +   This file is part of the GNU C Library.
439 +
440 +   The GNU C Library is free software; you can redistribute it and/or
441 +   modify it under the terms of the GNU Lesser General Public
442 +   License as published by the Free Software Foundation; either
443 +   version 2.1 of the License, or (at your option) any later version.
444 +
445 +   The GNU C Library is distributed in the hope that it will be useful,
446 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
447 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
448 +   Lesser General Public License for more details.
449 +
450 +   You should have received a copy of the GNU Lesser General Public
451 +   License along with the GNU C Library; if not, write to the Free
452 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
453 +   02111-1307 USA.  */
454 +
455 +/*
456 + * Never include <bits/ipctypes.h> directly.
457 + */
458 +
459 +#ifndef _BITS_IPCTYPES_H
460 +#define _BITS_IPCTYPES_H       1
461 +
462 +#include <bits/types.h>
463 +
464 +typedef __SLONG32_TYPE __ipc_pid_t;
465 +
466 +
467 +#endif /* bits/ipctypes.h */
468 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/link.h b/glibc-2.14.1/sysdeps/riscv/bits/link.h
469 new file mode 100644
470 index 0000000..f216ebd
471 --- /dev/null
472 +++ glibc-2.14.1/sysdeps/riscv/bits/link.h
473 @@ -0,0 +1,76 @@
474 +/* Copyright (C) 2005, 2009 Free Software Foundation, Inc.
475 +   This file is part of the GNU C Library.
476 +
477 +   The GNU C Library is free software; you can redistribute it and/or
478 +   modify it under the terms of the GNU Lesser General Public
479 +   License as published by the Free Software Foundation; either
480 +   version 2.1 of the License, or (at your option) any later version.
481 +
482 +   The GNU C Library is distributed in the hope that it will be useful,
483 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
484 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
485 +   Lesser General Public License for more details.
486 +
487 +   You should have received a copy of the GNU Lesser General Public
488 +   License along with the GNU C Library; if not, write to the Free
489 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
490 +   02111-1307 USA.  */
491 +
492 +#ifndef        _LINK_H
493 +# error "Never include <bits/link.h> directly; use <link.h> instead."
494 +#endif
495 +
496 +typedef struct La_mips_64_regs
497 +{
498 +  unsigned long lr_reg[8]; /* $a0 through $a7 */
499 +  double lr_fpreg[8]; /* $f4 throgh $f11 */
500 +  unsigned long lr_ra;
501 +  unsigned long lr_sp;
502 +} La_mips_64_regs;
503 +
504 +/* Return values for calls from PLT on MIPS.  */
505 +typedef struct La_mips_64_retval
506 +{
507 +  unsigned long lrv_v0;
508 +  unsigned long lrv_v1;
509 +  double lrv_fv0;
510 +  double lrv_fv1;
511 +} La_mips_64_retval;
512 +
513 +__BEGIN_DECLS
514 +
515 +#if _RISCV_SIM == _ABI32
516 +
517 +extern Elf32_Addr la_mips_n32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
518 +                                           uintptr_t *__refcook,
519 +                                           uintptr_t *__defcook,
520 +                                           La_mips_64_regs *__regs,
521 +                                           unsigned int *__flags,
522 +                                           const char *__symname,
523 +                                           long int *__framesizep);
524 +extern unsigned int la_mips_n32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
525 +                                            uintptr_t *__refcook,
526 +                                            uintptr_t *__defcook,
527 +                                            const La_mips_64_regs *__inregs,
528 +                                            La_mips_64_retval *__outregs,
529 +                                            const char *__symname);
530 +
531 +#else
532 +
533 +extern Elf64_Addr la_mips_n64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx,
534 +                                           uintptr_t *__refcook,
535 +                                           uintptr_t *__defcook,
536 +                                           La_mips_64_regs *__regs,
537 +                                           unsigned int *__flags,
538 +                                           const char *__symname,
539 +                                           long int *__framesizep);
540 +extern unsigned int la_mips_n64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx,
541 +                                            uintptr_t *__refcook,
542 +                                            uintptr_t *__defcook,
543 +                                            const La_mips_64_regs *__inregs,
544 +                                            La_mips_64_retval *__outregs,
545 +                                            const char *__symname);
546 +
547 +#endif
548 +
549 +__END_DECLS
550 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/linkmap.h b/glibc-2.14.1/sysdeps/riscv/bits/linkmap.h
551 new file mode 100644
552 index 0000000..a6df782
553 --- /dev/null
554 +++ glibc-2.14.1/sysdeps/riscv/bits/linkmap.h
555 @@ -0,0 +1,4 @@
556 +struct link_map_machine
557 +  {
558 +    ElfW(Addr) plt; /* Address of .plt */
559 +  };
560 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/mathdef.h b/glibc-2.14.1/sysdeps/riscv/bits/mathdef.h
561 new file mode 100644
562 index 0000000..d718016
563 --- /dev/null
564 +++ glibc-2.14.1/sysdeps/riscv/bits/mathdef.h
565 @@ -0,0 +1,45 @@
566 +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2007
567 +       Free Software Foundation, Inc.
568 +   This file is part of the GNU C Library.
569 +
570 +   The GNU C Library is free software; you can redistribute it and/or
571 +   modify it under the terms of the GNU Lesser General Public
572 +   License as published by the Free Software Foundation; either
573 +   version 2.1 of the License, or (at your option) any later version.
574 +
575 +   The GNU C Library is distributed in the hope that it will be useful,
576 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
577 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
578 +   Lesser General Public License for more details.
579 +
580 +   You should have received a copy of the GNU Lesser General Public
581 +   License along with the GNU C Library; if not, write to the Free
582 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
583 +   02111-1307 USA.  */
584 +
585 +#if !defined _MATH_H && !defined _COMPLEX_H
586 +# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
587 +#endif
588 +
589 +#include <sgidefs.h>
590 +
591 +#if defined  __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
592 +# define _MATH_H_MATHDEF       1
593 +
594 +/* MIPS has `float' and `double' operations.  */
595 +typedef float float_t;         /* `float' expressions are evaluated as
596 +                                  `float'.  */
597 +typedef double double_t;       /* `double' expressions are evaluated as
598 +                                  `double'.  */
599 +
600 +/* The values returned by `ilogb' for 0 and NaN respectively.  */
601 +# define FP_ILOGB0     (-2147483647)
602 +# define FP_ILOGBNAN   2147483647
603 +
604 +#endif /* ISO C99 */
605 +
606 +#if ! defined __NO_LONG_DOUBLE_MATH && _RISCV_SIM == _ABI32
607 +/* Signal that we do not really have a `long double'.  This disables the
608 +   declaration of all the `long double' function variants.  */
609 +# define __NO_LONG_DOUBLE_MATH 1
610 +#endif
611 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/nan.h b/glibc-2.14.1/sysdeps/riscv/bits/nan.h
612 new file mode 100644
613 index 0000000..baaaa55
614 --- /dev/null
615 +++ glibc-2.14.1/sysdeps/riscv/bits/nan.h
616 @@ -0,0 +1,56 @@
617 +/* `NAN' constant for IEEE 754 machines.
618 +   Copyright (C) 1992, 1996, 1997, 1999, 2002, 2004
619 +   Free Software Foundation, Inc.
620 +   This file is part of the GNU C Library.
621 +
622 +   The GNU C Library is free software; you can redistribute it and/or
623 +   modify it under the terms of the GNU Lesser General Public
624 +   License as published by the Free Software Foundation; either
625 +   version 2.1 of the License, or (at your option) any later version.
626 +
627 +   The GNU C Library is distributed in the hope that it will be useful,
628 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
629 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
630 +   Lesser General Public License for more details.
631 +
632 +   You should have received a copy of the GNU Lesser General Public
633 +   License along with the GNU C Library; if not, write to the Free
634 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
635 +   02111-1307 USA.  */
636 +
637 +#ifndef _MATH_H
638 +# error "Never use <bits/nan.h> directly; include <math.h> instead."
639 +#endif
640 +
641 +
642 +/* IEEE Not A Number (QNaN). Note that MIPS has the QNaN and SNaN patterns
643 +   reversed compared to most other architectures. The IEEE spec left
644 +   the definition of this open to implementations, and for MIPS the top
645 +   bit of the mantissa must be SET to indicate a SNaN.  */
646 +
647 +#if __GNUC_PREREQ(3,3)
648 +
649 +# define NAN   (__builtin_nanf(""))
650 +
651 +#elif defined __GNUC__
652 +
653 +# define NAN \
654 +  (__extension__                                                            \
655 +   ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; })  \
656 +    { __l: 0x7fbfffffUL }).__d)
657 +
658 +#else
659 +
660 +# include <endian.h>
661 +
662 +# if __BYTE_ORDER == __BIG_ENDIAN
663 +#  define __nan_bytes          { 0x7f, 0xbf, 0xff, 0xff }
664 +# endif
665 +# if __BYTE_ORDER == __LITTLE_ENDIAN
666 +#  define __nan_bytes          { 0xff, 0xff, 0xbf, 0x7f }
667 +# endif
668 +
669 +static union { unsigned char __c[4]; float __d; } __nan_union = { __nan_bytes };
670 +# define NAN   (__nan_union.__d)
671 +
672 +#endif /* GCC.  */
673 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/setjmp.h b/glibc-2.14.1/sysdeps/riscv/bits/setjmp.h
674 new file mode 100644
675 index 0000000..52e2d3d
676 --- /dev/null
677 +++ glibc-2.14.1/sysdeps/riscv/bits/setjmp.h
678 @@ -0,0 +1,43 @@
679 +/* Define the machine-dependent type `jmp_buf'.  RISC-V version.
680 +   Copyright (C) 1992,1993,1995,1997,2000,2002,2003,2004,2005,2006
681 +       Free Software Foundation, Inc.
682 +   This file is part of the GNU C Library.
683 +
684 +   The GNU C Library is free software; you can redistribute it and/or
685 +   modify it under the terms of the GNU Lesser General Public
686 +   License as published by the Free Software Foundation; either
687 +   version 2.1 of the License, or (at your option) any later version.
688 +
689 +   The GNU C Library is distributed in the hope that it will be useful,
690 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
691 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
692 +   Lesser General Public License for more details.
693 +
694 +   You should have received a copy of the GNU Lesser General Public
695 +   License along with the GNU C Library; if not, write to the Free
696 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
697 +   02111-1307 USA.  */
698 +
699 +#ifndef _RISCV_BITS_SETJMP_H
700 +#define _RISCV_BITS_SETJMP_H
701 +
702 +typedef struct __jmp_buf_internal_tag
703 +  {
704 +    /* Program counter.  */
705 +    long __pc;
706 +    /* Callee-saved registers. */
707 +    long __regs[12];
708 +    /* Stack pointer.  */
709 +    long __sp;
710 +    /* Thread pointer. */
711 +    long __tp;
712 +    /* Floating point status register.  */
713 +    long __fsr;
714 +
715 +    /* Callee-saved floating point registers.
716 +       Note that there are an even number of preceding words in this struct,
717 +       so no padding will be inserted before __fpregs, even for RV32. */
718 +    double __fpregs[16];
719 +  } __jmp_buf[1];
720 +
721 +#endif /* _RISCV_BITS_SETJMP_H */
722 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/string.h b/glibc-2.14.1/sysdeps/riscv/bits/string.h
723 new file mode 100644
724 index 0000000..b7b4c0a
725 --- /dev/null
726 +++ glibc-2.14.1/sysdeps/riscv/bits/string.h
727 @@ -0,0 +1,47 @@
728 +/* This file should provide inline versions of string functions.
729 +
730 +   Surround GCC-specific parts with #ifdef __GNUC__, and use `__extern_inline'.
731 +
732 +   This file should define __STRING_INLINES if functions are actually defined
733 +   as inlines.  */
734 +
735 +#ifndef _BITS_STRING_H
736 +#define _BITS_STRING_H 1
737 +
738 +#if defined(__GNUC__) && !defined(__cplusplus)
739 +
740 +#define _HAVE_STRING_ARCH_memcpy 1
741 +#define __use_memcpy_align(k, d, s, n) \
742 +  (__builtin_constant_p(n) && (n) % (k) == 0 && (n) <= 64 && \
743 +   __alignof__(d) >= (k) && __alignof__(s) >= (k))
744 +#define memcpy(d, s, n) \
745 +  (__use_memcpy_align(8, d, s, n) ? __memcpy_align8(d, s, n) : \
746 +   __use_memcpy_align(4, d, s, n) ? __memcpy_align4(d, s, n) : \
747 +   __memcpy_g(d, s, n))
748 +
749 +#define __declare_memcpy_align(size, type) \
750 +  static inline void *__memcpy_align ## size(void *__restrict __dest, \
751 +                        __const void *__restrict __src, size_t __n) { \
752 +    type *__d = (type*)__dest; \
753 +    const type *__s = (const type*)__src, *__e = (const type*)(__src + __n); \
754 +    while (__s < __e) { \
755 +      type __t = *__s; \
756 +      __d++, __s++; \
757 +      *(__d-1) = __t; \
758 +    } \
759 +    return __dest; \
760 +  }
761 +__declare_memcpy_align(8, long long)
762 +__declare_memcpy_align(4, int)
763 +
764 +#ifdef _LIBC
765 +extern void *__memcpy_g (void *__restrict __dest,
766 +                         __const void *__restrict __src, size_t __n);
767 +libc_hidden_proto (__memcpy_g)
768 +#else
769 +# define __memcpy_g memcpy
770 +#endif
771 +
772 +#endif /* __GNUC__ && !__cplusplus */
773 +
774 +#endif /* bits/string.h */
775 diff --git a/glibc-2.14.1/sysdeps/riscv/bits/wordsize.h b/glibc-2.14.1/sysdeps/riscv/bits/wordsize.h
776 new file mode 100644
777 index 0000000..f956c87
778 --- /dev/null
779 +++ glibc-2.14.1/sysdeps/riscv/bits/wordsize.h
780 @@ -0,0 +1,22 @@
781 +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
782 +   This file is part of the GNU C Library.
783 +
784 +   The GNU C Library is free software; you can redistribute it and/or
785 +   modify it under the terms of the GNU Lesser General Public
786 +   License as published by the Free Software Foundation; either
787 +   version 2.1 of the License, or (at your option) any later version.
788 +
789 +   The GNU C Library is distributed in the hope that it will be useful,
790 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
791 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
792 +   Lesser General Public License for more details.
793 +
794 +   You should have received a copy of the GNU Lesser General Public
795 +   License along with the GNU C Library; if not, write to the Free
796 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
797 +   02111-1307 USA.  */
798 +
799 +#define __WORDSIZE     _RISCV_SZPTR
800 +#if _RISCV_SIM == _ABI64
801 +# define __WORDSIZE_COMPAT32   1
802 +#endif
803 diff --git a/glibc-2.14.1/sysdeps/riscv/bsd-_setjmp.c b/glibc-2.14.1/sysdeps/riscv/bsd-_setjmp.c
804 new file mode 100644
805 index 0000000..0d41310
806 --- /dev/null
807 +++ glibc-2.14.1/sysdeps/riscv/bsd-_setjmp.c
808 @@ -0,0 +1 @@
809 +/* _setjmp is implemented in setjmp.S */
810 diff --git a/glibc-2.14.1/sysdeps/riscv/bsd-setjmp.c b/glibc-2.14.1/sysdeps/riscv/bsd-setjmp.c
811 new file mode 100644
812 index 0000000..ee7c5e3
813 --- /dev/null
814 +++ glibc-2.14.1/sysdeps/riscv/bsd-setjmp.c
815 @@ -0,0 +1 @@
816 +/* setjmp is implemented in setjmp.S */
817 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-dtprocnum.h b/glibc-2.14.1/sysdeps/riscv/dl-dtprocnum.h
818 new file mode 100644
819 index 0000000..dfd03ba
820 --- /dev/null
821 +++ glibc-2.14.1/sysdeps/riscv/dl-dtprocnum.h
822 @@ -0,0 +1,22 @@
823 +/* Configuration of lookup functions.  MIPS version.
824 +   Copyright (C) 2000 Free Software Foundation, Inc.
825 +   This file is part of the GNU C Library.
826 +
827 +   The GNU C Library is free software; you can redistribute it and/or
828 +   modify it under the terms of the GNU Lesser General Public
829 +   License as published by the Free Software Foundation; either
830 +   version 2.1 of the License, or (at your option) any later version.
831 +
832 +   The GNU C Library is distributed in the hope that it will be useful,
833 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
834 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
835 +   Lesser General Public License for more details.
836 +
837 +   You should have received a copy of the GNU Lesser General Public
838 +   License along with the GNU C Library; if not, write to the Free
839 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
840 +   02111-1307 USA.  */
841 +
842 +/* Number of extra dynamic section entries for this architecture.  By
843 +   default there are none.  */
844 +#define DT_THISPROCNUM DT_MIPS_NUM
845 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-lookup.c b/glibc-2.14.1/sysdeps/riscv/dl-lookup.c
846 new file mode 100644
847 index 0000000..4090efe
848 --- /dev/null
849 +++ glibc-2.14.1/sysdeps/riscv/dl-lookup.c
850 @@ -0,0 +1,1033 @@
851 +/* Look up a symbol in the loaded objects.
852 +   MIPS/Linux version - special handling of non-PIC undefined symbol rules.
853 +   Copyright (C) 1995-2005, 2006, 2007, 2009, 2010
854 +   Free Software Foundation, Inc.
855 +   This file is part of the GNU C Library.
856 +
857 +   The GNU C Library is free software; you can redistribute it and/or
858 +   modify it under the terms of the GNU Lesser General Public
859 +   License as published by the Free Software Foundation; either
860 +   version 2.1 of the License, or (at your option) any later version.
861 +
862 +   The GNU C Library is distributed in the hope that it will be useful,
863 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
864 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
865 +   Lesser General Public License for more details.
866 +
867 +   You should have received a copy of the GNU Lesser General Public
868 +   License along with the GNU C Library; if not, write to the Free
869 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
870 +   02111-1307 USA.  */
871 +
872 +#include <alloca.h>
873 +#include <libintl.h>
874 +#include <stdlib.h>
875 +#include <string.h>
876 +#include <unistd.h>
877 +#include <ldsodefs.h>
878 +#include <dl-hash.h>
879 +#include <dl-machine.h>
880 +#include <sysdep-cancel.h>
881 +#include <bits/libc-lock.h>
882 +#include <tls.h>
883 +
884 +#include <assert.h>
885 +
886 +#define VERSTAG(tag)   (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
887 +
888 +/* We need this string more than once.  */
889 +static const char undefined_msg[] = "undefined symbol: ";
890 +
891 +
892 +struct sym_val
893 +  {
894 +    const ElfW(Sym) *s;
895 +    struct link_map *m;
896 +  };
897 +
898 +
899 +#define make_string(string, rest...) \
900 +  ({                                                                         \
901 +    const char *all[] = { string, ## rest };                                 \
902 +    size_t len, cnt;                                                         \
903 +    char *result, *cp;                                                       \
904 +                                                                             \
905 +    len = 1;                                                                 \
906 +    for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)               \
907 +      len += strlen (all[cnt]);                                                      \
908 +                                                                             \
909 +    cp = result = alloca (len);                                                      \
910 +    for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)               \
911 +      cp = __stpcpy (cp, all[cnt]);                                          \
912 +                                                                             \
913 +    result;                                                                  \
914 +  })
915 +
916 +/* Statistics function.  */
917 +#ifdef SHARED
918 +# define bump_num_relocations() ++GL(dl_num_relocations)
919 +#else
920 +# define bump_num_relocations() ((void) 0)
921 +#endif
922 +
923 +
924 +/* Inner part of the lookup functions.  We return a value > 0 if we
925 +   found the symbol, the value 0 if nothing is found and < 0 if
926 +   something bad happened.  */
927 +static int
928 +__attribute_noinline__
929 +do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
930 +            unsigned long int *old_hash, const ElfW(Sym) *ref,
931 +            struct sym_val *result, struct r_scope_elem *scope, size_t i,
932 +            const struct r_found_version *const version, int flags,
933 +            struct link_map *skip, int type_class, struct link_map *undef_map)
934 +{
935 +  size_t n = scope->r_nlist;
936 +  /* Make sure we read the value before proceeding.  Otherwise we
937 +     might use r_list pointing to the initial scope and r_nlist being
938 +     the value after a resize.  That is the only path in dl-open.c not
939 +     protected by GSCOPE.  A read barrier here might be to expensive.  */
940 +  __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
941 +  struct link_map **list = scope->r_list;
942 +
943 +  do
944 +    {
945 +      /* These variables are used in the nested function.  */
946 +      Elf_Symndx symidx;
947 +      int num_versions = 0;
948 +      const ElfW(Sym) *versioned_sym = NULL;
949 +
950 +      const struct link_map *map = list[i]->l_real;
951 +
952 +      /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */
953 +      if (map == skip)
954 +       continue;
955 +
956 +      /* Don't search the executable when resolving a copy reloc.  */
957 +      if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
958 +       continue;
959 +
960 +      /* Do not look into objects which are going to be removed.  */
961 +      if (map->l_removed)
962 +       continue;
963 +
964 +      /* Print some debugging info if wanted.  */
965 +      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))
966 +       _dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
967 +                         undef_name,
968 +                         map->l_name[0] ? map->l_name : rtld_progname,
969 +                         map->l_ns);
970 +
971 +      /* If the hash table is empty there is nothing to do here.  */
972 +      if (map->l_nbuckets == 0)
973 +       continue;
974 +
975 +      /* The tables for this map.  */
976 +      const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
977 +      const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
978 +
979 +
980 +      /* Nested routine to check whether the symbol matches.  */
981 +      const ElfW(Sym) *
982 +      __attribute_noinline__
983 +      check_match (const ElfW(Sym) *sym)
984 +      {
985 +       unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
986 +       assert (ELF_RTYPE_CLASS_PLT == 1);
987 +       /* The semantics of zero/non-zero values of undefined symbols
988 +          differs depending on whether the non-PIC ABI is in use.
989 +          Under the non-PIC ABI, a non-zero value indicates that
990 +          there is an address reference to the symbol and thus it
991 +          must always be resolved (except when resolving a jump slot
992 +          relocation) to the PLT entry whose address is provided as
993 +          the symbol's value; a zero value indicates that this
994 +          canonical-address behaviour is not required.  Yet under the
995 +          classic MIPS psABI, a zero value indicates that there is an
996 +          address reference to the function and the dynamic linker
997 +          must resolve the symbol immediately upon loading.  To avoid
998 +          conflict, symbols for which the dynamic linker must assume
999 +          the non-PIC ABI semantics are marked with the STO_MIPS_PLT
1000 +          flag.  */
1001 +       if (__builtin_expect ((sym->st_value == 0 /* No value.  */
1002 +                              && stt != STT_TLS)
1003 +                             || (sym->st_shndx == SHN_UNDEF
1004 +                                 && !(sym->st_other & STO_MIPS_PLT))
1005 +                             || (type_class & (sym->st_shndx == SHN_UNDEF)),
1006 +                             0))
1007 +         return NULL;
1008 +
1009 +       /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
1010 +          STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
1011 +          code/data definitions.  */
1012 +#define ALLOWED_STT \
1013 +       ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
1014 +        | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
1015 +       if (__builtin_expect (((1 << stt) & ALLOWED_STT) == 0, 0))
1016 +         return NULL;
1017 +
1018 +       if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
1019 +         /* Not the symbol we are looking for.  */
1020 +         return NULL;
1021 +
1022 +       const ElfW(Half) *verstab = map->l_versyms;
1023 +       if (version != NULL)
1024 +         {
1025 +           if (__builtin_expect (verstab == NULL, 0))
1026 +             {
1027 +               /* We need a versioned symbol but haven't found any.  If
1028 +                  this is the object which is referenced in the verneed
1029 +                  entry it is a bug in the library since a symbol must
1030 +                  not simply disappear.
1031 +
1032 +                  It would also be a bug in the object since it means that
1033 +                  the list of required versions is incomplete and so the
1034 +                  tests in dl-version.c haven't found a problem.*/
1035 +               assert (version->filename == NULL
1036 +                       || ! _dl_name_match_p (version->filename, map));
1037 +
1038 +               /* Otherwise we accept the symbol.  */
1039 +             }
1040 +           else
1041 +             {
1042 +               /* We can match the version information or use the
1043 +                  default one if it is not hidden.  */
1044 +               ElfW(Half) ndx = verstab[symidx] & 0x7fff;
1045 +               if ((map->l_versions[ndx].hash != version->hash
1046 +                    || strcmp (map->l_versions[ndx].name, version->name))
1047 +                   && (version->hidden || map->l_versions[ndx].hash
1048 +                       || (verstab[symidx] & 0x8000)))
1049 +                 /* It's not the version we want.  */
1050 +                 return NULL;
1051 +             }
1052 +         }
1053 +       else
1054 +         {
1055 +           /* No specific version is selected.  There are two ways we
1056 +              can got here:
1057 +
1058 +              - a binary which does not include versioning information
1059 +              is loaded
1060 +
1061 +              - dlsym() instead of dlvsym() is used to get a symbol which
1062 +              might exist in more than one form
1063 +
1064 +              If the library does not provide symbol version information
1065 +              there is no problem at at: we simply use the symbol if it
1066 +              is defined.
1067 +
1068 +              These two lookups need to be handled differently if the
1069 +              library defines versions.  In the case of the old
1070 +              unversioned application the oldest (default) version
1071 +              should be used.  In case of a dlsym() call the latest and
1072 +              public interface should be returned.  */
1073 +           if (verstab != NULL)
1074 +             {
1075 +               if ((verstab[symidx] & 0x7fff)
1076 +                   >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
1077 +                 {
1078 +                   /* Don't accept hidden symbols.  */
1079 +                   if ((verstab[symidx] & 0x8000) == 0
1080 +                       && num_versions++ == 0)
1081 +                     /* No version so far.  */
1082 +                     versioned_sym = sym;
1083 +
1084 +                   return NULL;
1085 +                 }
1086 +             }
1087 +         }
1088 +
1089 +       /* There cannot be another entry for this symbol so stop here.  */
1090 +       return sym;
1091 +      }
1092 +
1093 +      const ElfW(Sym) *sym;
1094 +      const ElfW(Addr) *bitmask = map->l_gnu_bitmask;
1095 +      if (__builtin_expect (bitmask != NULL, 1))
1096 +       {
1097 +         ElfW(Addr) bitmask_word
1098 +           = bitmask[(new_hash / __ELF_NATIVE_CLASS)
1099 +                     & map->l_gnu_bitmask_idxbits];
1100 +
1101 +         unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);
1102 +         unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)
1103 +                                  & (__ELF_NATIVE_CLASS - 1));
1104 +
1105 +         if (__builtin_expect ((bitmask_word >> hashbit1)
1106 +                               & (bitmask_word >> hashbit2) & 1, 0))
1107 +           {
1108 +             Elf32_Word bucket = map->l_gnu_buckets[new_hash
1109 +                                                    % map->l_nbuckets];
1110 +             if (bucket != 0)
1111 +               {
1112 +                 const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
1113 +
1114 +                 do
1115 +                   if (((*hasharr ^ new_hash) >> 1) == 0)
1116 +                     {
1117 +                       symidx = hasharr - map->l_gnu_chain_zero;
1118 +                       sym = check_match (&symtab[symidx]);
1119 +                       if (sym != NULL)
1120 +                         goto found_it;
1121 +                     }
1122 +                 while ((*hasharr++ & 1u) == 0);
1123 +               }
1124 +           }
1125 +         /* No symbol found.  */
1126 +         symidx = SHN_UNDEF;
1127 +       }
1128 +      else
1129 +       {
1130 +         if (*old_hash == 0xffffffff)
1131 +           *old_hash = _dl_elf_hash (undef_name);
1132 +
1133 +         /* Use the old SysV-style hash table.  Search the appropriate
1134 +            hash bucket in this object's symbol table for a definition
1135 +            for the same symbol name.  */
1136 +         for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];
1137 +              symidx != STN_UNDEF;
1138 +              symidx = map->l_chain[symidx])
1139 +           {
1140 +             sym = check_match (&symtab[symidx]);
1141 +             if (sym != NULL)
1142 +               goto found_it;
1143 +           }
1144 +       }
1145 +
1146 +      /* If we have seen exactly one versioned symbol while we are
1147 +        looking for an unversioned symbol and the version is not the
1148 +        default version we still accept this symbol since there are
1149 +        no possible ambiguities.  */
1150 +      sym = num_versions == 1 ? versioned_sym : NULL;
1151 +
1152 +      if (sym != NULL)
1153 +       {
1154 +       found_it:
1155 +         switch (__builtin_expect (ELFW(ST_BIND) (sym->st_info), STB_GLOBAL))
1156 +           {
1157 +           case STB_WEAK:
1158 +             /* Weak definition.  Use this value if we don't find another.  */
1159 +             if (__builtin_expect (GLRO(dl_dynamic_weak), 0))
1160 +               {
1161 +                 if (! result->s)
1162 +                   {
1163 +                     result->s = sym;
1164 +                     result->m = (struct link_map *) map;
1165 +                   }
1166 +                 break;
1167 +               }
1168 +             /* FALLTHROUGH */
1169 +           case STB_GLOBAL:
1170 +           success:
1171 +             /* Global definition.  Just what we need.  */
1172 +             result->s = sym;
1173 +             result->m = (struct link_map *) map;
1174 +             return 1;
1175 +
1176 +           case STB_GNU_UNIQUE:;
1177 +             /* We have to determine whether we already found a
1178 +                symbol with this name before.  If not then we have to
1179 +                add it to the search table.  If we already found a
1180 +                definition we have to use it.  */
1181 +             void enter (struct unique_sym *table, size_t size,
1182 +                         unsigned int hash, const char *name,
1183 +                         const ElfW(Sym) *sym, struct link_map *map)
1184 +             {
1185 +               size_t idx = hash % size;
1186 +               size_t hash2 = 1 + hash % (size - 2);
1187 +               while (1)
1188 +                 {
1189 +                   if (table[idx].name == NULL)
1190 +                     {
1191 +                       table[idx].hashval = hash;
1192 +                       table[idx].name = name;
1193 +                       if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
1194 +                         {
1195 +                           table[idx].sym = ref;
1196 +                           table[idx].map = undef_map;
1197 +                         }
1198 +                       else
1199 +                         {
1200 +                           table[idx].sym = sym;
1201 +                           table[idx].map = map;
1202 +
1203 +                           if (map->l_type == lt_loaded)
1204 +                             /* Make sure we don't unload this object by
1205 +                                setting the appropriate flag.  */
1206 +                             map->l_flags_1 |= DF_1_NODELETE;
1207 +                         }
1208 +
1209 +                       return;
1210 +                     }
1211 +
1212 +                   idx += hash2;
1213 +                   if (idx >= size)
1214 +                     idx -= size;
1215 +                 }
1216 +             }
1217 +
1218 +             struct unique_sym_table *tab
1219 +               = &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;
1220 +
1221 +             __rtld_lock_lock_recursive (tab->lock);
1222 +
1223 +             struct unique_sym *entries = tab->entries;
1224 +             size_t size = tab->size;
1225 +             if (entries != NULL)
1226 +               {
1227 +                 size_t idx = new_hash % size;
1228 +                 size_t hash2 = 1 + new_hash % (size - 2);
1229 +                 while (1)
1230 +                   {
1231 +                     if (entries[idx].hashval == new_hash
1232 +                         && strcmp (entries[idx].name, undef_name) == 0)
1233 +                       {
1234 +                         result->s = entries[idx].sym;
1235 +                         result->m = (struct link_map *) entries[idx].map;
1236 +                         __rtld_lock_unlock_recursive (tab->lock);
1237 +                         return 1;
1238 +                       }
1239 +
1240 +                     if (entries[idx].name == NULL)
1241 +                       break;
1242 +
1243 +                     idx += hash2;
1244 +                     if (idx >= size)
1245 +                       idx -= size;
1246 +                   }
1247 +
1248 +                 if (size * 3 <= tab->n_elements * 4)
1249 +                   {
1250 +                     /* Expand the table.  */
1251 +#ifdef RTLD_CHECK_FOREIGN_CALL
1252 +                     /* This must not happen during runtime relocations.  */
1253 +                     assert (!RTLD_CHECK_FOREIGN_CALL);
1254 +#endif
1255 +                     size_t newsize = _dl_higher_prime_number (size + 1);
1256 +                     struct unique_sym *newentries
1257 +                       = calloc (sizeof (struct unique_sym), newsize);
1258 +                     if (newentries == NULL)
1259 +                       {
1260 +                       nomem:
1261 +                         __rtld_lock_unlock_recursive (tab->lock);
1262 +                         _dl_fatal_printf ("out of memory\n");
1263 +                       }
1264 +
1265 +                     for (idx = 0; idx < size; ++idx)
1266 +                       if (entries[idx].name != NULL)
1267 +                         enter (newentries, newsize, entries[idx].hashval,
1268 +                                entries[idx].name, entries[idx].sym,
1269 +                                entries[idx].map);
1270 +
1271 +                     tab->free (entries);
1272 +                     tab->size = newsize;
1273 +                     size = newsize;
1274 +                     entries = tab->entries = newentries;
1275 +                     tab->free = free;
1276 +                   }
1277 +               }
1278 +             else
1279 +               {
1280 +#ifdef RTLD_CHECK_FOREIGN_CALL
1281 +                 /* This must not happen during runtime relocations.  */
1282 +                 assert (!RTLD_CHECK_FOREIGN_CALL);
1283 +#endif
1284 +
1285 +#ifdef SHARED
1286 +                 /* If tab->entries is NULL, but tab->size is not, it means
1287 +                    this is the second, conflict finding, lookup for
1288 +                    LD_TRACE_PRELINKING in _dl_debug_bindings.  Don't
1289 +                    allocate anything and don't enter anything into the
1290 +                    hash table.  */
1291 +                 if (__builtin_expect (tab->size, 0))
1292 +                   {
1293 +                     assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
1294 +                     __rtld_lock_unlock_recursive (tab->lock);
1295 +                     goto success;
1296 +                   }
1297 +#endif
1298 +
1299 +#define INITIAL_NUNIQUE_SYM_TABLE 31
1300 +                 size = INITIAL_NUNIQUE_SYM_TABLE;
1301 +                 entries = calloc (sizeof (struct unique_sym), size);
1302 +                 if (entries == NULL)
1303 +                   goto nomem;
1304 +
1305 +                 tab->entries = entries;
1306 +                 tab->size = size;
1307 +                 tab->free = free;
1308 +               }
1309 +
1310 +             enter (entries, size, new_hash, strtab + sym->st_name, sym,
1311 +                    (struct link_map *) map);
1312 +             ++tab->n_elements;
1313 +
1314 +             __rtld_lock_unlock_recursive (tab->lock);
1315 +
1316 +             goto success;
1317 +
1318 +           default:
1319 +             /* Local symbols are ignored.  */
1320 +             break;
1321 +           }
1322 +       }
1323 +
1324 +      /* If this current map is the one mentioned in the verneed entry
1325 +        and we have not found a weak entry, it is a bug.  */
1326 +      if (symidx == STN_UNDEF && version != NULL && version->filename != NULL
1327 +         && __builtin_expect (_dl_name_match_p (version->filename, map), 0))
1328 +       return -1;
1329 +    }
1330 +  while (++i < n);
1331 +
1332 +  /* We have not found anything until now.  */
1333 +  return 0;
1334 +}
1335 +
1336 +
1337 +static uint_fast32_t
1338 +dl_new_hash (const char *s)
1339 +{
1340 +  uint_fast32_t h = 5381;
1341 +  for (unsigned char c = *s; c != '\0'; c = *++s)
1342 +    h = h * 33 + c;
1343 +  return h & 0xffffffff;
1344 +}
1345 +
1346 +
1347 +/* Add extra dependency on MAP to UNDEF_MAP.  */
1348 +static int
1349 +internal_function
1350 +add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
1351 +{
1352 +  struct link_map *runp;
1353 +  unsigned int i;
1354 +  int result = 0;
1355 +
1356 +  /* Avoid self-references and references to objects which cannot be
1357 +     unloaded anyway.  */
1358 +  if (undef_map == map)
1359 +    return 0;
1360 +
1361 +  /* Avoid references to objects which cannot be unloaded anyway.  */
1362 +  assert (map->l_type == lt_loaded);
1363 +  if ((map->l_flags_1 & DF_1_NODELETE) != 0)
1364 +    return 0;
1365 +
1366 +  struct link_map_reldeps *l_reldeps
1367 +    = atomic_forced_read (undef_map->l_reldeps);
1368 +
1369 +  /* Make sure l_reldeps is read before l_initfini.  */
1370 +  atomic_read_barrier ();
1371 +
1372 +  /* Determine whether UNDEF_MAP already has a reference to MAP.  First
1373 +     look in the normal dependencies.  */
1374 +  struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
1375 +  if (l_initfini != NULL)
1376 +    {
1377 +      for (i = 0; l_initfini[i] != NULL; ++i)
1378 +       if (l_initfini[i] == map)
1379 +         return 0;
1380 +    }
1381 +
1382 +  /* No normal dependency.  See whether we already had to add it
1383 +     to the special list of dynamic dependencies.  */
1384 +  unsigned int l_reldepsact = 0;
1385 +  if (l_reldeps != NULL)
1386 +    {
1387 +      struct link_map **list = &l_reldeps->list[0];
1388 +      l_reldepsact = l_reldeps->act;
1389 +      for (i = 0; i < l_reldepsact; ++i)
1390 +       if (list[i] == map)
1391 +         return 0;
1392 +    }
1393 +
1394 +  /* Save serial number of the target MAP.  */
1395 +  unsigned long long serial = map->l_serial;
1396 +
1397 +  /* Make sure nobody can unload the object while we are at it.  */
1398 +  if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
1399 +    {
1400 +      /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
1401 +        here, that can result in ABBA deadlock.  */
1402 +      THREAD_GSCOPE_RESET_FLAG ();
1403 +      __rtld_lock_lock_recursive (GL(dl_load_lock));
1404 +      /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
1405 +        it can e.g. point to unallocated memory.  So avoid the optimizer
1406 +        treating the above read from MAP->l_serial as ensurance it
1407 +        can safely dereference it.  */
1408 +      map = atomic_forced_read (map);
1409 +
1410 +      /* From this point on it is unsafe to dereference MAP, until it
1411 +        has been found in one of the lists.  */
1412 +
1413 +      /* Redo the l_initfini check in case undef_map's l_initfini
1414 +        changed in the mean time.  */
1415 +      if (undef_map->l_initfini != l_initfini
1416 +         && undef_map->l_initfini != NULL)
1417 +       {
1418 +         l_initfini = undef_map->l_initfini;
1419 +         for (i = 0; l_initfini[i] != NULL; ++i)
1420 +           if (l_initfini[i] == map)
1421 +             goto out_check;
1422 +       }
1423 +
1424 +      /* Redo the l_reldeps check if undef_map's l_reldeps changed in
1425 +        the mean time.  */
1426 +      if (undef_map->l_reldeps != NULL)
1427 +       {
1428 +         if (undef_map->l_reldeps != l_reldeps)
1429 +           {
1430 +             struct link_map **list = &undef_map->l_reldeps->list[0];
1431 +             l_reldepsact = undef_map->l_reldeps->act;
1432 +             for (i = 0; i < l_reldepsact; ++i)
1433 +               if (list[i] == map)
1434 +                 goto out_check;
1435 +           }
1436 +         else if (undef_map->l_reldeps->act > l_reldepsact)
1437 +           {
1438 +             struct link_map **list
1439 +               = &undef_map->l_reldeps->list[0];
1440 +             i = l_reldepsact;
1441 +             l_reldepsact = undef_map->l_reldeps->act;
1442 +             for (; i < l_reldepsact; ++i)
1443 +               if (list[i] == map)
1444 +                 goto out_check;
1445 +           }
1446 +       }
1447 +    }
1448 +  else
1449 +    __rtld_lock_lock_recursive (GL(dl_load_lock));
1450 +
1451 +  /* The object is not yet in the dependency list.  Before we add
1452 +     it make sure just one more time the object we are about to
1453 +     reference is still available.  There is a brief period in
1454 +     which the object could have been removed since we found the
1455 +     definition.  */
1456 +  runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
1457 +  while (runp != NULL && runp != map)
1458 +    runp = runp->l_next;
1459 +
1460 +  if (runp != NULL)
1461 +    {
1462 +      /* The object is still available.  */
1463 +
1464 +      /* MAP could have been dlclosed, freed and then some other dlopened
1465 +        library could have the same link_map pointer.  */
1466 +      if (map->l_serial != serial)
1467 +       goto out_check;
1468 +
1469 +      /* Redo the NODELETE check, as when dl_load_lock wasn't held
1470 +        yet this could have changed.  */
1471 +      if ((map->l_flags_1 & DF_1_NODELETE) != 0)
1472 +       goto out;
1473 +
1474 +      /* If the object with the undefined reference cannot be removed ever
1475 +        just make sure the same is true for the object which contains the
1476 +        definition.  */
1477 +      if (undef_map->l_type != lt_loaded
1478 +         || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
1479 +       {
1480 +         map->l_flags_1 |= DF_1_NODELETE;
1481 +         goto out;
1482 +       }
1483 +
1484 +      /* Add the reference now.  */
1485 +      if (__builtin_expect (l_reldepsact >= undef_map->l_reldepsmax, 0))
1486 +       {
1487 +         /* Allocate more memory for the dependency list.  Since this
1488 +            can never happen during the startup phase we can use
1489 +            `realloc'.  */
1490 +         struct link_map_reldeps *newp;
1491 +         unsigned int max
1492 +           = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
1493 +
1494 +#ifdef RTLD_PREPARE_FOREIGN_CALL
1495 +         RTLD_PREPARE_FOREIGN_CALL;
1496 +#endif
1497 +
1498 +         newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
1499 +         if (newp == NULL)
1500 +           {
1501 +             /* If we didn't manage to allocate memory for the list this is
1502 +                no fatal problem.  We simply make sure the referenced object
1503 +                cannot be unloaded.  This is semantically the correct
1504 +                behavior.  */
1505 +             map->l_flags_1 |= DF_1_NODELETE;
1506 +             goto out;
1507 +           }
1508 +         else
1509 +           {
1510 +             if (l_reldepsact)
1511 +               memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
1512 +                       l_reldepsact * sizeof (struct link_map *));
1513 +             newp->list[l_reldepsact] = map;
1514 +             newp->act = l_reldepsact + 1;
1515 +             atomic_write_barrier ();
1516 +             void *old = undef_map->l_reldeps;
1517 +             undef_map->l_reldeps = newp;
1518 +             undef_map->l_reldepsmax = max;
1519 +             if (old)
1520 +               _dl_scope_free (old);
1521 +           }
1522 +       }
1523 +      else
1524 +       {
1525 +         undef_map->l_reldeps->list[l_reldepsact] = map;
1526 +         atomic_write_barrier ();
1527 +         undef_map->l_reldeps->act = l_reldepsact + 1;
1528 +       }
1529 +
1530 +      /* Display information if we are debugging.  */
1531 +      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
1532 +       _dl_debug_printf ("\
1533 +\nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
1534 +                         map->l_name[0] ? map->l_name : rtld_progname,
1535 +                         map->l_ns,
1536 +                         undef_map->l_name[0]
1537 +                         ? undef_map->l_name : rtld_progname,
1538 +                         undef_map->l_ns);
1539 +    }
1540 +  else
1541 +    /* Whoa, that was bad luck.  We have to search again.  */
1542 +    result = -1;
1543 +
1544 + out:
1545 +  /* Release the lock.  */
1546 +  __rtld_lock_unlock_recursive (GL(dl_load_lock));
1547 +
1548 +  if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
1549 +    THREAD_GSCOPE_SET_FLAG ();
1550 +
1551 +  return result;
1552 +
1553 + out_check:
1554 +  if (map->l_serial != serial)
1555 +    result = -1;
1556 +  goto out;
1557 +}
1558 +
1559 +static void
1560 +internal_function
1561 +_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
1562 +                   const ElfW(Sym) **ref, struct sym_val *value,
1563 +                   const struct r_found_version *version, int type_class,
1564 +                   int protected);
1565 +
1566 +
1567 +/* Search loaded objects' symbol tables for a definition of the symbol
1568 +   UNDEF_NAME, perhaps with a requested version for the symbol.
1569 +
1570 +   We must never have calls to the audit functions inside this function
1571 +   or in any function which gets called.  If this would happen the audit
1572 +   code might create a thread which can throw off all the scope locking.  */
1573 +lookup_t
1574 +internal_function
1575 +_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
1576 +                    const ElfW(Sym) **ref,
1577 +                    struct r_scope_elem *symbol_scope[],
1578 +                    const struct r_found_version *version,
1579 +                    int type_class, int flags, struct link_map *skip_map)
1580 +{
1581 +  const uint_fast32_t new_hash = dl_new_hash (undef_name);
1582 +  unsigned long int old_hash = 0xffffffff;
1583 +  struct sym_val current_value = { NULL, NULL };
1584 +  struct r_scope_elem **scope = symbol_scope;
1585 +
1586 +  bump_num_relocations ();
1587 +
1588 +  /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK
1589 +     is allowed if we look up a versioned symbol.  */
1590 +  assert (version == NULL
1591 +         || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK))
1592 +            == 0);
1593 +
1594 +  size_t i = 0;
1595 +  if (__builtin_expect (skip_map != NULL, 0))
1596 +    /* Search the relevant loaded objects for a definition.  */
1597 +    while ((*scope)->r_list[i] != skip_map)
1598 +      ++i;
1599 +
1600 +  /* Search the relevant loaded objects for a definition.  */
1601 +  for (size_t start = i; *scope != NULL; start = 0, ++scope)
1602 +    {
1603 +      int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1604 +                            &current_value, *scope, start, version, flags,
1605 +                            skip_map, type_class, undef_map);
1606 +      if (res > 0)
1607 +       break;
1608 +
1609 +      if (__builtin_expect (res, 0) < 0 && skip_map == NULL)
1610 +       {
1611 +         /* Oh, oh.  The file named in the relocation entry does not
1612 +            contain the needed symbol.  This code is never reached
1613 +            for unversioned lookups.  */
1614 +         assert (version != NULL);
1615 +         const char *reference_name = undef_map ? undef_map->l_name : NULL;
1616 +
1617 +         /* XXX We cannot translate the message.  */
1618 +         _dl_signal_cerror (0, (reference_name[0]
1619 +                                ? reference_name
1620 +                                : (rtld_progname ?: "<main program>")),
1621 +                            N_("relocation error"),
1622 +                            make_string ("symbol ", undef_name, ", version ",
1623 +                                         version->name,
1624 +                                         " not defined in file ",
1625 +                                         version->filename,
1626 +                                         " with link time reference",
1627 +                                         res == -2
1628 +                                         ? " (no version symbols)" : ""));
1629 +         *ref = NULL;
1630 +         return 0;
1631 +       }
1632 +    }
1633 +
1634 +  if (__builtin_expect (current_value.s == NULL, 0))
1635 +    {
1636 +      if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
1637 +         && skip_map == NULL)
1638 +       {
1639 +         /* We could find no value for a strong reference.  */
1640 +         const char *reference_name = undef_map ? undef_map->l_name : "";
1641 +         const char *versionstr = version ? ", version " : "";
1642 +         const char *versionname = (version && version->name
1643 +                                    ? version->name : "");
1644 +
1645 +         /* XXX We cannot translate the message.  */
1646 +         _dl_signal_cerror (0, (reference_name[0]
1647 +                                ? reference_name
1648 +                                : (rtld_progname ?: "<main program>")),
1649 +                            N_("symbol lookup error"),
1650 +                            make_string (undefined_msg, undef_name,
1651 +                                         versionstr, versionname));
1652 +       }
1653 +      *ref = NULL;
1654 +      return 0;
1655 +    }
1656 +
1657 +  int protected = (*ref
1658 +                  && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
1659 +  if (__builtin_expect (protected != 0, 0))
1660 +    {
1661 +      /* It is very tricky.  We need to figure out what value to
1662 +        return for the protected symbol.  */
1663 +      if (type_class == ELF_RTYPE_CLASS_PLT)
1664 +       {
1665 +         if (current_value.s != NULL && current_value.m != undef_map)
1666 +           {
1667 +             current_value.s = *ref;
1668 +             current_value.m = undef_map;
1669 +           }
1670 +       }
1671 +      else
1672 +       {
1673 +         struct sym_val protected_value = { NULL, NULL };
1674 +
1675 +         for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
1676 +           if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1677 +                            &protected_value, *scope, i, version, flags,
1678 +                            skip_map, ELF_RTYPE_CLASS_PLT, NULL) != 0)
1679 +             break;
1680 +
1681 +         if (protected_value.s != NULL && protected_value.m != undef_map)
1682 +           {
1683 +             current_value.s = *ref;
1684 +             current_value.m = undef_map;
1685 +           }
1686 +       }
1687 +    }
1688 +
1689 +  /* We have to check whether this would bind UNDEF_MAP to an object
1690 +     in the global scope which was dynamically loaded.  In this case
1691 +     we have to prevent the latter from being unloaded unless the
1692 +     UNDEF_MAP object is also unloaded.  */
1693 +  if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
1694 +      /* Don't do this for explicit lookups as opposed to implicit
1695 +        runtime lookups.  */
1696 +      && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
1697 +      /* Add UNDEF_MAP to the dependencies.  */
1698 +      && add_dependency (undef_map, current_value.m, flags) < 0)
1699 +      /* Something went wrong.  Perhaps the object we tried to reference
1700 +        was just removed.  Try finding another definition.  */
1701 +      return _dl_lookup_symbol_x (undef_name, undef_map, ref,
1702 +                                 (flags & DL_LOOKUP_GSCOPE_LOCK)
1703 +                                 ? undef_map->l_scope : symbol_scope,
1704 +                                 version, type_class, flags, skip_map);
1705 +
1706 +  /* The object is used.  */
1707 +  if (__builtin_expect (current_value.m->l_used == 0, 0))
1708 +    current_value.m->l_used = 1;
1709 +
1710 +  if (__builtin_expect (GLRO(dl_debug_mask)
1711 +                       & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
1712 +    _dl_debug_bindings (undef_name, undef_map, ref,
1713 +                       &current_value, version, type_class, protected);
1714 +
1715 +  *ref = current_value.s;
1716 +  return LOOKUP_VALUE (current_value.m);
1717 +}
1718 +
1719 +
1720 +/* Cache the location of MAP's hash table.  */
1721 +
1722 +void
1723 +internal_function
1724 +_dl_setup_hash (struct link_map *map)
1725 +{
1726 +  Elf_Symndx *hash;
1727 +  Elf_Symndx nchain;
1728 +
1729 +  if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
1730 +                                   + DT_THISPROCNUM + DT_VERSIONTAGNUM
1731 +                                   + DT_EXTRANUM + DT_VALNUM] != NULL, 1))
1732 +    {
1733 +      Elf32_Word *hash32
1734 +       = (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
1735 +                                     + DT_THISPROCNUM + DT_VERSIONTAGNUM
1736 +                                     + DT_EXTRANUM + DT_VALNUM]);
1737 +      map->l_nbuckets = *hash32++;
1738 +      Elf32_Word symbias = *hash32++;
1739 +      Elf32_Word bitmask_nwords = *hash32++;
1740 +      /* Must be a power of two.  */
1741 +      assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
1742 +      map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
1743 +      map->l_gnu_shift = *hash32++;
1744 +
1745 +      map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
1746 +      hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
1747 +
1748 +      map->l_gnu_buckets = hash32;
1749 +      hash32 += map->l_nbuckets;
1750 +      map->l_gnu_chain_zero = hash32 - symbias;
1751 +      return;
1752 +    }
1753 +
1754 +  if (!map->l_info[DT_HASH])
1755 +    return;
1756 +  hash = (void *) D_PTR (map, l_info[DT_HASH]);
1757 +
1758 +  map->l_nbuckets = *hash++;
1759 +  nchain = *hash++;
1760 +  map->l_buckets = hash;
1761 +  hash += map->l_nbuckets;
1762 +  map->l_chain = hash;
1763 +}
1764 +
1765 +
1766 +static void
1767 +internal_function
1768 +_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
1769 +                   const ElfW(Sym) **ref, struct sym_val *value,
1770 +                   const struct r_found_version *version, int type_class,
1771 +                   int protected)
1772 +{
1773 +  const char *reference_name = undef_map->l_name;
1774 +
1775 +  if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
1776 +    {
1777 +      _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
1778 +                       (reference_name[0]
1779 +                        ? reference_name
1780 +                        : (rtld_progname ?: "<main program>")),
1781 +                       undef_map->l_ns,
1782 +                       value->m->l_name[0] ? value->m->l_name : rtld_progname,
1783 +                       value->m->l_ns,
1784 +                       protected ? "protected" : "normal", undef_name);
1785 +      if (version)
1786 +       _dl_debug_printf_c (" [%s]\n", version->name);
1787 +      else
1788 +       _dl_debug_printf_c ("\n");
1789 +    }
1790 +#ifdef SHARED
1791 +  if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
1792 +    {
1793 +      int conflict = 0;
1794 +      struct sym_val val = { NULL, NULL };
1795 +
1796 +      if ((GLRO(dl_trace_prelink_map) == NULL
1797 +          || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
1798 +         && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
1799 +       {
1800 +         const uint_fast32_t new_hash = dl_new_hash (undef_name);
1801 +         unsigned long int old_hash = 0xffffffff;
1802 +         struct unique_sym *saved_entries
1803 +           = GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries;
1804 +
1805 +         GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL;
1806 +         do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
1807 +                      undef_map->l_local_scope[0], 0, version, 0, NULL,
1808 +                      type_class, undef_map);
1809 +         if (val.s != value->s || val.m != value->m)
1810 +           conflict = 1;
1811 +         else if (__builtin_expect (undef_map->l_symbolic_in_local_scope, 0)
1812 +                  && val.s
1813 +                  && __builtin_expect (ELFW(ST_BIND) (val.s->st_info),
1814 +                                       STB_GLOBAL) == STB_GNU_UNIQUE)
1815 +           {
1816 +             /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope
1817 +                contains any DT_SYMBOLIC libraries, unfortunately there
1818 +                can be conflicts even if the above is equal.  As symbol
1819 +                resolution goes from the last library to the first and
1820 +                if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC
1821 +                library, it would be the one that is looked up.  */
1822 +             struct sym_val val2 = { NULL, NULL };
1823 +             size_t n;
1824 +             struct r_scope_elem *scope = undef_map->l_local_scope[0];
1825 +
1826 +             for (n = 0; n < scope->r_nlist; n++)
1827 +               if (scope->r_list[n] == val.m)
1828 +                 break;
1829 +
1830 +             for (n++; n < scope->r_nlist; n++)
1831 +               if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL
1832 +                   && do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1833 +                                   &val2,
1834 +                                   &scope->r_list[n]->l_symbolic_searchlist,
1835 +                                   0, version, 0, NULL, type_class,
1836 +                                   undef_map) > 0)
1837 +                 {
1838 +                   conflict = 1;
1839 +                   val = val2;
1840 +                   break;
1841 +                 }
1842 +           }
1843 +         GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
1844 +       }
1845 +
1846 +      if (value->s)
1847 +       {
1848 +         if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
1849 +                               == STT_TLS, 0))
1850 +           type_class = 4;
1851 +         else if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
1852 +                                    == STT_GNU_IFUNC, 0))
1853 +           type_class |= 8;
1854 +       }
1855 +
1856 +      if (conflict
1857 +         || GLRO(dl_trace_prelink_map) == undef_map
1858 +         || GLRO(dl_trace_prelink_map) == NULL
1859 +         || type_class >= 4)
1860 +       {
1861 +         _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
1862 +                     conflict ? "conflict" : "lookup",
1863 +                     (int) sizeof (ElfW(Addr)) * 2,
1864 +                     (size_t) undef_map->l_map_start,
1865 +                     (int) sizeof (ElfW(Addr)) * 2,
1866 +                     (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
1867 +                     (int) sizeof (ElfW(Addr)) * 2,
1868 +                     (size_t) (value->s ? value->m->l_map_start : 0),
1869 +                     (int) sizeof (ElfW(Addr)) * 2,
1870 +                     (size_t) (value->s ? value->s->st_value : 0));
1871 +
1872 +         if (conflict)
1873 +           _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
1874 +                       (int) sizeof (ElfW(Addr)) * 2,
1875 +                       (size_t) (val.s ? val.m->l_map_start : 0),
1876 +                       (int) sizeof (ElfW(Addr)) * 2,
1877 +                       (size_t) (val.s ? val.s->st_value : 0));
1878 +
1879 +         _dl_printf ("/%x %s\n", type_class, undef_name);
1880 +       }
1881 +    }
1882 +#endif
1883 +}
1884 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-machine.h b/glibc-2.14.1/sysdeps/riscv/dl-machine.h
1885 new file mode 100644
1886 index 0000000..7f65545
1887 --- /dev/null
1888 +++ glibc-2.14.1/sysdeps/riscv/dl-machine.h
1889 @@ -0,0 +1,717 @@
1890 +/* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
1891 +   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007
1892 +   Free Software Foundation, Inc.
1893 +   This file is part of the GNU C Library.
1894 +   Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
1895 +
1896 +   The GNU C Library is free software; you can redistribute it and/or
1897 +   modify it under the terms of the GNU Lesser General Public
1898 +   License as published by the Free Software Foundation; either
1899 +   version 2.1 of the License, or (at your option) any later version.
1900 +
1901 +   The GNU C Library is distributed in the hope that it will be useful,
1902 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
1903 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1904 +   Lesser General Public License for more details.
1905 +
1906 +   You should have received a copy of the GNU Lesser General Public
1907 +   License along with the GNU C Library; if not, write to the Free
1908 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1909 +   02111-1307 USA.  */
1910 +
1911 +/*  FIXME: Profiling of shared libraries is not implemented yet.  */
1912 +#ifndef dl_machine_h
1913 +#define dl_machine_h
1914 +
1915 +#define ELF_MACHINE_NAME "RISC-V"
1916 +
1917 +#include <entry.h>
1918 +
1919 +#ifndef ENTRY_POINT
1920 +#error ENTRY_POINT needs to be defined for MIPS.
1921 +#endif
1922 +
1923 +#include <sys/asm.h>
1924 +#include <dl-tls.h>
1925 +
1926 +#ifndef _RTLD_PROLOGUE
1927 +# define _RTLD_PROLOGUE(entry)                                         \
1928 +       ".globl\t" __STRING(entry) "\n\t"                               \
1929 +       ".type\t" __STRING(entry) ", @function\n"                       \
1930 +       __STRING(entry) ":\n\t"
1931 +#endif
1932 +
1933 +#ifndef _RTLD_EPILOGUE
1934 +# define _RTLD_EPILOGUE(entry)                                         \
1935 +       ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
1936 +#endif
1937 +
1938 +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
1939 +   This only makes sense on MIPS when using PLTs, so choose the
1940 +   PLT relocation (not encountered when not using PLTs).  */
1941 +#define ELF_MACHINE_JMP_SLOT                   R_MIPS_JUMP_SLOT
1942 +#define elf_machine_type_class(type) \
1943 +  ((((type) == ELF_MACHINE_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)    \
1944 +   | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY))
1945 +
1946 +#define ELF_MACHINE_PLT_REL 1
1947 +
1948 +/* Translate a processor specific dynamic tag to the index
1949 +   in l_info array.  */
1950 +#define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM)
1951 +
1952 +/* If there is a DT_MIPS_RLD_MAP entry in the dynamic section, fill it in
1953 +   with the run-time address of the r_debug structure  */
1954 +#define ELF_MACHINE_DEBUG_SETUP(l,r) \
1955 +do { if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
1956 +       *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \
1957 +       (ElfW(Addr)) (r); \
1958 +   } while (0)
1959 +
1960 +/* Return nonzero iff ELF header is compatible with the running host.  */
1961 +static inline int __attribute_used__
1962 +elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
1963 +{
1964 +  return 1;
1965 +}
1966 +
1967 +static inline ElfW(Addr) *
1968 +elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
1969 +{
1970 +  return (ElfW(Addr) *) gpreg;
1971 +}
1972 +
1973 +/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
1974 +   first element of the GOT.  This must be inlined in a function which
1975 +   uses global data.  */
1976 +static inline ElfW(Addr)
1977 +elf_machine_dynamic (void)
1978 +{
1979 +  ElfW(Addr) load, link, got;
1980 +  asm ("   la   %0, 1f\n"
1981 +       "   la   %1, _GLOBAL_OFFSET_TABLE_\n"
1982 +       "1: rdpc %2"
1983 +       : "=r"(link), "=r"(got), "=r"(load));
1984 +
1985 +  return *elf_mips_got_from_gpreg(load - link + got);
1986 +}
1987 +
1988 +#define STRINGXP(X) __STRING(X)
1989 +#define STRINGXV(X) STRINGV_(X)
1990 +#define STRINGV_(...) # __VA_ARGS__
1991 +
1992 +/* Return the run-time load address of the shared object.  */
1993 +static inline ElfW(Addr)
1994 +elf_machine_load_address (void)
1995 +{
1996 +  ElfW(Addr) load, link;
1997 +  asm ("   la   %0, 1f\n"
1998 +       "1: rdpc %1\n"
1999 +       : "=r"(link), "=r"(load));
2000 +
2001 +  return load - link;
2002 +}
2003 +
2004 +/* The MSB of got[1] of a gnu object is set to identify gnu objects.  */
2005 +#ifdef __riscv64
2006 +# define ELF_MIPS_GNU_GOT1_MASK        0x8000000000000000L
2007 +#else
2008 +# define ELF_MIPS_GNU_GOT1_MASK        0x80000000L
2009 +#endif
2010 +
2011 +/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
2012 +   fiddles with global data.  */
2013 +#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info)                    \
2014 +do {                                                                   \
2015 +  struct link_map *map = &bootstrap_map;                               \
2016 +  ElfW(Sym) *sym;                                                      \
2017 +  ElfW(Addr) *got;                                                     \
2018 +  int i, n;                                                            \
2019 +                                                                       \
2020 +  got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);                 \
2021 +                                                                       \
2022 +  if (__builtin_expect (map->l_addr == 0, 1))                          \
2023 +    break;                                                             \
2024 +                                                                       \
2025 +  /* got[0] is reserved. got[1] is also reserved for the dynamic object        \
2026 +     generated by gnu ld. Skip these reserved entries from             \
2027 +     relocation.  */                                                   \
2028 +  i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;                                \
2029 +  n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;                  \
2030 +                                                                       \
2031 +  /* Add the run-time displacement to all local got entries. */                \
2032 +  while (i < n)                                                                \
2033 +    got[i++] += map->l_addr;                                           \
2034 +                                                                       \
2035 +  /* Handle global got entries. */                                     \
2036 +  got += n;                                                            \
2037 +  sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB])                    \
2038 +       + map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;                    \
2039 +  i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val                     \
2040 +       - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);                   \
2041 +                                                                       \
2042 +  while (i--)                                                          \
2043 +    {                                                                  \
2044 +      if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON)   \
2045 +       *got = map->l_addr + sym->st_value;                             \
2046 +      else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC                        \
2047 +              && *got != sym->st_value)                                \
2048 +       *got += map->l_addr;                                            \
2049 +      else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)            \
2050 +       {                                                               \
2051 +         if (sym->st_other == 0)                                       \
2052 +           *got += map->l_addr;                                        \
2053 +       }                                                               \
2054 +      else                                                             \
2055 +       *got = map->l_addr + sym->st_value;                             \
2056 +                                                                       \
2057 +      got++;                                                           \
2058 +      sym++;                                                           \
2059 +    }                                                                  \
2060 +} while(0)
2061 +
2062 +
2063 +/* Mask identifying addresses reserved for the user program,
2064 +   where the dynamic linker should not map anything.  */
2065 +#define ELF_MACHINE_USER_ADDRESS_MASK  0x80000000UL
2066 +
2067 +
2068 +/* Initial entry point code for the dynamic linker.
2069 +   The C function `_dl_start' is the real entry point;
2070 +   its return value is the user program's entry point. */
2071 +
2072 +#define RTLD_START asm (\
2073 +       ".text\n\
2074 +       " _RTLD_PROLOGUE(ENTRY_POINT) "\
2075 +       # Store &_DYNAMIC in the first entry of the GOT.\n\
2076 +       la a1, 1f\n\
2077 +       la a2, _GLOBAL_OFFSET_TABLE_\n\
2078 +       la a3, _DYNAMIC\n\
2079 +       1: rdpc a0\n\
2080 +       sub a0, a0, a1\n\
2081 +       add a0, a0, a2\n\
2082 +       " STRINGXP(REG_S) " a3, 0(a0)\n\
2083 +       move a0, sp\n\
2084 +       jal _dl_start\n\
2085 +       # Fall through to _dl_start_user \
2086 +       " _RTLD_EPILOGUE(ENTRY_POINT) "\
2087 +       \n\
2088 +       \n\
2089 +       " _RTLD_PROLOGUE(_dl_start_user) "\
2090 +       # Stash user entry point in s0.\n\
2091 +       move s0, v0\n\
2092 +       # See if we were run as a command with the executable file\n\
2093 +       # name as an extra leading argument.\n\
2094 +       la v0, _dl_skip_args\n\
2095 +       lw v0, 0(v0)\n\
2096 +       beqz v0, 1f\n\
2097 +       # Load the original argument count.\n\
2098 +       " STRINGXP(REG_L) " a0, 0(sp)\n\
2099 +       # Subtract _dl_skip_args from it.\n\
2100 +       sub a0, a0, v0\n\
2101 +       # Adjust the stack pointer to skip _dl_skip_args words.\n\
2102 +       sll v0, v0, " STRINGXP (PTRLOG) "\n\
2103 +       add sp, sp, v0\n\
2104 +       # Save back the modified argument count.\n\
2105 +       " STRINGXP(REG_S) " a0, 0(sp)\n\
2106 +1:     # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
2107 +       la a0, _rtld_local\n\
2108 +       " STRINGXP(REG_L) " a0, 0(a0)\n\
2109 +       " STRINGXP(REG_L) " a1, 0(sp)\n\
2110 +       add a2, sp, " STRINGXP (PTRSIZE) "\n\
2111 +       sll a3, a1, " STRINGXP (PTRLOG) "\n\
2112 +       add a3, a3, a2\n\
2113 +       add a3, a3, " STRINGXP (PTRSIZE) "\n\
2114 +       # Call the function to run the initializers.\n\
2115 +       jal _dl_init_internal\n\
2116 +       # Pass our finalizer function to the user in v0 as per ELF ABI.\n\
2117 +       la v0, _dl_fini\n\
2118 +       # Jump to the user entry point.\n\
2119 +       jr s0\n\t"\
2120 +       _RTLD_EPILOGUE(_dl_start_user)\
2121 +       ".previous"\
2122 +);
2123 +
2124 +/* Names of the architecture-specific auditing callback functions.  */
2125 +# ifdef __riscv64
2126 +#  define ARCH_LA_PLTENTER mips_n64_gnu_pltenter
2127 +#  define ARCH_LA_PLTEXIT mips_n64_gnu_pltexit
2128 +# else
2129 +#  define ARCH_LA_PLTENTER mips_n32_gnu_pltenter
2130 +#  define ARCH_LA_PLTEXIT mips_n32_gnu_pltexit
2131 +# endif
2132 +
2133 +/* For a non-writable PLT, rewrite the .got.plt entry at RELOC_ADDR to
2134 +   point at the symbol with address VALUE.  For a writable PLT, rewrite
2135 +   the corresponding PLT entry instead.  */
2136 +static inline ElfW(Addr)
2137 +elf_machine_fixup_plt (struct link_map *map, lookup_t t,
2138 +                      const ElfW(Rel) *reloc,
2139 +                      ElfW(Addr) *reloc_addr, ElfW(Addr) value)
2140 +{
2141 +  return *reloc_addr = value;
2142 +}
2143 +
2144 +static inline ElfW(Addr)
2145 +elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc,
2146 +                      ElfW(Addr) value)
2147 +{
2148 +  return value;
2149 +}
2150 +
2151 +#endif /* !dl_machine_h */
2152 +
2153 +#ifdef RESOLVE_MAP
2154 +
2155 +/* Perform a relocation described by R_INFO at the location pointed to
2156 +   by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
2157 +   MAP is the object containing the reloc.  */
2158 +
2159 +auto inline void
2160 +__attribute__ ((always_inline))
2161 +elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
2162 +                  const ElfW(Sym) *sym, const struct r_found_version *version,
2163 +                  void *reloc_addr, ElfW(Addr) r_addend, int inplace_p)
2164 +{
2165 +  const unsigned long int r_type = ELFW(R_TYPE) (r_info);
2166 +  ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
2167 +
2168 +#if !defined RTLD_BOOTSTRAP && !defined SHARED
2169 +  /* This is defined in rtld.c, but nowhere in the static libc.a;
2170 +     make the reference weak so static programs can still link.  This
2171 +     declaration cannot be done when compiling rtld.c (i.e.  #ifdef
2172 +     RTLD_BOOTSTRAP) because rtld.c contains the common defn for
2173 +     _dl_rtld_map, which is incompatible with a weak decl in the same
2174 +     file.  */
2175 +  weak_extern (GL(dl_rtld_map));
2176 +#endif
2177 +
2178 +  switch (r_type)
2179 +    {
2180 +#if defined (USE_TLS) && !defined (RTLD_BOOTSTRAP)
2181 +# if _RISCV_SIM == _ABI64
2182 +    case R_MIPS_TLS_DTPMOD64:
2183 +    case R_MIPS_TLS_DTPREL64:
2184 +    case R_MIPS_TLS_TPREL64:
2185 +# else
2186 +    case R_MIPS_TLS_DTPMOD32:
2187 +    case R_MIPS_TLS_DTPREL32:
2188 +    case R_MIPS_TLS_TPREL32:
2189 +# endif
2190 +      {
2191 +       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
2192 +
2193 +       switch (r_type)
2194 +         {
2195 +         case R_MIPS_TLS_DTPMOD64:
2196 +         case R_MIPS_TLS_DTPMOD32:
2197 +           if (sym_map)
2198 +             *addr_field = sym_map->l_tls_modid;
2199 +           break;
2200 +
2201 +         case R_MIPS_TLS_DTPREL64:
2202 +         case R_MIPS_TLS_DTPREL32:
2203 +           if (sym)
2204 +             {
2205 +               if (inplace_p)
2206 +                 r_addend = *addr_field;
2207 +               *addr_field = r_addend + TLS_DTPREL_VALUE (sym);
2208 +             }
2209 +           break;
2210 +
2211 +         case R_MIPS_TLS_TPREL32:
2212 +         case R_MIPS_TLS_TPREL64:
2213 +           if (sym)
2214 +             {
2215 +               CHECK_STATIC_TLS (map, sym_map);
2216 +               if (inplace_p)
2217 +                 r_addend = *addr_field;
2218 +               *addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym);
2219 +             }
2220 +           break;
2221 +         }
2222 +
2223 +       break;
2224 +      }
2225 +#endif
2226 +
2227 +#if _RISCV_SIM == _ABI64
2228 +    case (R_MIPS_64 << 8) | R_MIPS_REL32:
2229 +#else
2230 +    case R_MIPS_REL32:
2231 +#endif
2232 +      {
2233 +       int symidx = ELFW(R_SYM) (r_info);
2234 +       ElfW(Addr) reloc_value;
2235 +
2236 +       if (inplace_p)
2237 +         /* Support relocations on mis-aligned offsets.  */
2238 +         __builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
2239 +       else
2240 +         reloc_value = r_addend;
2241 +
2242 +       if (symidx)
2243 +         {
2244 +           const ElfW(Word) gotsym
2245 +             = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
2246 +
2247 +           if ((ElfW(Word))symidx < gotsym)
2248 +             {
2249 +               /* This wouldn't work for a symbol imported from other
2250 +                  libraries for which there's no GOT entry, but MIPS
2251 +                  requires every symbol referenced in a dynamic
2252 +                  relocation to have a GOT entry in the primary GOT,
2253 +                  so we only get here for locally-defined symbols.
2254 +                  For section symbols, we should *NOT* be adding
2255 +                  sym->st_value (per the definition of the meaning of
2256 +                  S in reloc expressions in the ELF64 MIPS ABI),
2257 +                  since it should have already been added to
2258 +                  reloc_value by the linker, but older versions of
2259 +                  GNU ld didn't add it, and newer versions don't emit
2260 +                  useless relocations to section symbols any more, so
2261 +                  it is safe to keep on adding sym->st_value, even
2262 +                  though it's not ABI compliant.  Some day we should
2263 +                  bite the bullet and stop doing this.  */
2264 +#ifndef RTLD_BOOTSTRAP
2265 +               if (map != &GL(dl_rtld_map))
2266 +#endif
2267 +                 reloc_value += sym->st_value + map->l_addr;
2268 +             }
2269 +           else
2270 +             {
2271 +#ifndef RTLD_BOOTSTRAP
2272 +               const ElfW(Addr) *got
2273 +                 = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
2274 +               const ElfW(Word) local_gotno
2275 +                 = (const ElfW(Word))
2276 +                   map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
2277 +
2278 +               reloc_value += got[symidx + local_gotno - gotsym];
2279 +#endif
2280 +             }
2281 +         }
2282 +       else
2283 +#ifndef RTLD_BOOTSTRAP
2284 +         if (map != &GL(dl_rtld_map))
2285 +#endif
2286 +           reloc_value += map->l_addr;
2287 +
2288 +       __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
2289 +      }
2290 +      break;
2291 +#ifndef RTLD_BOOTSTRAP
2292 +#if _RISCV_SIM == _ABI64
2293 +    case (R_MIPS_64 << 8) | R_MIPS_GLOB_DAT:
2294 +#else
2295 +    case R_MIPS_GLOB_DAT:
2296 +#endif
2297 +      {
2298 +       int symidx = ELFW(R_SYM) (r_info);
2299 +       const ElfW(Word) gotsym
2300 +         = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
2301 +
2302 +       if (__builtin_expect ((ElfW(Word)) symidx >= gotsym, 1))
2303 +         {
2304 +           const ElfW(Addr) *got
2305 +             = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
2306 +           const ElfW(Word) local_gotno
2307 +             = ((const ElfW(Word))
2308 +                map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val);
2309 +
2310 +           ElfW(Addr) reloc_value = got[symidx + local_gotno - gotsym];
2311 +           __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
2312 +         }
2313 +      }
2314 +      break;
2315 +#endif
2316 +    case R_MIPS_NONE:          /* Alright, Wilbur.  */
2317 +      break;
2318 +
2319 +    case R_MIPS_JUMP_SLOT:
2320 +      {
2321 +       struct link_map *sym_map;
2322 +       ElfW(Addr) value;
2323 +
2324 +       /* The addend for a jump slot relocation must always be zero:
2325 +          calls via the PLT always branch to the symbol's address and
2326 +          not to the address plus a non-zero offset.  */
2327 +       if (r_addend != 0)
2328 +         _dl_signal_error (0, map->l_name, NULL,
2329 +                           "found jump slot relocation with non-zero addend");
2330 +
2331 +       sym_map = RESOLVE_MAP (&sym, version, r_type);
2332 +       value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
2333 +       *addr_field = value;
2334 +
2335 +       break;
2336 +      }
2337 +
2338 +    case R_MIPS_COPY:
2339 +      {
2340 +       const ElfW(Sym) *const refsym = sym;
2341 +       struct link_map *sym_map;
2342 +       ElfW(Addr) value;
2343 +
2344 +       /* Calculate the address of the symbol.  */
2345 +       sym_map = RESOLVE_MAP (&sym, version, r_type);
2346 +       value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
2347 +
2348 +       if (__builtin_expect (sym == NULL, 0))
2349 +         /* This can happen in trace mode if an object could not be
2350 +            found.  */
2351 +         break;
2352 +       if (__builtin_expect (sym->st_size > refsym->st_size, 0)
2353 +           || (__builtin_expect (sym->st_size < refsym->st_size, 0)
2354 +               && GLRO(dl_verbose)))
2355 +         {
2356 +           const char *strtab;
2357 +
2358 +           strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
2359 +           _dl_error_printf ("\
2360 +  %s: Symbol `%s' has different size in shared object, consider re-linking\n",
2361 +                             rtld_progname ?: "<program name unknown>",
2362 +                             strtab + refsym->st_name);
2363 +         }
2364 +       memcpy (reloc_addr, (void *) value,
2365 +               MIN (sym->st_size, refsym->st_size));
2366 +       break;
2367 +      }
2368 +
2369 +#if _RISCV_SIM == _ABI64
2370 +    case R_MIPS_64:
2371 +      /* For full compliance with the ELF64 ABI, one must precede the
2372 +        _REL32/_64 pair of relocations with a _64 relocation, such
2373 +        that the in-place addend is read as a 64-bit value.  IRIX
2374 +        didn't pick up on this requirement, so we treat the
2375 +        _REL32/_64 relocation as a 64-bit relocation even if it's by
2376 +        itself.  For ABI compliance, we ignore such _64 dummy
2377 +        relocations.  For RELA, this may be simply removed, since
2378 +        it's totally unnecessary.  */
2379 +      if (ELFW(R_SYM) (r_info) == 0)
2380 +       break;
2381 +      /* Fall through.  */
2382 +#endif
2383 +    default:
2384 +      _dl_reloc_bad_type (map, r_type, 0);
2385 +      break;
2386 +    }
2387 +}
2388 +
2389 +/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
2390 +   MAP is the object containing the reloc.  */
2391 +
2392 +auto inline void
2393 +__attribute__ ((always_inline))
2394 +elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
2395 +                const ElfW(Sym) *sym, const struct r_found_version *version,
2396 +                void *const reloc_addr)
2397 +{
2398 +  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1);
2399 +}
2400 +
2401 +auto inline void
2402 +__attribute__((always_inline))
2403 +elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
2404 +                         void *const reloc_addr)
2405 +{
2406 +  /* XXX Nothing to do.  There is no relative relocation, right?  */
2407 +}
2408 +
2409 +auto inline void
2410 +__attribute__((always_inline))
2411 +elf_machine_lazy_rel (struct link_map *map,
2412 +                     ElfW(Addr) l_addr, const ElfW(Rel) *reloc)
2413 +{
2414 +  ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
2415 +  const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info);
2416 +  /* Check for unexpected PLT reloc type.  */
2417 +  if (__builtin_expect (r_type == R_MIPS_JUMP_SLOT, 1))
2418 +    {
2419 +      if (__builtin_expect (map->l_mach.plt, 0) == 0)
2420 +       {
2421 +         /* Nothing is required here since we only support lazy
2422 +            relocation in executables.  */
2423 +       }
2424 +      else
2425 +       *reloc_addr = map->l_mach.plt;
2426 +    }
2427 +  else
2428 +    _dl_reloc_bad_type (map, r_type, 1);
2429 +}
2430 +
2431 +auto inline void
2432 +__attribute__ ((always_inline))
2433 +elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
2434 +                 const ElfW(Sym) *sym, const struct r_found_version *version,
2435 +                void *const reloc_addr)
2436 +{
2437 +  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr,
2438 +                    reloc->r_addend, 0);
2439 +}
2440 +
2441 +auto inline void
2442 +__attribute__((always_inline))
2443 +elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
2444 +                          void *const reloc_addr)
2445 +{
2446 +}
2447 +
2448 +#ifndef RTLD_BOOTSTRAP
2449 +/* Relocate GOT. */
2450 +auto inline void
2451 +__attribute__((always_inline))
2452 +elf_machine_got_rel (struct link_map *map, int lazy)
2453 +{
2454 +  ElfW(Addr) *got;
2455 +  ElfW(Sym) *sym;
2456 +  const ElfW(Half) *vernum;
2457 +  int i, n, symidx;
2458 +
2459 +#define RESOLVE_GOTSYM(sym,vernum,sym_index,reloc)                       \
2460 +    ({                                                                   \
2461 +      const ElfW(Sym) *ref = sym;                                        \
2462 +      const struct r_found_version *version                              \
2463 +        = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL;          \
2464 +      struct link_map *sym_map;                                                  \
2465 +      sym_map = RESOLVE_MAP (&ref, version, reloc);                      \
2466 +      ref ? sym_map->l_addr + ref->st_value : 0;                         \
2467 +    })
2468 +
2469 +  if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
2470 +    vernum = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
2471 +  else
2472 +    vernum = NULL;
2473 +
2474 +  got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
2475 +
2476 +  n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
2477 +  /* The dynamic linker's local got entries have already been relocated.  */
2478 +  if (map != &GL(dl_rtld_map))
2479 +    {
2480 +      /* got[0] is reserved. got[1] is also reserved for the dynamic object
2481 +        generated by gnu ld. Skip these reserved entries from relocation.  */
2482 +      i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
2483 +
2484 +      /* Add the run-time displacement to all local got entries if
2485 +         needed.  */
2486 +      if (__builtin_expect (map->l_addr != 0, 0))
2487 +       {
2488 +         while (i < n)
2489 +           got[i++] += map->l_addr;
2490 +       }
2491 +    }
2492 +
2493 +  /* Handle global got entries. */
2494 +  got += n;
2495 +  /* Keep track of the symbol index.  */
2496 +  symidx = map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
2497 +  sym = (ElfW(Sym) *) D_PTR (map, l_info[DT_SYMTAB]) + symidx;
2498 +  i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val
2499 +       - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);
2500 +
2501 +  /* This loop doesn't handle Quickstart.  */
2502 +  while (i--)
2503 +    {
2504 +      if (sym->st_shndx == SHN_UNDEF)
2505 +       {
2506 +         if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC && sym->st_value
2507 +             && !(sym->st_other & STO_MIPS_PLT))
2508 +           {
2509 +             if (lazy)
2510 +               *got = sym->st_value + map->l_addr;
2511 +             else
2512 +               /* This is a lazy-binding stub, so we don't need the
2513 +                  canonical address.  */
2514 +               *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
2515 +           }
2516 +         else
2517 +           *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
2518 +       }
2519 +      else if (sym->st_shndx == SHN_COMMON)
2520 +       *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
2521 +      else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
2522 +              && *got != sym->st_value)
2523 +       {
2524 +         if (lazy)
2525 +           *got += map->l_addr;
2526 +         else
2527 +           /* This is a lazy-binding stub, so we don't need the
2528 +              canonical address.  */
2529 +           *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
2530 +       }
2531 +      else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)
2532 +       {
2533 +         if (sym->st_other == 0)
2534 +           *got += map->l_addr;
2535 +       }
2536 +      else
2537 +       *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
2538 +
2539 +      ++got;
2540 +      ++sym;
2541 +      ++symidx;
2542 +    }
2543 +
2544 +#undef RESOLVE_GOTSYM
2545 +}
2546 +#endif
2547 +
2548 +/* Set up the loaded object described by L so its stub function
2549 +   will jump to the on-demand fixup code __dl_runtime_resolve.  */
2550 +
2551 +auto inline int
2552 +__attribute__((always_inline))
2553 +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
2554 +{
2555 +# ifndef RTLD_BOOTSTRAP
2556 +  ElfW(Addr) *got;
2557 +  extern void _dl_runtime_resolve (ElfW(Word));
2558 +  extern void _dl_fixup (void);
2559 +  extern int _dl_mips_gnu_objects;
2560 +
2561 +  if (lazy)
2562 +    {
2563 +      /* The GOT entries for functions have not yet been filled in.
2564 +        Their initial contents will arrange when called to put an
2565 +        offset into the .dynsym section in t8, the return address
2566 +        in t7 and then jump to _GLOBAL_OFFSET_TABLE[0].  */
2567 +      got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
2568 +
2569 +      /* This function will get called to fix up the GOT entry indicated by
2570 +        the register t8, and then jump to the resolved address.  */
2571 +      got[0] = (ElfW(Addr)) &_dl_runtime_resolve;
2572 +
2573 +      /* Store l to _GLOBAL_OFFSET_TABLE[1] for gnu object. The MSB
2574 +        of got[1] of a gnu object is set to identify gnu objects.
2575 +        Where we can store l for non gnu objects? XXX  */
2576 +      if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)
2577 +       got[1] = ((ElfW(Addr)) l | ELF_MIPS_GNU_GOT1_MASK);
2578 +      else
2579 +       _dl_mips_gnu_objects = 0;
2580 +    }
2581 +
2582 +  /* Relocate global offset table.  */
2583 +  elf_machine_got_rel (l, lazy);
2584 +
2585 +  /* If using PLTs, fill in the first two entries of .got.plt.  */
2586 +  if (l->l_info[DT_JMPREL] && lazy)
2587 +    {
2588 +      ElfW(Addr) *gotplt;
2589 +      gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_MIPS (PLTGOT)]);
2590 +      /* If a library is prelinked but we have to relocate anyway,
2591 +        we have to be able to undo the prelinking of .got.plt.
2592 +        The prelinker saved the address of .plt for us here.  */
2593 +      if (gotplt[1])
2594 +       l->l_mach.plt = gotplt[1] + l->l_addr;
2595 +      gotplt[0] = (ElfW(Addr)) &_dl_fixup;
2596 +      gotplt[1] = (ElfW(Addr)) l;
2597 +      /* Relocate subsequent .got.plt entries. */
2598 +      for (gotplt += 2; *gotplt; gotplt++)
2599 +       *gotplt += l->l_addr;
2600 +    }
2601 +
2602 +# endif
2603 +  return lazy;
2604 +}
2605 +
2606 +#endif /* RESOLVE_MAP */
2607 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-tls.h b/glibc-2.14.1/sysdeps/riscv/dl-tls.h
2608 new file mode 100644
2609 index 0000000..69d3893
2610 --- /dev/null
2611 +++ glibc-2.14.1/sysdeps/riscv/dl-tls.h
2612 @@ -0,0 +1,49 @@
2613 +/* Thread-local storage handling in the ELF dynamic linker.  MIPS version.
2614 +   Copyright (C) 2005 Free Software Foundation, Inc.
2615 +   This file is part of the GNU C Library.
2616 +
2617 +   The GNU C Library is free software; you can redistribute it and/or
2618 +   modify it under the terms of the GNU Lesser General Public
2619 +   License as published by the Free Software Foundation; either
2620 +   version 2.1 of the License, or (at your option) any later version.
2621 +
2622 +   The GNU C Library is distributed in the hope that it will be useful,
2623 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
2624 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2625 +   Lesser General Public License for more details.
2626 +
2627 +   You should have received a copy of the GNU Lesser General Public
2628 +   License along with the GNU C Library; if not, write to the Free
2629 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2630 +   02111-1307 USA.  */
2631 +
2632 +
2633 +/* Type used for the representation of TLS information in the GOT.  */
2634 +typedef struct
2635 +{
2636 +  unsigned long int ti_module;
2637 +  unsigned long int ti_offset;
2638 +} tls_index;
2639 +
2640 +/* The thread pointer points 0x7000 past the first static TLS block.  */
2641 +#define TLS_TP_OFFSET          0x7000
2642 +
2643 +/* Dynamic thread vector pointers point 0x8000 past the start of each
2644 +   TLS block.  */
2645 +#define TLS_DTV_OFFSET         0x8000
2646 +
2647 +/* Compute the value for a GOTTPREL reloc.  */
2648 +#define TLS_TPREL_VALUE(sym_map, sym) \
2649 +  ((sym_map)->l_tls_offset + (sym)->st_value - TLS_TP_OFFSET)
2650 +
2651 +/* Compute the value for a DTPREL reloc.  */
2652 +#define TLS_DTPREL_VALUE(sym) \
2653 +  ((sym)->st_value - TLS_DTV_OFFSET)
2654 +
2655 +extern void *__tls_get_addr (tls_index *ti);
2656 +
2657 +# define GET_ADDR_OFFSET       (ti->ti_offset + TLS_DTV_OFFSET)
2658 +# define __TLS_GET_ADDR(__ti)  (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
2659 +
2660 +/* Value used for dtv entries for which the allocation is delayed.  */
2661 +#define TLS_DTV_UNALLOCATED    ((void *) -1l)
2662 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-trampoline.c b/glibc-2.14.1/sysdeps/riscv/dl-trampoline.c
2663 new file mode 100644
2664 index 0000000..70b5968
2665 --- /dev/null
2666 +++ glibc-2.14.1/sysdeps/riscv/dl-trampoline.c
2667 @@ -0,0 +1,104 @@
2668 +/* PLT trampoline.  MIPS version.
2669 +   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005
2670 +   Free Software Foundation, Inc.
2671 +   This file is part of the GNU C Library.
2672 +   Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
2673 +
2674 +   The GNU C Library is free software; you can redistribute it and/or
2675 +   modify it under the terms of the GNU Lesser General Public
2676 +   License as published by the Free Software Foundation; either
2677 +   version 2.1 of the License, or (at your option) any later version.
2678 +
2679 +   The GNU C Library is distributed in the hope that it will be useful,
2680 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
2681 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2682 +   Lesser General Public License for more details.
2683 +
2684 +   You should have received a copy of the GNU Lesser General Public
2685 +   License along with the GNU C Library; if not, write to the Free
2686 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2687 +   02111-1307 USA.  */
2688 +
2689 +/*  FIXME: Profiling of shared libraries is not implemented yet.  */
2690 +
2691 +#include <sysdep.h>
2692 +#include <link.h>
2693 +#include <elf.h>
2694 +#include <ldsodefs.h>
2695 +#include <dl-machine.h>
2696 +
2697 +/* The flag _dl_mips_gnu_objects is set if all dynamic objects are
2698 +   generated by the gnu linker. */
2699 +int _dl_mips_gnu_objects = 1;
2700 +
2701 +/* Get link map for callers object containing STUB_PC.  */
2702 +static inline struct link_map *
2703 +elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
2704 +{
2705 +  /* got[1] is reserved to keep its link map address for the shared
2706 +     object generated by the gnu linker.  If all are such objects, we
2707 +     can find the link map from current GPREG simply.  If not so, get
2708 +     the link map for caller's object containing STUB_PC.  */
2709 +
2710 +  if (_dl_mips_gnu_objects)
2711 +    {
2712 +      ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg);
2713 +      ElfW(Word) g1;
2714 +
2715 +      g1 = ((ElfW(Word) *) got)[1];
2716 +
2717 +      if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
2718 +       {
2719 +         struct link_map *l =
2720 +           (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
2721 +         ElfW(Addr) base, limit;
2722 +         const ElfW(Phdr) *p = l->l_phdr;
2723 +         ElfW(Half) this, nent = l->l_phnum;
2724 +
2725 +         /* For the common case of a stub being called from the containing
2726 +            object, STUB_PC will point to somewhere within the object that
2727 +            is described by the link map fetched via got[1].  Otherwise we
2728 +            have to scan all maps.  */
2729 +         for (this = 0; this < nent; this++)
2730 +           {
2731 +             if (p[this].p_type == PT_LOAD)
2732 +               {
2733 +                 base = p[this].p_vaddr + l->l_addr;
2734 +                 limit = base + p[this].p_memsz;
2735 +                 if (stub_pc >= base && stub_pc < limit)
2736 +                   return l;
2737 +               }
2738 +           }
2739 +       }
2740 +    }
2741 +
2742 +    struct link_map *l;
2743 +    Lmid_t nsid;
2744 +
2745 +    for (nsid = 0; nsid < DL_NNS; ++nsid)
2746 +      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
2747 +       {
2748 +         ElfW(Addr) base, limit;
2749 +         const ElfW(Phdr) *p = l->l_phdr;
2750 +         ElfW(Half) this, nent = l->l_phnum;
2751 +
2752 +         for (this = 0; this < nent; ++this)
2753 +           {
2754 +             if (p[this].p_type == PT_LOAD)
2755 +               {
2756 +                 base = p[this].p_vaddr + l->l_addr;
2757 +                 limit = base + p[this].p_memsz;
2758 +                 if (stub_pc >= base && stub_pc < limit)
2759 +                   return l;
2760 +               }
2761 +           }
2762 +       }
2763 +
2764 +  _dl_signal_error (0, NULL, NULL, "cannot find runtime link map");
2765 +  return NULL;
2766 +}
2767 +
2768 +void _dl_runtime_resolve(void)
2769 +{
2770 +  while (1);
2771 +}
2772 diff --git a/glibc-2.14.1/sysdeps/riscv/elf/configure b/glibc-2.14.1/sysdeps/riscv/elf/configure
2773 new file mode 100644
2774 index 0000000..63368b7
2775 --- /dev/null
2776 +++ glibc-2.14.1/sysdeps/riscv/elf/configure
2777 @@ -0,0 +1,126 @@
2778 +
2779 +# as_fn_set_status STATUS
2780 +# -----------------------
2781 +# Set $? to STATUS, without forking.
2782 +as_fn_set_status ()
2783 +{
2784 +  return $1
2785 +} # as_fn_set_status
2786 +
2787 +# as_fn_exit STATUS
2788 +# -----------------
2789 +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
2790 +as_fn_exit ()
2791 +{
2792 +  set +e
2793 +  as_fn_set_status $1
2794 +  exit $1
2795 +} # as_fn_exit
2796 +if expr a : '\(a\)' >/dev/null 2>&1 &&
2797 +   test "X`expr 00001 : '.*\(...\)'`" = X001; then
2798 +  as_expr=expr
2799 +else
2800 +  as_expr=false
2801 +fi
2802 +
2803 +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
2804 +  as_basename=basename
2805 +else
2806 +  as_basename=false
2807 +fi
2808 +
2809 +as_me=`$as_basename -- "$0" ||
2810 +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
2811 +        X"$0" : 'X\(//\)$' \| \
2812 +        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
2813 +$as_echo X/"$0" |
2814 +    sed '/^.*\/\([^/][^/]*\)\/*$/{
2815 +           s//\1/
2816 +           q
2817 +         }
2818 +         /^X\/\(\/\/\)$/{
2819 +           s//\1/
2820 +           q
2821 +         }
2822 +         /^X\/\(\/\).*/{
2823 +           s//\1/
2824 +           q
2825 +         }
2826 +         s/.*/./; q'`
2827 +
2828 +
2829 +  as_lineno_1=$LINENO as_lineno_1a=$LINENO
2830 +  as_lineno_2=$LINENO as_lineno_2a=$LINENO
2831 +  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
2832 +  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
2833 +  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
2834 +  sed -n '
2835 +    p
2836 +    /[$]LINENO/=
2837 +  ' <$as_myself |
2838 +    sed '
2839 +      s/[$]LINENO.*/&-/
2840 +      t lineno
2841 +      b
2842 +      :lineno
2843 +      N
2844 +      :loop
2845 +      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
2846 +      t loop
2847 +      s/-\n.*//
2848 +    ' >$as_me.lineno &&
2849 +  chmod +x "$as_me.lineno" ||
2850 +    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
2851 +
2852 +  # Don't try to exec as it changes $[0], causing all sort of problems
2853 +  # (the dirname of $[0] is not the place where we might find the
2854 +  # original and so on.  Autoconf is especially sensitive to this).
2855 +  . "./$as_me.lineno"
2856 +  # Exit status is that of the last command.
2857 +  exit
2858 +}
2859 +
2860 +# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
2861 + # Local configure fragment for sysdeps/mips/elf.
2862 +
2863 +if test "$usetls" != no; then
2864 +# Check for support of thread-local storage handling in assembler and
2865 +# linker.
2866 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MIPS TLS support" >&5
2867 +$as_echo_n "checking for MIPS TLS support... " >&6; }
2868 +if ${libc_cv_mips_tls+:} false; then :
2869 +  $as_echo_n "(cached) " >&6
2870 +else
2871 +  cat > conftest.s <<\EOF
2872 +       .section ".tdata", "awT", %progbits
2873 +       .globl foo
2874 +foo:   .long   1
2875 +       .section ".tbss", "awT", %nobits
2876 +       .globl bar
2877 +bar:   .skip   4
2878 +       .text
2879 +
2880 +       la              v0, __tls_get_addr
2881 +       la.tls.gd       a0, x
2882 +       jalr            v0
2883 +EOF
2884 +if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
2885 +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
2886 +  (eval $ac_try) 2>&5
2887 +  ac_status=$?
2888 +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
2889 +  test $ac_status = 0; }; }; then
2890 +  libc_cv_mips_tls=yes
2891 +else
2892 +  libc_cv_mips_tls=no
2893 +fi
2894 +rm -f conftest*
2895 +fi
2896 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_tls" >&5
2897 +$as_echo "$libc_cv_mips_tls" >&6; }
2898 +if test $libc_cv_mips_tls = yes; then
2899 +  $as_echo "#define HAVE_TLS_SUPPORT 1" >>confdefs.h
2900 +
2901 +fi
2902 +fi
2903 +
2904 diff --git a/glibc-2.14.1/sysdeps/riscv/elf/configure.in b/glibc-2.14.1/sysdeps/riscv/elf/configure.in
2905 new file mode 100644
2906 index 0000000..92966b4
2907 --- /dev/null
2908 +++ glibc-2.14.1/sysdeps/riscv/elf/configure.in
2909 @@ -0,0 +1,35 @@
2910 +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
2911 +# Local configure fragment for sysdeps/mips/elf.
2912 +
2913 +if test "$usetls" != no; then
2914 +# Check for support of thread-local storage handling in assembler and
2915 +# linker.
2916 +AC_CACHE_CHECK(for MIPS TLS support, libc_cv_mips_tls, [dnl
2917 +cat > conftest.s <<\EOF
2918 +       .section ".tdata", "awT", %progbits
2919 +       .globl foo
2920 +foo:   .long   1
2921 +       .section ".tbss", "awT", %nobits
2922 +       .globl bar
2923 +bar:   .skip   4
2924 +       .text
2925 +
2926 +       la              v0, __tls_get_addr
2927 +       la.tls.gd       a0, x
2928 +       jalr            v0
2929 +EOF
2930 +dnl
2931 +if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
2932 +  libc_cv_mips_tls=yes
2933 +else
2934 +  libc_cv_mips_tls=no
2935 +fi
2936 +rm -f conftest*])
2937 +if test $libc_cv_mips_tls = yes; then
2938 +  AC_DEFINE(HAVE_TLS_SUPPORT)
2939 +fi
2940 +fi
2941 +
2942 +dnl No MIPS GCC supports accessing static and hidden symbols in an
2943 +dnl position independent way.
2944 +dnl AC_DEFINE(PI_STATIC_AND_HIDDEN)
2945 diff --git a/glibc-2.14.1/sysdeps/riscv/elf/start.S b/glibc-2.14.1/sysdeps/riscv/elf/start.S
2946 new file mode 100644
2947 index 0000000..49b469c
2948 --- /dev/null
2949 +++ glibc-2.14.1/sysdeps/riscv/elf/start.S
2950 @@ -0,0 +1,98 @@
2951 +/* Startup code compliant to the ELF Mips ABI.
2952 +   Copyright (C) 1995, 1997, 2000, 2001, 2002, 2003, 2004
2953 +       Free Software Foundation, Inc.
2954 +   This file is part of the GNU C Library.
2955 +
2956 +   The GNU C Library is free software; you can redistribute it and/or
2957 +   modify it under the terms of the GNU Lesser General Public
2958 +   License as published by the Free Software Foundation; either
2959 +   version 2.1 of the License, or (at your option) any later version.
2960 +
2961 +   In addition to the permissions in the GNU Lesser General Public
2962 +   License, the Free Software Foundation gives you unlimited
2963 +   permission to link the compiled version of this file with other
2964 +   programs, and to distribute those programs without any restriction
2965 +   coming from the use of this file. (The GNU Lesser General Public
2966 +   License restrictions do apply in other respects; for example, they
2967 +   cover modification of the file, and distribution when not linked
2968 +   into another program.)
2969 +
2970 +   Note that people who make modified versions of this file are not
2971 +   obligated to grant this special exception for their modified
2972 +   versions; it is their choice whether to do so. The GNU Lesser
2973 +   General Public License gives permission to release a modified
2974 +   version without this exception; this exception also makes it
2975 +   possible to release a modified version which carries forward this
2976 +   exception.
2977 +
2978 +   The GNU C Library is distributed in the hope that it will be useful,
2979 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
2980 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2981 +   Lesser General Public License for more details.
2982 +
2983 +   You should have received a copy of the GNU Lesser General Public
2984 +   License along with the GNU C Library; if not, write to the Free
2985 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2986 +   02111-1307 USA.  */
2987 +
2988 +#define __ASSEMBLY__ 1
2989 +#include <entry.h>
2990 +#include <sgidefs.h>
2991 +#include <sys/asm.h>
2992 +
2993 +#ifndef ENTRY_POINT
2994 +#error ENTRY_POINT needs to be defined for start.S on MIPS/ELF.
2995 +#endif
2996 +
2997 +/* This is the canonical entry point, usually the first thing in the text
2998 +   segment.  The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry
2999 +   point runs, most registers' values are unspecified, except for:
3000 +
3001 +   v0 ($2)     Contains a function pointer to be registered with `atexit'.
3002 +               This is how the dynamic linker arranges to have DT_FINI
3003 +               functions called for shared libraries that have been loaded
3004 +               before this code runs.
3005 +
3006 +   sp ($29)    The stack contains the arguments and environment:
3007 +               0(%esp)                 argc
3008 +               4(%esp)                 argv[0]
3009 +               ...
3010 +               (4*argc)(%esp)          NULL
3011 +               (4*(argc+1))(%esp)      envp[0]
3012 +               ...
3013 +                                       NULL
3014 +   ra ($31)    The return address register is set to zero so that programs
3015 +               that search backword through stack frames recognize the last
3016 +               stack frame.
3017 +*/
3018 +
3019 +
3020 +/* We need to call:
3021 +   __libc_start_main (int (*main) (int, char **, char **), int argc,
3022 +                     char **argv, void (*init) (void), void (*fini) (void),
3023 +                     void (*rtld_fini) (void), void *stack_end)
3024 +*/
3025 +       
3026 +       .text
3027 +       .globl ENTRY_POINT
3028 +       .type ENTRY_POINT,@function
3029 +ENTRY_POINT:
3030 +       la    a0, main
3031 +       REG_L a1, 0(sp)      /* argc */
3032 +       addi  a2, sp, SZREG  /* argv */
3033 +       andi  sp, sp, ALMASK /* Align stack. */
3034 +       la    a3, __libc_csu_init
3035 +       la    a4, __libc_csu_fini
3036 +       move  a5, v0  /* rtld_fini */
3037 +       move  a6, sp  /* stack_end */
3038 +       
3039 +       la    v0, __libc_start_main
3040 +       jr    v0
3041 +
3042 +/* Define a symbol for the first piece of initialized data.  */
3043 +       .data
3044 +       .globl __data_start
3045 +__data_start:
3046 +       .long 0
3047 +       .weak data_start
3048 +       data_start = __data_start
3049 diff --git a/glibc-2.14.1/sysdeps/riscv/fpu/bits/mathinline.h b/glibc-2.14.1/sysdeps/riscv/fpu/bits/mathinline.h
3050 new file mode 100644
3051 index 0000000..dfb033a
3052 --- /dev/null
3053 +++ glibc-2.14.1/sysdeps/riscv/fpu/bits/mathinline.h
3054 @@ -0,0 +1,52 @@
3055 +/* Inline math functions for RISC-V.
3056 +   Copyright (C) 2011
3057 +   Free Software Foundation, Inc.
3058 +   This file is part of the GNU C Library.
3059 +   Contributed by Jakub Jelinek <jakub@redhat.com>.
3060 +
3061 +   The GNU C Library is free software; you can redistribute it and/or
3062 +   modify it under the terms of the GNU Lesser General Public
3063 +   License as published by the Free Software Foundation; either
3064 +   version 2.1 of the License, or (at your option) any later version.
3065 +
3066 +   The GNU C Library is distributed in the hope that it will be useful,
3067 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
3068 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3069 +   Lesser General Public License for more details.
3070 +
3071 +   You should have received a copy of the GNU Lesser General Public
3072 +   License along with the GNU C Library; if not, write to the Free
3073 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3074 +   02111-1307 USA.  */
3075 +
3076 +#ifndef _MATH_H
3077 +# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
3078 +#endif
3079 +
3080 +#include <bits/wordsize.h>
3081 +
3082 +#ifdef __GNUC__
3083 +
3084 +#if defined __USE_ISOC99
3085 +# undef isgreater
3086 +# undef isgreaterequal
3087 +# undef isless
3088 +# undef islessequal
3089 +# undef islessgreater
3090 +# undef isunordered
3091 +
3092 +# define isgreater(x, y) ((x) > (y))
3093 +# define isgreaterequal(x, y) ((x) >= (y))
3094 +# define isless(x, y) ((x) < (y))
3095 +# define islessequal(x, y) ((x) <= (y))
3096 +# define islessgreater(x, y) (!!(isless(x, y) + isgreater(x, y)))
3097 +# define isunordered(x, y) (((x) == (x)) + ((y) == (y)) < 2)
3098 +
3099 +#endif /* __USE_ISOC99 */
3100 +
3101 +#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) && defined __OPTIMIZE__
3102 +
3103 +/* Nothing yet. */
3104 +
3105 +#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
3106 +#endif /* __GNUC__ */
3107 diff --git a/glibc-2.14.1/sysdeps/riscv/fpu/e_sqrt.c b/glibc-2.14.1/sysdeps/riscv/fpu/e_sqrt.c
3108 new file mode 100644
3109 index 0000000..f956945
3110 --- /dev/null
3111 +++ glibc-2.14.1/sysdeps/riscv/fpu/e_sqrt.c
3112 @@ -0,0 +1,26 @@
3113 +/* Copyright (C) 2002 Free Software Foundation, Inc.
3114 +   This file is part of the GNU C Library.
3115 +   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
3116 +
3117 +   The GNU C Library is free software; you can redistribute it and/or
3118 +   modify it under the terms of the GNU Lesser General Public
3119 +   License as published by the Free Software Foundation; either
3120 +   version 2.1 of the License, or (at your option) any later version.
3121 +
3122 +   The GNU C Library is distributed in the hope that it will be useful,
3123 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
3124 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3125 +   Lesser General Public License for more details.
3126 +
3127 +   You should have received a copy of the GNU Lesser General Public
3128 +   License along with the GNU C Library; if not, write to the Free
3129 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3130 +   02111-1307 USA.  */