summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/lshift.S4
-rw-r--r--sysdeps/ia64/memchr.S8
-rw-r--r--sysdeps/mach/hurd/ttyname_r.c6
-rw-r--r--sysdeps/posix/cuserid.c5
-rw-r--r--sysdeps/s390/s390-64/utf16-utf32-z9.c11
-rw-r--r--sysdeps/s390/s390-64/utf8-utf16-z9.c9
-rw-r--r--sysdeps/unix/bsd/ptsname.c11
-rw-r--r--sysdeps/unix/getlogin.c9
-rw-r--r--sysdeps/unix/readdir_r.c14
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c14
-rw-r--r--sysdeps/unix/sysv/linux/i386/fallocate.c8
-rw-r--r--sysdeps/unix/sysv/linux/i386/fallocate64.c8
-rw-r--r--sysdeps/unix/sysv/linux/i386/readdir64_r.c3
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c55
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c2
-rw-r--r--sysdeps/x86_64/dl-machine.h4
-rw-r--r--sysdeps/x86_64/multiarch/init-arch.c33
-rw-r--r--sysdeps/x86_64/multiarch/init-arch.h4
19 files changed, 145 insertions, 65 deletions
diff --git a/sysdeps/i386/lshift.S b/sysdeps/i386/lshift.S
index 536d9878eb..398cf038c7 100644
--- a/sysdeps/i386/lshift.S
+++ b/sysdeps/i386/lshift.S
@@ -1,5 +1,5 @@
/* i80386 __mpn_lshift --
- Copyright (C) 1992, 1994, 1997-2000, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1992,1994,1997-2000,2005,2010 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
@@ -55,6 +55,7 @@ ENTRY (BP_SYM (__mpn_lshift))
movl (%esi,%edx,4),%ebx /* read most significant limb */
cfi_rel_offset (ebx, 0)
+ cfi_remember_state
xorl %eax,%eax
shldl %cl,%ebx,%eax /* compute carry limb */
decl %edx
@@ -95,6 +96,7 @@ L(1): movl (%esi,%edx,4),%eax
LEAVE
ret
+ cfi_restore_state
L(end): shll %cl,%ebx /* compute least significant limb */
movl %ebx,(%edi) /* store it */
diff --git a/sysdeps/ia64/memchr.S b/sysdeps/ia64/memchr.S
index cdd71ca5a5..56d8056839 100644
--- a/sysdeps/ia64/memchr.S
+++ b/sysdeps/ia64/memchr.S
@@ -47,7 +47,7 @@
#define saved_lc r16
#define chr r17
#define len r18
-#define pos0 r20
+#define last r20
#define val r21
#define tmp r24
#define chrx8 r25
@@ -67,6 +67,7 @@ ENTRY(__memchr)
mov saved_pr = pr // save the predicates
.body
mov ret0 = str
+ add last = str, in2 // last byte
and tmp = 7, str // tmp = str % 8
cmp.ne p7, p0 = r0, r0 // clear p7
extr.u chr = in1, 0, 8 // chr = (unsigned char) in1
@@ -143,7 +144,10 @@ ENTRY(__memchr)
ld8 tmp = [ret0];; // load the first unchecked 8byte
xor aux[1] = tmp, chrx8;;
czx1.r poschr[1] = aux[1];;
- cmp.ne p7, p0 = 8, poschr[1]
+ cmp.ne p7, p0 = 8, poschr[1];;
+(p7) add ret0 = addr[MEMLAT+2], poschr[1];;
+(p7) cmp.geu p6, p7 = ret0, last // don't go over the last byte
+(p6) br.cond.spnt .notfound;;
(p7) br.cond.spnt .foundit;;
adds ret0 = 8, ret0 // load the next unchecked 8byte
br.sptk .l4;;
diff --git a/sysdeps/mach/hurd/ttyname_r.c b/sysdeps/mach/hurd/ttyname_r.c
index 7313b9afcb..8896252246 100644
--- a/sysdeps/mach/hurd/ttyname_r.c
+++ b/sysdeps/mach/hurd/ttyname_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 95, 96, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1994,1995,1996,1998,2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -34,13 +34,13 @@ __ttyname_r (int fd, char *buf, size_t buflen)
nodename[0] = '\0';
if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename)))
- return __hurd_dfail (fd, err), -1;
+ return __hurd_dfail (fd, err), errno;
len = strlen (nodename) + 1;
if (len > buflen)
{
errno = EINVAL;
- return -1;
+ return errno;
}
memcpy (buf, nodename, len);
diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c
index 11c827a686..a74ff84368 100644
--- a/sysdeps/posix/cuserid.c
+++ b/sysdeps/posix/cuserid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1998, 1999, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1998, 1999, 2001, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -44,5 +44,6 @@ cuserid (s)
if (s == NULL)
s = name;
- return strncpy (s, pwptr->pw_name, L_cuserid);
+ s[L_cuserid - 1] = '\0';
+ return strncpy (s, pwptr->pw_name, L_cuserid - 1);
}
diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c
index 868dea68ca..14daf2118f 100644
--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c
+++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c
@@ -203,7 +203,10 @@ gconv_end (struct __gconv_step *data)
swapping). */
#define BODY \
{ \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
+ /* The hardware instruction currently fails to report an error for \
+ isolated low surrogates so we have to disable the instruction \
+ until this gets resolved. */ \
+ if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \
{ \
HARDWARE_CONVERT ("cu24 %0, %1, 1"); \
if (inptr != inend) \
@@ -229,6 +232,12 @@ gconv_end (struct __gconv_step *data)
} \
else \
{ \
+ /* An isolated low-surrogate was found. This has to be \
+ considered ill-formed. */ \
+ if (__builtin_expect (u1 >= 0xdc00, 0)) \
+ { \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ } \
/* It's a surrogate character. At least the first word says \
it is. */ \
if (__builtin_expect (inptr + 4 > inend, 0)) \
diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c
index 531d3ebd4b..5f73f3c59e 100644
--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c
+++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c
@@ -345,9 +345,12 @@ gconv_end (struct __gconv_step *data)
Operation. */
#define BODY \
{ \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
+ /* The hardware instruction currently fails to report an error for \
+ isolated low surrogates so we have to disable the instruction \
+ until this gets resolved. */ \
+ if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \
{ \
- HARDWARE_CONVERT ("cu21 %0, %1"); \
+ HARDWARE_CONVERT ("cu21 %0, %1, 1"); \
if (inptr != inend) \
{ \
/* Check if the third byte is \
@@ -388,7 +391,7 @@ gconv_end (struct __gconv_step *data)
\
outptr += 2; \
} \
- else if (c >= 0x0800 && c <= 0xd7ff) \
+ else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \
{ \
/* Three byte UTF-8 char. */ \
\
diff --git a/sysdeps/unix/bsd/ptsname.c b/sysdeps/unix/bsd/ptsname.c
index fd446a4b66..6063201b0f 100644
--- a/sysdeps/unix/bsd/ptsname.c
+++ b/sysdeps/unix/bsd/ptsname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1998,2002,2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -44,6 +44,7 @@ int
__ptsname_r (int fd, char *buf, size_t buflen)
{
int save_errno = errno;
+ int err;
struct stat st;
if (buf == NULL)
@@ -62,8 +63,12 @@ __ptsname_r (int fd, char *buf, size_t buflen)
return ERANGE;
}
- if (__ttyname_r (fd, buf, buflen) != 0)
- return errno;
+ err = __ttyname_r (fd, buf, buflen);
+ if (err != 0)
+ {
+ __set_errno (err);
+ return errno;
+ }
buf[sizeof (_PATH_DEV) - 1] = 't';
diff --git a/sysdeps/unix/getlogin.c b/sysdeps/unix/getlogin.c
index 4752685f86..7345af0886 100644
--- a/sysdeps/unix/getlogin.c
+++ b/sysdeps/unix/getlogin.c
@@ -33,6 +33,7 @@ getlogin (void)
{
char tty_pathname[2 + 2 * NAME_MAX];
char *real_tty_path = tty_pathname;
+ int err;
char *result = NULL;
static char name[UT_NAMESIZE + 1];
struct utmp *ut, line, buffer;
@@ -46,8 +47,12 @@ getlogin (void)
thing to do. Note that ttyname(open("/dev/tty")) on those
systems returns /dev/tty, so that is not a possible solution for
getlogin(). */
- if (__ttyname_r (0, real_tty_path, sizeof (tty_pathname)) != 0)
- return NULL;
+ err = __ttyname_r (0, real_tty_path, sizeof (tty_pathname));
+ if (err != 0)
+ {
+ __set_errno (err);
+ return NULL;
+ }
real_tty_path += 5; /* Remove "/dev/". */
diff --git a/sysdeps/unix/readdir_r.c b/sysdeps/unix/readdir_r.c
index f84709e737..93727912c1 100644
--- a/sysdeps/unix/readdir_r.c
+++ b/sysdeps/unix/readdir_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,02
+/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,02,10
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -113,7 +113,17 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
while (dp->d_ino == 0);
if (dp != NULL)
- *result = memcpy (entry, dp, reclen);
+ {
+#ifdef GETDENTS_64BIT_ALIGNED
+ /* The d_reclen value might include padding which is not part of
+ the DIRENT_TYPE data structure. */
+ reclen = MIN (reclen, sizeof (DIRENT_TYPE));
+#endif
+ *result = memcpy (entry, dp, reclen);
+#ifdef GETDENTS_64BIT_ALIGNED
+ entry->d_reclen = reclen;
+#endif
+ }
else
*result = NULL;
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 97e20d249b..af454b650d 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -1,5 +1,5 @@
/* Determine various system internal values, Linux version.
- Copyright (C) 1996-2003, 2006, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1996-2003,2006,2007,2009,2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -117,18 +117,6 @@ next_line (int fd, char *const buffer, char **cp, char **re,
if (nl == NULL)
nl = *re - 1;
}
- else if (nl + 5 >= *re)
- {
- memmove (buffer, nl, *re - nl);
- *re = buffer + (*re - nl);
- nl = *cp = buffer;
-
- ssize_t n = read_not_cancel (fd, *re, buffer_end - *re);
- if (n < 0)
- return NULL;
-
- *re += n;
- }
*cp = nl + 1;
assert (*cp <= *re);
diff --git a/sysdeps/unix/sysv/linux/i386/fallocate.c b/sysdeps/unix/sysv/linux/i386/fallocate.c
index 14e788386c..1434a833f9 100644
--- a/sysdeps/unix/sysv/linux/i386/fallocate.c
+++ b/sysdeps/unix/sysv/linux/i386/fallocate.c
@@ -30,7 +30,13 @@ int
fallocate (int fd, int mode, __off_t offset, __off_t len)
{
#ifdef __NR_fallocate
- return __call_fallocate (fd, mode, offset, len);
+ int err = __call_fallocate (fd, mode, offset, len);
+ if (__builtin_expect (err, 0))
+ {
+ __set_errno (err);
+ err = -1;
+ }
+ return err;
#else
__set_errno (ENOSYS);
return -1;
diff --git a/sysdeps/unix/sysv/linux/i386/fallocate64.c b/sysdeps/unix/sysv/linux/i386/fallocate64.c
index 85f315c9b6..063bab06e9 100644
--- a/sysdeps/unix/sysv/linux/i386/fallocate64.c
+++ b/sysdeps/unix/sysv/linux/i386/fallocate64.c
@@ -30,7 +30,13 @@ int
fallocate64 (int fd, int mode, __off64_t offset, __off64_t len)
{
#ifdef __NR_fallocate
- return __call_fallocate (fd, mode, offset, len);
+ int err = __call_fallocate (fd, mode, offset, len);
+ if (__builtin_expect (err, 0))
+ {
+ __set_errno (err);
+ err = -1;
+ }
+ return err;
#else
__set_errno (ENOSYS);
return -1;
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
index c6da57b75e..f96f16a6f2 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2004, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@
#define __READDIR_R __readdir64_r
#define __GETDENTS __getdents64
#define DIRENT_TYPE struct dirent64
+#define GETDENTS_64BIT_ALIGNED 1
#include <sysdeps/unix/readdir_r.c>
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 149bd1c3ba..84f223ddbd 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -1,5 +1,5 @@
/* getifaddrs -- get names and addresses of all network interfaces
- Copyright (C) 2003-2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2003-2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -315,17 +315,19 @@ map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
else if (map[i] == index)
return i;
}
- /* This should never be reached. If this will be reached, we have
- a very big problem. */
- abort ();
+
+ /* This means interfaces changed inbetween the reading of the
+ RTM_GETLINK and RTM_GETADDR information. We have to repeat
+ everything. */
+ return -1;
}
/* Create a linked list of `struct ifaddrs' structures, one for each
network interface on the host machine. If successful, store the
list in *IFAP and return 0. On errors, return -1 and set `errno'. */
-int
-getifaddrs (struct ifaddrs **ifap)
+static int
+getifaddrs_internal (struct ifaddrs **ifap)
{
struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
struct netlink_res *nlp;
@@ -481,6 +483,13 @@ getifaddrs (struct ifaddrs **ifap)
kernel. */
ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
map_newlink_data, newlink);
+ if (__builtin_expect (ifa_index == -1, 0))
+ {
+ try_again:
+ result = -EAGAIN;
+ free (ifas);
+ goto exit_free;
+ }
ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
while (RTA_OK (rta, rtasize))
@@ -565,9 +574,11 @@ getifaddrs (struct ifaddrs **ifap)
that we have holes in the interface part of the list,
but we always have already the interface for this address. */
ifa_index = newlink + newaddr_idx;
- ifas[ifa_index].ifa.ifa_flags
- = ifas[map_newlink (ifam->ifa_index - 1, ifas,
- map_newlink_data, newlink)].ifa.ifa_flags;
+ int idx = map_newlink (ifam->ifa_index - 1, ifas,
+ map_newlink_data, newlink);
+ if (__builtin_expect (idx == -1, 0))
+ goto try_again;
+ ifas[ifa_index].ifa.ifa_flags = ifas[idx].ifa.ifa_flags;
if (ifa_index > 0)
ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
++newaddr_idx;
@@ -747,9 +758,13 @@ getifaddrs (struct ifaddrs **ifap)
/* If we didn't get the interface name with the
address, use the name from the interface entry. */
if (ifas[ifa_index].ifa.ifa_name == NULL)
- ifas[ifa_index].ifa.ifa_name
- = ifas[map_newlink (ifam->ifa_index - 1, ifas,
- map_newlink_data, newlink)].ifa.ifa_name;
+ {
+ int idx = map_newlink (ifam->ifa_index - 1, ifas,
+ map_newlink_data, newlink);
+ if (__builtin_expect (idx == -1, 0))
+ goto try_again;
+ ifas[ifa_index].ifa.ifa_name = ifas[idx].ifa.ifa_name;
+ }
/* Calculate the netmask. */
if (ifas[ifa_index].ifa.ifa_addr
@@ -826,6 +841,22 @@ getifaddrs (struct ifaddrs **ifap)
return result;
}
+
+
+/* Create a linked list of `struct ifaddrs' structures, one for each
+ network interface on the host machine. If successful, store the
+ list in *IFAP and return 0. On errors, return -1 and set `errno'. */
+int
+getifaddrs (struct ifaddrs **ifap)
+{
+ int res;
+
+ do
+ res = getifaddrs_internal (ifap);
+ while (res == -EAGAIN);
+
+ return res;
+}
libc_hidden_def (getifaddrs)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
index b28e587498..f2c1518572 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
@@ -46,7 +46,7 @@
{ \
if ((oss.ss_flags & SS_ONSTACK) == 0 \
|| ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp \
- >= oss.ss_size)) \
+ < oss.ss_size)) \
__fortify_fail ("longjmp causes uninitialized stack frame");\
} \
} \
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
index dcf58fb50b..261be250dc 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
@@ -46,7 +46,7 @@
{ \
if ((oss.ss_flags & SS_ONSTACK) == 0 \
|| ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp \
- >= oss.ss_size)) \
+ < oss.ss_size)) \
__fortify_fail ("longjmp causes uninitialized stack frame");\
} \
} \
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 61a0556d5e..f615e9591f 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. x86-64 version.
- Copyright (C) 2001-2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2001-2006, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>.
@@ -419,7 +419,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
case R_X86_64_PC32:
value += reloc->r_addend - (Elf64_Addr) reloc_addr;
*(unsigned int *) reloc_addr = value;
- if (__builtin_expect (value != (unsigned int) value, 0))
+ if (__builtin_expect (value != (int) value, 0))
{
fmt = "\
%s: Symbol `%s' causes overflow in R_X86_64_PC32 relocation\n";
diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c
index 7823aceb9b..0fe2f86b4f 100644
--- a/sysdeps/x86_64/multiarch/init-arch.c
+++ b/sysdeps/x86_64/multiarch/init-arch.c
@@ -1,6 +1,6 @@
/* Initialize CPU feature data.
This file is part of the GNU C Library.
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@redhat.com>.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <atomic.h>
#include <cpuid.h>
#include "init-arch.h"
@@ -26,7 +27,7 @@ struct cpu_features __cpu_features attribute_hidden;
static void
-get_common_indeces (void)
+get_common_indeces (unsigned int *family, unsigned int *model)
{
__cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax,
__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx,
@@ -34,8 +35,8 @@ get_common_indeces (void)
__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx);
unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
- __cpu_features.family = (eax >> 8) & 0x0f;
- __cpu_features.model = (eax >> 4) & 0x0f;
+ *family = (eax >> 8) & 0x0f;
+ *model = (eax >> 4) & 0x0f;
}
@@ -45,36 +46,44 @@ __init_cpu_features (void)
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
+ unsigned int family = 0;
+ unsigned int model = 0;
+ enum cpu_features_kind kind;
__cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx);
/* This spells out "GenuineIntel". */
if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
{
- __cpu_features.kind = arch_kind_intel;
+ kind = arch_kind_intel;
- get_common_indeces ();
+ get_common_indeces (&family, &model);
unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
unsigned int extended_family = (eax >> 20) & 0xff;
unsigned int extended_model = (eax >> 12) & 0xf0;
if (__cpu_features.family == 0x0f)
{
- __cpu_features.family += extended_family;
- __cpu_features.model += extended_model;
+ family += extended_family;
+ model += extended_model;
}
else if (__cpu_features.family == 0x06)
- __cpu_features.model += extended_model;
+ model += extended_model;
}
/* This spells out "AuthenticAMD". */
else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
{
- __cpu_features.kind = arch_kind_amd;
+ kind = arch_kind_amd;
- get_common_indeces ();
+ get_common_indeces (&family, &model);
}
else
- __cpu_features.kind = arch_kind_other;
+ kind = arch_kind_other;
+
+ __cpu_features.family = family;
+ __cpu_features.model = model;
+ atomic_write_barrier ();
+ __cpu_features.kind = kind;
}
#undef __get_cpu_features
diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h
index 9b12831a6e..f6320693bf 100644
--- a/sysdeps/x86_64/multiarch/init-arch.h
+++ b/sysdeps/x86_64/multiarch/init-arch.h
@@ -1,5 +1,5 @@
/* This file is part of the GNU C Library.
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@ enum
extern struct cpu_features
{
- enum
+ enum cpu_features_kind
{
arch_kind_unknown = 0,
arch_kind_intel,