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