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