~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to libclamav/7z/CpuArch.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* CpuArch.c -- CPU specific code
2
 
2010-10-26: Igor Pavlov : Public domain */
3
 
 
4
 
#include "CpuArch.h"
5
 
 
6
 
#ifdef MY_CPU_X86_OR_AMD64
7
 
 
8
 
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
9
 
#define USE_ASM
10
 
#endif
11
 
 
12
 
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
13
 
static UInt32 CheckFlag(UInt32 flag)
14
 
{
15
 
  #ifdef _MSC_VER
16
 
  __asm pushfd;
17
 
  __asm pop EAX;
18
 
  __asm mov EDX, EAX;
19
 
  __asm xor EAX, flag;
20
 
  __asm push EAX;
21
 
  __asm popfd;
22
 
  __asm pushfd;
23
 
  __asm pop EAX;
24
 
  __asm xor EAX, EDX;
25
 
  __asm push EDX;
26
 
  __asm popfd;
27
 
  __asm and flag, EAX;
28
 
  #else
29
 
  __asm__ __volatile__ (
30
 
    "pushf\n\t"
31
 
    "pop  %%EAX\n\t"
32
 
    "movl %%EAX,%%EDX\n\t"
33
 
    "xorl %0,%%EAX\n\t"
34
 
    "push %%EAX\n\t"
35
 
    "popf\n\t"
36
 
    "pushf\n\t"
37
 
    "pop  %%EAX\n\t"
38
 
    "xorl %%EDX,%%EAX\n\t"
39
 
    "push %%EDX\n\t"
40
 
    "popf\n\t"
41
 
    "andl %%EAX, %0\n\t":
42
 
    "=c" (flag) : "c" (flag));
43
 
  #endif
44
 
  return flag;
45
 
}
46
 
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
47
 
#else
48
 
#define CHECK_CPUID_IS_SUPPORTED
49
 
#endif
50
 
 
51
 
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
52
 
{
53
 
  #ifdef USE_ASM
54
 
 
55
 
  #ifdef _MSC_VER
56
 
 
57
 
  UInt32 a2, b2, c2, d2;
58
 
  __asm xor EBX, EBX;
59
 
  __asm xor ECX, ECX;
60
 
  __asm xor EDX, EDX;
61
 
  __asm mov EAX, function;
62
 
  __asm cpuid;
63
 
  __asm mov a2, EAX;
64
 
  __asm mov b2, EBX;
65
 
  __asm mov c2, ECX;
66
 
  __asm mov d2, EDX;
67
 
 
68
 
  *a = a2;
69
 
  *b = b2;
70
 
  *c = c2;
71
 
  *d = d2;
72
 
 
73
 
  #else
74
 
 
75
 
  __asm__ __volatile__ (
76
 
    "cpuid"
77
 
    : "=a" (*a) ,
78
 
      "=b" (*b) ,
79
 
      "=c" (*c) ,
80
 
      "=d" (*d)
81
 
    : "0" (function)) ;
82
 
 
83
 
  #endif
84
 
  
85
 
  #else
86
 
 
87
 
  int CPUInfo[4];
88
 
  __cpuid(CPUInfo, function);
89
 
  *a = CPUInfo[0];
90
 
  *b = CPUInfo[1];
91
 
  *c = CPUInfo[2];
92
 
  *d = CPUInfo[3];
93
 
 
94
 
  #endif
95
 
}
96
 
 
97
 
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
98
 
{
99
 
  CHECK_CPUID_IS_SUPPORTED
100
 
  MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
101
 
  MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
102
 
  return True;
103
 
}
104
 
 
105
 
static UInt32 kVendors[][3] =
106
 
{
107
 
  { 0x756E6547, 0x49656E69, 0x6C65746E},
108
 
  { 0x68747541, 0x69746E65, 0x444D4163},
109
 
  { 0x746E6543, 0x48727561, 0x736C7561}
110
 
};
111
 
 
112
 
int x86cpuid_GetFirm(const Cx86cpuid *p)
113
 
{
114
 
  unsigned i;
115
 
  for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
116
 
  {
117
 
    const UInt32 *v = kVendors[i];
118
 
    if (v[0] == p->vendor[0] &&
119
 
        v[1] == p->vendor[1] &&
120
 
        v[2] == p->vendor[2])
121
 
      return (int)i;
122
 
  }
123
 
  return -1;
124
 
}
125
 
 
126
 
Bool CPU_Is_InOrder()
127
 
{
128
 
  Cx86cpuid p;
129
 
  int firm;
130
 
  UInt32 family, model;
131
 
  if (!x86cpuid_CheckAndRead(&p))
132
 
    return True;
133
 
  family = x86cpuid_GetFamily(&p);
134
 
  model = x86cpuid_GetModel(&p);
135
 
  firm = x86cpuid_GetFirm(&p);
136
 
  switch (firm)
137
 
  {
138
 
    case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
139
 
    case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
140
 
    case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
141
 
  }
142
 
  return True;
143
 
}
144
 
 
145
 
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
146
 
static Bool CPU_Sys_Is_SSE_Supported()
147
 
{
148
 
  OSVERSIONINFO vi;
149
 
  vi.dwOSVersionInfoSize = sizeof(vi);
150
 
  if (!GetVersionEx(&vi))
151
 
    return False;
152
 
  return (vi.dwMajorVersion >= 5);
153
 
}
154
 
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
155
 
#else
156
 
#define CHECK_SYS_SSE_SUPPORT
157
 
#endif
158
 
 
159
 
Bool CPU_Is_Aes_Supported()
160
 
{
161
 
  Cx86cpuid p;
162
 
  CHECK_SYS_SSE_SUPPORT
163
 
  if (!x86cpuid_CheckAndRead(&p))
164
 
    return False;
165
 
  return (p.c >> 25) & 1;
166
 
}
167
 
 
168
 
#endif
 
1
/* CpuArch.c -- CPU specific code
 
2
2010-10-26: Igor Pavlov : Public domain */
 
3
 
 
4
#if defined(_WIN32)
 
5
#include <WinSock2.h>
 
6
#include <Windows.h>
 
7
#endif
 
8
 
 
9
#include <openssl/ssl.h>
 
10
#include <openssl/err.h>
 
11
#include "libclamav/crypto.h"
 
12
 
 
13
#include "CpuArch.h"
 
14
 
 
15
#ifdef MY_CPU_X86_OR_AMD64
 
16
 
 
17
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
 
18
#define USE_ASM
 
19
#endif
 
20
 
 
21
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
 
22
static UInt32 CheckFlag(UInt32 flag)
 
23
{
 
24
  #ifdef _MSC_VER
 
25
  __asm pushfd;
 
26
  __asm pop EAX;
 
27
  __asm mov EDX, EAX;
 
28
  __asm xor EAX, flag;
 
29
  __asm push EAX;
 
30
  __asm popfd;
 
31
  __asm pushfd;
 
32
  __asm pop EAX;
 
33
  __asm xor EAX, EDX;
 
34
  __asm push EDX;
 
35
  __asm popfd;
 
36
  __asm and flag, EAX;
 
37
  #else
 
38
  __asm__ __volatile__ (
 
39
    "pushf\n\t"
 
40
    "pop  %%EAX\n\t"
 
41
    "movl %%EAX,%%EDX\n\t"
 
42
    "xorl %0,%%EAX\n\t"
 
43
    "push %%EAX\n\t"
 
44
    "popf\n\t"
 
45
    "pushf\n\t"
 
46
    "pop  %%EAX\n\t"
 
47
    "xorl %%EDX,%%EAX\n\t"
 
48
    "push %%EDX\n\t"
 
49
    "popf\n\t"
 
50
    "andl %%EAX, %0\n\t":
 
51
    "=c" (flag) : "c" (flag));
 
52
  #endif
 
53
  return flag;
 
54
}
 
55
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
 
56
#else
 
57
#define CHECK_CPUID_IS_SUPPORTED
 
58
#endif
 
59
 
 
60
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
 
61
{
 
62
  #ifdef USE_ASM
 
63
 
 
64
  #ifdef _MSC_VER
 
65
 
 
66
  UInt32 a2, b2, c2, d2;
 
67
  __asm xor EBX, EBX;
 
68
  __asm xor ECX, ECX;
 
69
  __asm xor EDX, EDX;
 
70
  __asm mov EAX, function;
 
71
  __asm cpuid;
 
72
  __asm mov a2, EAX;
 
73
  __asm mov b2, EBX;
 
74
  __asm mov c2, ECX;
 
75
  __asm mov d2, EDX;
 
76
 
 
77
  *a = a2;
 
78
  *b = b2;
 
79
  *c = c2;
 
80
  *d = d2;
 
81
 
 
82
  #else
 
83
 
 
84
  __asm__ __volatile__ (
 
85
    "cpuid"
 
86
    : "=a" (*a) ,
 
87
      "=b" (*b) ,
 
88
      "=c" (*c) ,
 
89
      "=d" (*d)
 
90
    : "0" (function)) ;
 
91
 
 
92
  #endif
 
93
  
 
94
  #else
 
95
 
 
96
  int CPUInfo[4];
 
97
  __cpuid(CPUInfo, function);
 
98
  *a = CPUInfo[0];
 
99
  *b = CPUInfo[1];
 
100
  *c = CPUInfo[2];
 
101
  *d = CPUInfo[3];
 
102
 
 
103
  #endif
 
104
}
 
105
 
 
106
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
 
107
{
 
108
  CHECK_CPUID_IS_SUPPORTED
 
109
  MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
 
110
  MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
 
111
  return True;
 
112
}
 
113
 
 
114
static UInt32 kVendors[][3] =
 
115
{
 
116
  { 0x756E6547, 0x49656E69, 0x6C65746E},
 
117
  { 0x68747541, 0x69746E65, 0x444D4163},
 
118
  { 0x746E6543, 0x48727561, 0x736C7561}
 
119
};
 
120
 
 
121
int x86cpuid_GetFirm(const Cx86cpuid *p)
 
122
{
 
123
  unsigned i;
 
124
  for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
 
125
  {
 
126
    const UInt32 *v = kVendors[i];
 
127
    if (v[0] == p->vendor[0] &&
 
128
        v[1] == p->vendor[1] &&
 
129
        v[2] == p->vendor[2])
 
130
      return (int)i;
 
131
  }
 
132
  return -1;
 
133
}
 
134
 
 
135
Bool CPU_Is_InOrder()
 
136
{
 
137
  Cx86cpuid p;
 
138
  int firm;
 
139
  UInt32 family, model;
 
140
  if (!x86cpuid_CheckAndRead(&p))
 
141
    return True;
 
142
  family = x86cpuid_GetFamily(&p);
 
143
  model = x86cpuid_GetModel(&p);
 
144
  firm = x86cpuid_GetFirm(&p);
 
145
  switch (firm)
 
146
  {
 
147
    case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
 
148
    case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
 
149
    case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
 
150
  }
 
151
  return True;
 
152
}
 
153
 
 
154
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
 
155
static Bool CPU_Sys_Is_SSE_Supported()
 
156
{
 
157
  OSVERSIONINFO vi;
 
158
  vi.dwOSVersionInfoSize = sizeof(vi);
 
159
  if (!GetVersionEx(&vi))
 
160
    return False;
 
161
  return (vi.dwMajorVersion >= 5);
 
162
}
 
163
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
 
164
#else
 
165
#define CHECK_SYS_SSE_SUPPORT
 
166
#endif
 
167
 
 
168
Bool CPU_Is_Aes_Supported()
 
169
{
 
170
  Cx86cpuid p;
 
171
  CHECK_SYS_SSE_SUPPORT
 
172
  if (!x86cpuid_CheckAndRead(&p))
 
173
    return False;
 
174
  return (p.c >> 25) & 1;
 
175
}
 
176
 
 
177
#endif