coreutils: Use PIE version of LFS uname patch.
[people/teissler/ipfire-2.x.git] / src / patches / coreutils-5.96-uname-1.patch
CommitLineData
035ace2c
MT
1Submitted By: Robert Connolly <robert@linuxfromscratch.org> (ashes)
2Date: 2005-11-13
3Initial Package Version: 5.93
dd714b8a 4Upstream Status: pending
035ace2c
MT
5Origin: Scot McPherson and Zack Winkles
6Description: Fix the output of uname once and for all. This is the position independent
7version.
dd714b8a 8
035ace2c 9 $ uname -m # This always worked.
dd714b8a 10 i686
035ace2c 11 $ uname -i # Used to report 'unknown'.
dd714b8a 12 i386
035ace2c 13 $ uname -p # Likewise.
dd714b8a
MT
14 athlon-4
15
035ace2c
MT
16Now 'uname -p' can be used by GCC's mtune/mcpu and march options. For example:
17
18 CFLAGS="-march=$(uname -m) -mtune=$(uname -p)"
19
20diff -Naur coreutils-5.93.orig/src/uname.c coreutils-5.93/src/uname.c
21--- coreutils-5.93.orig/src/uname.c 2005-09-15 19:57:04.000000000 +0000
22+++ coreutils-5.93/src/uname.c 2005-11-13 19:18:35.000000000 +0000
23@@ -29,6 +29,26 @@
dd714b8a
MT
24 # include <sys/systeminfo.h>
25 #endif
26
27+#ifdef linux
035ace2c
MT
28+/* Thanks to the ffmpeg team for this PIC version of cpuid() */
29+#ifdef ARCH_X86_64
30+# define REG_b "rbx"
31+# define REG_S "rsi"
32+#else
33+# define REG_b "ebx"
34+# define REG_S "esi"
35+#endif
36+#define cpuid(index,eax,ebx,ecx,edx)\
37+ __asm __volatile\
38+ ("mov %%"REG_b", %%"REG_S"\n\t"\
39+ "cpuid\n\t"\
40+ "xchg %%"REG_b", %%"REG_S\
41+ : "=a" (eax), "=S" (ebx),\
42+ "=c" (ecx), "=d" (edx)\
43+ : "0" (index));
dd714b8a
MT
44+int has_sse( void );
45+#endif
46+
47 #if HAVE_SYS_SYSCTL_H
48 # if HAVE_SYS_PARAM_H
49 # include <sys/param.h> /* needed for OpenBSD 3.0 */
035ace2c 50@@ -256,6 +276,99 @@
dd714b8a
MT
51 if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
52 element = processor;
53 }
54+#else
55+ {
56+ struct utsname u;
57+ uname (&u);
58+ element = u.machine;
59+#ifdef linux
60+/******************************************************************************
61+ *
62+ * Hello, major hack. I shouldn't have to do this. struct utsname should
63+ * have another element with this info in it. There's probably a struct
64+ * somewhere that has this info, I just don't know where it is.
65+ *
66+ *****************************************************************************/
67+
68+ if( !strcmp( element, "i586" ) || !strcmp( element, "i686" ) ) {
69+ int eax, ebx, ecx, edx, unused;
70+ int model, family, sse;
71+
72+ cpuid(0,unused,ebx,ecx,edx);
73+ cpuid(1,eax,unused,unused,unused);
74+ model = (eax >> 4) & 0xf;
75+ family = (eax >> 8) & 0xf;
76+
77+ switch(ebx) {
78+ case 0x756e6547: // Intel
79+ switch( family ) {
80+ case 5: // Pentium
81+ if( model <= 3 )
82+ element="pentium";
83+ if( model > 3 )
84+ element="pentium-mmx";
85+ break;
86+ case 6: // PentiumPro - Pentium III
87+ if( model == 1 ) // Pentium Pro
88+ element="pentiumpro";
89+ if( ( model == 3 ) || ( model == 5 ) ||
90+ ( model == 6 ) ) // Pentium II
91+ element="pentium2";
92+ if( ( model == 7 ) || ( model == 8 ) ||
93+ ( model == 10 ) || ( model == 11 ) ) // These are all Pentium III
94+ element="pentium3";
95+ break;
96+ case 15: // Pentium4
035ace2c
MT
97+ if( model == 3 ) // Prescott
98+ element="prescott";
99+ else
dd714b8a
MT
100+ element="pentium4";
101+ break;
102+ default:
103+ break;
104+ } // end switch( family )
105+ break;
106+ case 0x68747541: // AMD
107+ switch(family) {
108+ case 5:
109+ if( ( model == 0 ) || ( model == 1 ) ||
110+ ( model == 2 ) || ( model == 3 ) ) // K5
111+ element="i586";
112+ if( ( model == 6 ) || ( model == 7 ) ) // K6
113+ element="k6";
114+ if( model == 8 ) // K6-2
115+ element="k6-2";
116+ if( model == 9 ) // K6-3
117+ element="k6-3";
118+ break;
119+ case 6:
120+ if( model <= 4 )
121+ element="athlon";
122+ if( model > 4 ) {
123+ sse = has_sse();
124+ if( sse == 0 )
125+ element="athlon";
126+ if( sse == 1 )
127+ element="athlon-4";
128+ }
129+ break;
130+ case 15:
131+ element="athlon-4";
132+ break;
133+ default:
134+ break;
135+ } // end switch( family )
136+ break;
137+ case 0x69727943: // Cyrix
138+ element="i386"; // who knows what cyrix supports, lets be safe
139+ break;
140+ default:
141+ break;
142+ } // end switch(ebx)
143+ }
144+
145+#endif
146+ }
147 #endif
148 #ifdef UNAME_PROCESSOR
149 if (element == unknown)
035ace2c 150@@ -293,7 +406,7 @@
dd714b8a
MT
151
152 if (toprint & PRINT_HARDWARE_PLATFORM)
153 {
154- char const *element = unknown;
155+ char *element = unknown;
156 #if HAVE_SYSINFO && defined SI_PLATFORM
157 {
158 static char hardware_platform[257];
035ace2c 159@@ -301,6 +414,15 @@
dd714b8a
MT
160 hardware_platform, sizeof hardware_platform))
161 element = hardware_platform;
162 }
163+#else
164+ {
165+ struct utsname u;
166+ uname (&u);
167+ element = u.machine;
168+ if (strlen (element) == 4 && element[0] == 'i' && element[2] == '8'
169+ && element[3] == '6')
170+ element[1] = '3';
171+ }
172 #endif
173 #ifdef UNAME_HARDWARE_PLATFORM
174 if (element == unknown)
035ace2c 175@@ -323,3 +445,29 @@
dd714b8a
MT
176
177 exit (EXIT_SUCCESS);
178 }
179+
180+#ifdef linux
181+
182+/******************************************************************************
183+ *
184+ * int has_sse( void )
185+ * Checks Athlon CPU's to see if they support SSE.
186+ *
187+ *****************************************************************************/
188+
189+int has_sse( void )
190+{
191+ unsigned long edx, unused;
192+ int sse;
193+ cpuid(1,unused,unused,unused,edx);
194+ // I think, I need this tested on a Duron with SSE
195+ // and one without it.
196+ sse = edx & 0x2000000;
197+ if( sse == 0 ) {
198+ return 0;
199+ } else {
200+ return 1;
201+ }
202+
203+}
204+#endif