added and removed uclibc patches

This commit is contained in:
John Voltz 2008-03-06 18:50:01 +00:00
parent f7e1c58a6c
commit 3ab16b1fd6
17 changed files with 12531 additions and 233 deletions

View file

@ -10,7 +10,7 @@ choice
Select the version of uClibc you wish to use.
config BR2_UCLIBC_VERSION_0_9_28_3
depends !BR2_avr32 && BR2_DEPRECATED
depends BR2_DEPRECATED
bool "uClibc 0.9.28.3"
depends BR2_EXT_UCLIBC_VERSION_0_9_28_3
@ -19,7 +19,6 @@ choice
depends BR2_EXT_UCLIBC_VERSION_0_9_29
config BR2_UCLIBC_VERSION_SNAPSHOT
depends !BR2_avr32
bool "daily snapshot"
endchoice

View file

@ -0,0 +1,215 @@
uClibc and Glibc are not the same -- there are a number of differences which
may or may not cause you problems. This document attempts to list these
differences and, when completed, will contain a full list of all relevant
differences.
1) uClibc is smaller than glibc. We attempt to maintain a glibc compatible
interface, allowing applications that compile with glibc to easily compile with
uClibc. However, we do not include _everything_ that glibc includes, and
therefore some applications may not compile. If this happens to you, please
report the failure to the uclibc mailing list, with detailed error messages.
2) uClibc is much more configurable then glibc. This means that a developer
may have compiled uClibc in such a way that significant amounts of
functionality have been omitted.
3) uClibc does not even attempt to ensure binary compatibility across releases.
When a new version of uClibc is released, you may or may not need to recompile
all your binaries.
4) malloc(0) in glibc returns a valid pointer to something(!?!?) while in
uClibc calling malloc(0) returns a NULL. The behavior of malloc(0) is listed
as implementation-defined by SuSv3, so both libraries are equally correct.
This difference also applies to realloc(NULL, 0). I personally feel glibc's
behavior is not particularly safe. To enable glibc behavior, one has to
explicitly enable the MALLOC_GLIBC_COMPAT option.
4.1) glibc's malloc() implementation has behavior that is tunable via the
MALLOC_CHECK_ environment variable. This is primarily used to provide extra
malloc debugging features. These extended malloc debugging features are not
available within uClibc. There are many good malloc debugging libraries
available for Linux (dmalloc, electric fence, valgrind, etc) that work much
better than the glibc extended malloc debugging. So our omitting this
functionality from uClibc is not a great loss.
5) uClibc does not provide a database library (libdb).
6) uClibc does not support NSS (/lib/libnss_*), which allows glibc to easily
support various methods of authentication and DNS resolution. uClibc only
supports flat password files and shadow password files for storing
authentication information. If you need something more complex than this,
you can compile and install pam.
7) uClibc's libresolv is only a stub. Some, but not all of the functionality
provided by glibc's libresolv is provided internal to uClibc. Other functions
are not at all implemented.
8) libnsl provides support for Network Information Service (NIS) which was
originally called "Yellow Pages" or "YP", which is an extension of RPC invented
by Sun to share Unix password files over the network. I personally think NIS
is an evil abomination and should not be used. These days, using ldap is much
more effective mechanism for doing the same thing. uClibc provides a stub
libnsl, but has no actual support for Network Information Service (NIS).
We therefore, also do not provide any of the headers files provided by glibc
under /usr/include/rpcsvc.
9) uClibc's locale support is not 100% complete yet. We are working on it.
10) uClibc's math library only supports long double as inlines, and even
then the long double support is quite limited. Also, very few of the
float math functions are implemented. Stick with double and you should
be just fine.
11) uClibc's libcrypt does not support the reentrant crypt_r, setkey_r and
encrypt_r, since these are not required by SuSv3.
12) uClibc directly uses kernel types to define most opaque data types.
13) uClibc directly uses the linux kernel's arch specific 'stuct stat'.
14) uClibc's librt library currently lacks all aio routines, all clock
routines, and all shm routines (only the timer routines and the mq
routines are implemented).
<other things as we notice them>
****************************** Manuel's Notes ******************************
Some general comments...
The intended target for all my uClibc code is ANSI/ISO C99 and SUSv3
compliance. While some glibc extensions are present, many will eventually
be configurable. Also, even when present, the glibc-like extensions may
differ slightly or be more restrictive than the native glibc counterparts.
They are primarily meant to be porting _aides_ and not necessarily
drop-in replacements.
Now for some details...
time functions
--------------
1) Leap seconds are not supported.
2) /etc/timezone and the whole zoneinfo directory tree are not supported.
To set the timezone, set the TZ environment variable as specified in
http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html
or you may also create an /etc/TZ file of a single line, ending with a
newline, containing the TZ setting. For example
echo CST6CDT > /etc/TZ
3) Currently, locale specific eras and alternate digits are not supported.
They are on my TODO list.
wide char support
-----------------
1) The only multibyte encoding currently supported is UTF-8. The various
ISO-8859-* encodings are (optionally) supported. The internal
representation of wchar's is assumed to be 31 bit unicode values in
native endian representation. Also, the underlying char encoding is
assumed to match ASCII in the range 0-0x7f.
2) In the next iteration of locale support, I plan to add support for
(at least some) other multibyte encodings.
locale support
--------------
1) The target for support is SUSv3 locale functionality. While nl_langinfo
has been extended, similar to glibc, it only returns values for related
locale entries.
2) Currently, all SUSv3 libc locale functionality should be implemented
except for wcsftime and collating item support in regex.
stdio
-----
1) Conversion of large magnitude floating-point values by printf suffers a loss
of precision due to the algorithm used.
2) uClibc's printf is much stricter than glibcs, especially regarding positional
args. The entire format string is parsed first and an error is returned if
a problem is detected. In locales other than C, the format string is checked
to be a valid multibyte sequence as well. Also, currently at most 10 positional
args are allowed (although this is configurable).
3) BUFSIZ is configurable, but no attempt is made at automatic tuning of internal
buffer sizes for stdio streams. In fact, the stdio code in general sacrifices
sophistication/performace for minimal size.
4) uClibc allows glibc-like custom printf functions. However, while not
currently checked, the specifier must be <= 0x7f.
5) uClibc allows glibc-like custom streams. However, no in-buffer seeking is
done.
6) The functions fcloseall() and __fpending() can behave differently than their
glibc counterparts.
7) uClibc's setvbuf is more restrictive about when it can be called than glibc's
is. The standards specify that setvbuf must occur before any other operations
take place on the stream.
8) Right now, %m is not handled properly by printf when the format uses positional
args.
9) The FILEs created by glibc's fmemopen(), open_memstream(), and fopencookie()
are not capable of wide orientation. The corresponding uClibc routines do
not have this limitation.
10) For scanf, the C99 standard states "The fscanf function returns the value of
the macro EOF if an input failure occurs before any conversion." But glibc's
scanf does not respect conversions for which assignment was surpressed, even
though the standard states that the value is converted but not stored.
glibc bugs that Ulrich Drepper has refused to acknowledge or comment on
( http://sources.redhat.com/ml/libc-alpha/2003-09/ )
-----------------------------------------------------------------------
1) The C99 standard says that for printf, a %s conversion makes no special
provisions for multibyte characters. SUSv3 is even more clear, stating
that bytes are written and a specified precision is in bytes. Yet glibc
treats the arg as a multibyte string when a precision is specified and
not otherwise.
2) Both C99 and C89 state that the %c conversion for scanf reads the exact
number of bytes specified by the optional field width (or 1 if not specified).
uClibc complies with the standard. There is an argument that perhaps the
specified width should be treated as an upper bound, based on some historical
use. However, such behavior should be mentioned in the Conformance document.
3) glibc's scanf is broken regarding some numeric patterns. Some invalid
strings are accepted as valid ("0x.p", "1e", digit grouped strings).
In spite of my posting examples clearly illustrating the bugs, they remain
unacknowledged by the glibc developers.
4) glibc's scanf seems to require a 'p' exponent for hexadecimal float strings.
According to the standard, this is optional.
5) C99 requires that once an EOF is encountered, the stream should be treated
as if at end-of-file even if more data becomes available. Further reading
can be attempted by clearing the EOF flag though, via clearerr() or a file
positioning function. For details concerning the original change, see
Defect Report #141. glibc is currently non-compliant, and the developers
did not comment when I asked for their official position on this issue.
6) glibc's collation routines and/or localedef are broken regarding implicit
and explicit UNDEFINED rules.
More to follow as I think of it...
Profiling:
-------------------------------------------------------------------
uClibc no longer supports 'gcc -fprofile-arcs -pg' style profiling, which
causes your application to generate a 'gmon.out' file that can then be analyzed
by 'gprof'. Not only does this require explicit extra support in uClibc, it
requires that you rebuild everything with profiling support. There is both a
size and performance penalty to profiling your applications this way, as well
as Heisenberg effects, where the act of measuring changes what is measured.
There exist a number of less invasive alternatives that do not require you to
specially instrument your application, and recompile and relink everything.
The OProfile system-wide profiler is an excellent alternative:
http://oprofile.sourceforge.net/
Many people have had good results using the combination of Valgrind
to generate profiling information and KCachegrind for analysis:
http://developer.kde.org/~sewardj/
http://kcachegrind.sourceforge.net/
Prospect is another alternative based on OProfile:
http://prospect.sourceforge.net/
And the Linux Trace Toolkit (LTT) is also a fine tool:
http://www.opersys.com/LTT/
FunctionCheck:
http://www710.univ-lyon1.fr/~yperret/fnccheck/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,72 +1,3 @@
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f474699
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,63 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# Normal rules
+#
+.*
+*.o
+*.a
+*.so
+*.os
+*.oS
+.config*
+
+#
+# Top-level generic files
+#
+obj.*
+
+#
+# Generated files
+#
+extra/config/conf
+extra/config/lex.zconf.c
+extra/config/lkc_defs.h
+extra/config/mconf
+extra/config/zconf.hash.c
+extra/config/zconf.tab.c
+extra/config/zconf.tab.h
+
+lib
+
+include/asm
+include/asm-*
+include/bits
+include/linux
+
+include/sys/acct.h
+include/sys/elf.h
+include/sys/epoll.h
+include/sys/inotify.h
+include/sys/io.h
+include/sys/prctl.h
+include/sys/procfs.h
+include/sys/ptrace.h
+include/sys/ucontext.h
+include/sys/user.h
+
+include/dl-osinfo.h
+include/fpu_control.h
+include/hp-timing.h
+include/pthread.h
+include/semaphore.h
+include/thread_db.h
+
+ldso/include/dl-debug.h
+ldso/include/dl-startup.h
+ldso/include/dl-syscalls.h
+ldso/include/dl-sysdep.h
+ldso/include/elf.h
+
+libc/misc/internals/interp.c
diff --git a/Rules.mak b/Rules.mak
index d054bbb..55381cf 100644
--- a/Rules.mak
@ -900,6 +831,30 @@ index 5cf1d04..d4294ec 100644
/* OK, now do the relocations. We do not do a lazy binding here, so
that once we are done, we have considerably more flexibility. */
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index f4e6cac..9cdc3fe 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1643,7 +1643,7 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
*result=result_buf;
ret=NETDB_SUCCESS;
#ifdef __UCLIBC_HAS_IPV6__
- } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
+ } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
DPRINTF("Found INET6\n");
addr_list6[0] = in6;
addr_list6[1] = 0;
@@ -1658,8 +1658,8 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
} else {
DPRINTF("Error\n");
ret=TRY_AGAIN;
- break; /* bad ip address */
- }
+ continue; /* bad ip address, keep searching */
+ }
if (action!=GETHOSTENT) {
fclose(fp);
diff --git a/libc/string/avr32/Makefile b/libc/string/avr32/Makefile
new file mode 100644
index 0000000..e19e9d9
@ -994,10 +949,10 @@ index 0000000..c999e65
+#endif /* __UCLIBC_SUSV3_LEGACY__ */
diff --git a/libc/string/avr32/memcmp.S b/libc/string/avr32/memcmp.S
new file mode 100644
index 0000000..7359a64
index 0000000..ae6cc91
--- /dev/null
+++ b/libc/string/avr32/memcmp.S
@@ -0,0 +1,58 @@
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2007 Atmel Corporation
+ *
@ -1041,14 +996,17 @@ index 0000000..7359a64
+ retal 0
+
+.Lfound_word:
+ psub.b r9, r8, r9
+ bfextu r8, r9, 24, 8
+ retne r8
+ bfextu r8, r9, 16, 8
+ retne r8
+ bfextu r8, r9, 8, 8
+ retne r8
+ retal r9
+ mov len, 4
+
+2: bfextu r11, r9, 24, 8
+ bfextu r12, r8, 24, 8
+ sub r12, r11
+ retne r12
+ lsl r8, 8
+ lsl r9, 8
+ sub len, 1
+ brne 2b
+ retal r12
+
+ .size memcmp, . - memcmp
+
@ -2752,30 +2710,39 @@ index 0000000..ca1fa7a
+4: .align 4
diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
new file mode 100644
index 0000000..3e132d0
index 0000000..660f47c
--- /dev/null
+++ b/libc/sysdeps/linux/avr32/crti.S
@@ -0,0 +1,17 @@
@@ -0,0 +1,26 @@
+
+ .section .init
+ .align 2
+ .global _init
+ .type _init, @function
+_init:
+ /* Use a four-byte instruction to avoid NOPs */
+ stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
+ .align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
+
+ .section .fini
+ .align 2
+ .global _fini
+ .type _fini, @function
+_fini:
+ stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
+ .align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
new file mode 100644
index 0000000..577adcc
index 0000000..f7d1040
--- /dev/null
+++ b/libc/sysdeps/linux/avr32/crtn.S
@@ -0,0 +1,14 @@
@ -2784,14 +2751,14 @@ index 0000000..577adcc
+ .align 2
+ .global _init
+ .type _init, @function
+ ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
+ .size _init, . - _init
+
+ .section .fini
+ .align 2
+ .global _fini
+ .type _fini, @function
+ ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
+ .size _fini, . - _fini
diff --git a/libc/sysdeps/linux/avr32/mmap.c b/libc/sysdeps/linux/avr32/mmap.c
new file mode 100644
@ -3405,7 +3372,7 @@ index 0000000..03ca99f
+libc_hidden_weak(vfork)
diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
new file mode 100644
index 0000000..2e8a33b
index 0000000..eccf329
--- /dev/null
+++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
@@ -0,0 +1,73 @@
@ -3478,7 +3445,7 @@ index 0000000..2e8a33b
+ : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
+ : "cc", "memory");
+
+ return result;
+ return result == 0;
+}
+
+#endif /* pt-machine.h */

View file

@ -0,0 +1,31 @@
From 974a769cc135bcfb1ea751db34a84ed6b5ceb509 Mon Sep 17 00:00:00 2001
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Fri, 7 Dec 2007 14:02:19 +0100
Subject: [PATCH] AVR32: Fix sa_restorer when SA_ONSTACK is set
I don't remember exactly why we decided to pick the caller's value of
sa_restorer when SA_ONSTACK is set, but it seems to break LTP's
sigaltstack testcase. Some users have reported problems with
sigaltstack as well; hopefully this will fix it.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
libc/sysdeps/linux/avr32/sigaction.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c
index a97ff3d..6dcca91 100644
--- a/libc/sysdeps/linux/avr32/sigaction.c
+++ b/libc/sysdeps/linux/avr32/sigaction.c
@@ -30,7 +30,7 @@ int __libc_sigaction(int signum, const struct sigaction *act,
kact.k_sa_handler = act->sa_handler;
memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
kact.sa_flags = act->sa_flags;
- if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
+ if (kact.sa_flags & SA_RESTORER)
kact.sa_restorer = act->sa_restorer;
else
kact.sa_restorer = __default_rt_sa_restorer;
--
1.5.3.4

View file

@ -1,28 +0,0 @@
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Wed, 19 Sep 2007 10:03:36 +0200
Subject: [Avr-gnu-toolchain] [uClibc PATCH] Fix inverted logic in
__compare_and_swap in linuxthreads.old
If the old value equals the value in memory, the result should be
TRUE, not FALSE.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
.../linuxthreads.old/sysdeps/avr32/pt-machine.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
index 2e8a33b..eccf329 100644
--- a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
+++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
@@ -67,7 +67,7 @@ __compare_and_swap(long int *p, long int oldval, long int newval)
: "m"(*p), [new] "r"(newval), [old] "r"(oldval)
: "cc", "memory");
- return result;
+ return result == 0;
}
#endif /* pt-machine.h */
--
1.5.3.1

View file

@ -1,46 +0,0 @@
From 91cb4bb00e4d9463c0d41015152daa4b39acf762 Mon Sep 17 00:00:00 2001
From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
Date: Tue, 18 Sep 2007 10:15:05 +0200
Subject: [PATCH] Fix resolve when identical IPv4 and IPv6 hosts are defined in /etc/hosts
This patch will fix a problem when the same host is defined with both IPv4 and
IPv6 entries in /etc/hosts. Previous only the first of these host would work,
as uClibc would read the /etc/hosts file from top to bottom, failing if the
first hit did not match the IP type.
Now uClibc will continue reading, even if the first correct entry name, but wrong IP
type fails. Thus, allowing a second correct entry name with correct IP type
will result in a name resolve.
Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
---
libc/inet/resolv.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index f4e6cac..9cdc3fe 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1643,7 +1643,7 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
*result=result_buf;
ret=NETDB_SUCCESS;
#ifdef __UCLIBC_HAS_IPV6__
- } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
+ } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
DPRINTF("Found INET6\n");
addr_list6[0] = in6;
addr_list6[1] = 0;
@@ -1658,8 +1658,8 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
} else {
DPRINTF("Error\n");
ret=TRY_AGAIN;
- break; /* bad ip address */
- }
+ continue; /* bad ip address, keep searching */
+ }
if (action!=GETHOSTENT) {
fclose(fp);
--
1.5.2.5

View file

@ -0,0 +1,145 @@
--- a/libpthread/linuxthreads.old/attr.c 2006-01-24 12:41:01.000000000 -0500
+++ b/libpthread/linuxthreads.old/attr.c 2008-02-10 11:35:32.000000000 -0500
@@ -25,6 +25,14 @@
#include "pthread.h"
#include "internals.h"
+#include <sys/resource.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+
+
/* NOTE: With uClibc I don't think we need this versioning stuff.
* Therefore, define the function pthread_attr_init() here using
* a strong symbol. */
@@ -209,4 +217,94 @@ int __pthread_attr_getstacksize(const pt
*stacksize = attr->__stacksize;
return 0;
}
+
+
+extern int *__libc_stack_end;
+
weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
+void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
+{
+ static void *stackBase = 0;
+ static size_t stackSize = 0;
+ int ret = 0;
+ /* Stack size limit. */
+ struct rlimit rl;
+
+ /* The safest way to get the top of the stack is to read
+ /proc/self/maps and locate the line into which
+ __libc_stack_end falls. */
+ FILE *fp = fopen("/proc/self/maps", "rc");
+ if (fp == NULL)
+ ret = errno;
+ /* We need the limit of the stack in any case. */
+ else if (getrlimit (RLIMIT_STACK, &rl) != 0)
+ ret = errno;
+ else {
+ /* We need no locking. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ /* Until we found an entry (which should always be the case)
+ mark the result as a failure. */
+ ret = ENOENT;
+
+ char *line = NULL;
+ size_t linelen = 0;
+ uintptr_t last_to = 0;
+
+ while (! feof_unlocked (fp)) {
+ if (getdelim (&line, &linelen, '\n', fp) <= 0)
+ break;
+
+ uintptr_t from;
+ uintptr_t to;
+ if (sscanf (line, "%x-%x", &from, &to) != 2)
+ continue;
+ if (from <= (uintptr_t) __libc_stack_end
+ && (uintptr_t) __libc_stack_end < to) {
+ /* Found the entry. Now we have the info we need. */
+ attr->__stacksize = rl.rlim_cur;
+#ifdef _STACK_GROWS_UP
+ /* Don't check to enforce a limit on the __stacksize */
+ attr->__stackaddr = (void *) from;
+#else
+ attr->__stackaddr = (void *) to;
+
+ /* The limit might be too high. */
+ if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr - last_to)
+ attr->__stacksize = (size_t) attr->__stackaddr - last_to;
+#endif
+
+ /* We succeed and no need to look further. */
+ ret = 0;
+ break;
+ }
+ last_to = to;
+ }
+
+ fclose (fp);
+ free (line);
+ }
+#ifndef _STACK_GROWS_UP
+ stackBase = (char *) attr->__stackaddr - attr->__stacksize;
+#else
+ stackBase = attr->__stackaddr;
+#endif
+ stackSize = attr->__stacksize;
+ return (void*)(stackBase + stackSize);
+}
+
+int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
+ size_t *stacksize)
+{
+ /* XXX This function has a stupid definition. The standard specifies
+ no error value but what is if no stack address was set? We simply
+ return the value we have in the member. */
+#ifndef _STACK_GROWS_UP
+ *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
+#else
+ *stackaddr = attr->__stackaddr;
+#endif
+ *stacksize = attr->__stacksize;
+ return 0;
+}
+weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
--- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h 2006-12-07 22:19:36.000000000 -0500
+++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h 2008-02-10 11:42:35.000000000 -0500
@@ -288,15 +288,11 @@ extern int pthread_attr_getstacksize (__
__attr, size_t *__restrict __stacksize)
__THROW;
-#if 0
-/* Not yet implemented in uClibc! */
-
#ifdef __USE_GNU
/* Initialize thread attribute *ATTR with attributes corresponding to the
already running thread TH. It shall be called on unitialized ATTR
and destroyed with pthread_attr_destroy when no longer needed. */
-extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
-#endif
+extern void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
#endif
/* Functions for scheduling control. */
@@ -599,6 +595,11 @@ extern int pthread_cancel (pthread_t __c
cancelled. */
extern void pthread_testcancel (void);
+/* Return the previously set address for the stack. */
+extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
+ void **__restrict __stackaddr,
+ size_t *__restrict __stacksize) __THROW;
+
/* Install a cleanup handler: ROUTINE will be called with arguments ARG
when the thread is cancelled or calls pthread_exit. ROUTINE will also

View file

@ -1,68 +0,0 @@
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Wed, 19 Sep 2007 10:03:35 +0200
Subject: [Avr-gnu-toolchain] [uClibc PATCH] Load GOT pointer at the
beginning of .init and .fini
I don't know why this seems to have worked before, but the .init and
.fini sections typically consist of a bunch of mcalls using r6 as the
base pointer. This can cause "interesting" behaviour when r6 hasn't
been initialized to point to the GOT.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
libc/sysdeps/linux/avr32/crti.S | 15 ++++++++++++---
libc/sysdeps/linux/avr32/crtn.S | 4 ++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
index 3e132d0..660f47c 100644
--- a/libc/sysdeps/linux/avr32/crti.S
+++ b/libc/sysdeps/linux/avr32/crti.S
@@ -4,14 +4,23 @@
.global _init
.type _init, @function
_init:
- /* Use a four-byte instruction to avoid NOPs */
- stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
.align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
.section .fini
.align 2
.global _fini
.type _fini, @function
_fini:
- stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
.align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
index 577adcc..f7d1040 100644
--- a/libc/sysdeps/linux/avr32/crtn.S
+++ b/libc/sysdeps/linux/avr32/crtn.S
@@ -3,12 +3,12 @@
.align 2
.global _init
.type _init, @function
- ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
.size _init, . - _init
.section .fini
.align 2
.global _fini
.type _fini, @function
- ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
.size _fini, . - _fini
--
1.5.3.1