Ticket #1990: coreutils-6.9-insane_uname.diff3

File coreutils-6.9-insane_uname.diff3, 8.1 KB (added by robert@…, 18 years ago)

multi-arch uname patch

Line 
1diff -Naur coreutils-6.9.orig/src/uname.c coreutils-6.9/src/uname.c
2--- coreutils-6.9.orig/src/uname.c 2007-03-18 21:36:43.000000000 +0000
3+++ coreutils-6.9/src/uname.c 2007-04-17 19:34:32.000000000 +0000
4@@ -51,6 +51,31 @@
5 # include <mach-o/arch.h>
6 #endif
7
8+#if defined(__linux__)
9+/* Thanks to the ffmpeg libavcodec/i386/cputest.c for this PIC version of cpuid() */
10+# if defined(__i386__)
11+# define REG_b "ebx"
12+# define REG_S "esi"
13+# elif defined(__x86_64__)
14+# define REG_b "rbx"
15+# define REG_S "rsi"
16+# endif
17+# if defined(REG_b) && defined(REG_S)
18+# define x86cpuid(index,eax,ebx,ecx,edx)\
19+ __asm __volatile\
20+ ("mov %%"REG_b", %%"REG_S"\n\t"\
21+ "cpuid\n\t"\
22+ "xchg %%"REG_b", %%"REG_S\
23+ : "=a" (eax), "=S" (ebx),\
24+ "=c" (ecx), "=d" (edx)\
25+ : "0" (index));
26+int has_sse(void);
27+# else /* Not an x86? Then try /proc/{sys,cpu}info. */
28+# define USE_PROCINFO
29+# define UNAME_HARDWARE_PLATFORM
30+# endif
31+#endif /* __linux__ */
32+
33 #include "system.h"
34 #include "error.h"
35 #include "quote.h"
36@@ -138,6 +163,108 @@
37 exit (status);
38 }
39
40+#if defined(USE_PROCINFO)
41+
42+# if defined(__s390__) || defined(__s390x__)
43+# define CPUINFO_FILE "/proc/sysinfo"
44+# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c"
45+# else
46+# define CPUINFO_FILE "/proc/cpuinfo"
47+# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c"
48+# endif
49+
50+# define PROCINFO_PROCESSOR 0
51+# define PROCINFO_HARDWARE_PLATFORM 1
52+
53+static void __eat_cpuinfo_space(char *buf)
54+{
55+ /* first eat trailing space */
56+ char *tmp = buf + strlen(buf) - 1;
57+ while (tmp > buf && isspace(*tmp))
58+ *tmp-- = '\0';
59+ /* then eat leading space */
60+ tmp = buf;
61+ while (*tmp && isspace(*tmp))
62+ tmp++;
63+ if (tmp != buf)
64+ memmove(buf, tmp, strlen(tmp)+1);
65+}
66+
67+static int __linux_procinfo (int x, char *fstr, size_t s)
68+{
69+ FILE *fp;
70+
71+ char *procinfo_keys[] = {
72+ /* --processor --hardware-platform */
73+ #if defined(__alpha__)
74+ "cpu model", "system type"
75+ #elif defined(__arm__)
76+ "Processor", "Hardware"
77+ #elif defined(bfin)
78+ "CPU", "BOARD Name"
79+ #elif defined(__cris__)
80+ "cpu", "cpu model"
81+ #elif defined(__frv__)
82+ "CPU-Core", "System"
83+ /*
84+ #elif defined(__i386__) || defined(__x86_64__)
85+ "model name", "vendor_id"
86+ */
87+ #elif defined(__ia64__)
88+ "family", "vendor"
89+ #elif defined(__hppa__)
90+ "cpu", "model"
91+ #elif defined(__m68k__)
92+ "CPU", "MMU"
93+ #elif defined(__mips__)
94+ "cpu model", "system type"
95+ #elif defined(__powerpc__) || defined(__powerpc64__)
96+ "cpu", "machine"
97+ #elif defined(__s390__) || defined(__s390x__)
98+ "Type", "Manufacturer"
99+ #elif defined(__sh__)
100+ "cpu type", "machine"
101+ #elif defined(sparc) || defined(__sparc__)
102+ "type", "cpu"
103+ #elif defined(__vax__)
104+ "cpu type", "cpu"
105+ #else
106+ "unknown", "unknown"
107+ #endif
108+ };
109+
110+ if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
111+ char key[65], value[257], eol, *ret = NULL;
112+
113+ while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
114+ __eat_cpuinfo_space(key);
115+ if (!strcmp(key, procinfo_keys[x])) {
116+ __eat_cpuinfo_space(value);
117+ ret = value;
118+ break;
119+ }
120+ if (eol != '\n') {
121+ /* we need two fscanf's here in case the previous
122+ * length limit caused us to read right up to the
123+ * newline ... doing "%*[^\n]\n" wont eat the newline
124+ */
125+ fscanf(fp, "%*[^\n]");
126+ fscanf(fp, "\n");
127+ }
128+ }
129+ fclose(fp);
130+
131+ if (ret) {
132+ strncpy(fstr, ret, s);
133+ return 0;
134+ }
135+ }
136+
137+ return -1;
138+}
139+
140+#endif
141+
142 /* Print ELEMENT, preceded by a space if something has already been
143 printed. */
144
145@@ -250,12 +377,107 @@
146 if (toprint & PRINT_PROCESSOR)
147 {
148 char const *element = unknown;
149-#if HAVE_SYSINFO && defined SI_ARCHITECTURE
150+#if (defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)) || defined(USE_PROCINFO)
151 {
152 static char processor[257];
153+# if defined(USE_PROCINFO)
154+ if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
155+# else
156 if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
157+# endif
158 element = processor;
159 }
160+# elif defined(x86cpuid)
161+ {
162+ struct utsname u;
163+ uname (&u);
164+ element = u.machine;
165+
166+/******************************************************************************
167+ *
168+ * Hello, major hack. I shouldn't have to do this. struct utsname should
169+ * have another element with this info in it. There's probably a struct
170+ * somewhere that has this info, I just don't know where it is.
171+ *
172+ *****************************************************************************/
173+
174+ if( !strcmp( element, "i586" ) || !strcmp( element, "i686" ) ) {
175+ int eax, ebx, ecx, edx, unused;
176+ int model, family, sse;
177+
178+ x86cpuid(0,unused,ebx,ecx,edx);
179+ x86cpuid(1,eax,unused,unused,unused);
180+ model = (eax >> 4) & 0xf;
181+ family = (eax >> 8) & 0xf;
182+
183+ switch(ebx) {
184+ case 0x756e6547: /* Intel */
185+ switch( family ) {
186+ case 5: /* Pentium */
187+ if( model <= 3 )
188+ element="pentium";
189+ if( model > 3 )
190+ element="pentium-mmx";
191+ break;
192+ case 6: /* PentiumPro - Pentium3 */
193+ if( model == 1 ) /* Pentium Pro */
194+ element="pentiumpro";
195+ if( ( model == 3 ) || ( model == 5 ) ||
196+ ( model == 6 ) ) /* Pentium II */
197+ element="pentium2";
198+ if( ( model == 7 ) || ( model == 8 ) ||
199+ ( model == 10 ) || ( model == 11 ) ) /* These are all Pentium3 */
200+ element="pentium3";
201+ break;
202+ case 15: /* Pentium4 */
203+ if( model == 3 ) /* Prescott */
204+ element="prescott";
205+ else
206+ element="pentium4";
207+ break;
208+ default:
209+ break;
210+ } // end switch( family )
211+ break;
212+ case 0x68747541: /* AMD */
213+ switch(family) {
214+ case 5:
215+ if( ( model == 0 ) || ( model == 1 ) ||
216+ ( model == 2 ) || ( model == 3 ) ) /* K5 */
217+ element="i586";
218+ if( ( model == 6 ) || ( model == 7 ) ) /* K6 */
219+ element="k6";
220+ if( model == 8 ) /* K6-2 */
221+ element="k6-2";
222+ if( model == 9 ) /* K6-3 */
223+ element="k6-3";
224+ break;
225+ case 6:
226+ if( model <= 4 )
227+ element="athlon";
228+ if( model > 4 ) {
229+ sse = has_sse();
230+ if( sse == 0 )
231+ element="athlon";
232+ if( sse == 1 )
233+ element="athlon-4";
234+ }
235+ break;
236+ case 15:
237+ element="athlon-4";
238+ break;
239+ default:
240+ break;
241+ } /* end switch(family) */
242+ break;
243+ case 0x69727943: /* Cyrix */
244+ element="i386"; /* Who knows what cyrix supports, lets be safe. */
245+ break;
246+ default:
247+ break;
248+ } /* end switch(ebx) */
249+ }
250+ }
251 #endif
252 #ifdef UNAME_PROCESSOR
253 if (element == unknown)
254@@ -293,7 +515,7 @@
255
256 if (toprint & PRINT_HARDWARE_PLATFORM)
257 {
258- char const *element = unknown;
259+ char *element = unknown;
260 #if HAVE_SYSINFO && defined SI_PLATFORM
261 {
262 static char hardware_platform[257];
263@@ -301,14 +523,27 @@
264 hardware_platform, sizeof hardware_platform))
265 element = hardware_platform;
266 }
267+#elif defined(x86cpuid)
268+ {
269+ struct utsname u;
270+ uname (&u);
271+ element = u.machine;
272+ if (strlen (element) == 4 && element[0] == 'i' && element[2] == '8'
273+ && element[3] == '6')
274+ element[1] = '3';
275+ }
276 #endif
277 #ifdef UNAME_HARDWARE_PLATFORM
278 if (element == unknown)
279 {
280 static char hardware_platform[257];
281+#if defined(USE_PROCINFO)
282+ if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
283+#else
284 size_t s = sizeof hardware_platform;
285 static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
286 if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
287+#endif
288 element = hardware_platform;
289 }
290 #endif
291@@ -323,3 +558,29 @@
292
293 exit (EXIT_SUCCESS);
294 }
295+
296+#if defined(x86cpuid)
297+
298+/******************************************************************************
299+ *
300+ * int has_sse( void )
301+ * Checks Athlon CPU's to see if they support SSE.
302+ *
303+ *****************************************************************************/
304+
305+int has_sse( void )
306+{
307+ unsigned long edx, unused;
308+ int sse;
309+ x86cpuid(1,unused,unused,unused,edx);
310+ /* I think, I need this tested on a Duron with SSE
311+ and one without it. */
312+ sse = edx & 0x2000000;
313+ if( sse == 0 ) {
314+ return 0;
315+ } else {
316+ return 1;
317+ }
318+
319+}
320+#endif