Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2014 Lennart Poettering
7 :
8 : systemd is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation; either version 2.1 of the License, or
11 : (at your option) any later version.
12 :
13 : systemd is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 : ***/
21 :
22 : #include <sys/utsname.h>
23 :
24 : #include "architecture.h"
25 :
26 5 : int uname_architecture(void) {
27 :
28 : /* Return a sanitized enum identifying the architecture we are
29 : * running on. This is based on uname(), and the user may
30 : * hence control what this returns by using
31 : * personality(). This puts the user in control on systems
32 : * that can run binaries of multiple architectures.
33 : *
34 : * We do not translate the string returned by uname()
35 : * 1:1. Instead we try to clean it up and break down the
36 : * confusion on x86 and arm in particular.
37 : *
38 : * We do not try to distinguish CPUs not CPU features, but
39 : * actual architectures, i.e. that have genuinely different
40 : * code. */
41 :
42 : static const struct {
43 : const char *machine;
44 : int arch;
45 : } arch_map[] = {
46 : #if defined(__x86_64__) || defined(__i386__)
47 : { "x86_64", ARCHITECTURE_X86_64 },
48 : { "i686", ARCHITECTURE_X86 },
49 : { "i586", ARCHITECTURE_X86 },
50 : { "i486", ARCHITECTURE_X86 },
51 : { "i386", ARCHITECTURE_X86 },
52 : #elif defined(__powerpc__) || defined(__powerpc64__)
53 : { "ppc64", ARCHITECTURE_PPC64 },
54 : { "ppc64le", ARCHITECTURE_PPC64_LE },
55 : { "ppc", ARCHITECTURE_PPC },
56 : { "ppcle", ARCHITECTURE_PPC_LE },
57 : #elif defined(__ia64__)
58 : { "ia64", ARCHITECTURE_IA64 },
59 : #elif defined(__hppa__) || defined(__hppa64__)
60 : { "parisc64", ARCHITECTURE_PARISC64 },
61 : { "parisc", ARCHITECTURE_PARISC },
62 : #elif defined(__s390__) || defined(__s390x__)
63 : { "s390x", ARCHITECTURE_S390X },
64 : { "s390", ARCHITECTURE_S390 },
65 : #elif defined(__sparc__) || defined(__sparc64__)
66 : { "sparc64", ARCHITECTURE_SPARC64 },
67 : { "sparc", ARCHITECTURE_SPARC },
68 : #elif defined(__mips__) || defined(__mips64__)
69 : { "mips64", ARCHITECTURE_MIPS64 },
70 : { "mips", ARCHITECTURE_MIPS },
71 : #elif defined(__alpha__)
72 : { "alpha" , ARCHITECTURE_ALPHA },
73 : #elif defined(__arm__) || defined(__aarch64__)
74 : { "aarch64", ARCHITECTURE_ARM64 },
75 : { "aarch64_be", ARCHITECTURE_ARM64_BE },
76 : { "armv4l", ARCHITECTURE_ARM },
77 : { "armv4b", ARCHITECTURE_ARM_BE },
78 : { "armv4tl", ARCHITECTURE_ARM },
79 : { "armv4tb", ARCHITECTURE_ARM_BE },
80 : { "armv5tl", ARCHITECTURE_ARM },
81 : { "armv5tb", ARCHITECTURE_ARM_BE },
82 : { "armv5tel", ARCHITECTURE_ARM },
83 : { "armv5teb" , ARCHITECTURE_ARM_BE },
84 : { "armv5tejl", ARCHITECTURE_ARM },
85 : { "armv5tejb", ARCHITECTURE_ARM_BE },
86 : { "armv6l", ARCHITECTURE_ARM },
87 : { "armv6b", ARCHITECTURE_ARM_BE },
88 : { "armv7l", ARCHITECTURE_ARM },
89 : { "armv7b", ARCHITECTURE_ARM_BE },
90 : { "armv7ml", ARCHITECTURE_ARM },
91 : { "armv7mb", ARCHITECTURE_ARM_BE },
92 : { "armv4l", ARCHITECTURE_ARM },
93 : { "armv4b", ARCHITECTURE_ARM_BE },
94 : { "armv4tl", ARCHITECTURE_ARM },
95 : { "armv4tb", ARCHITECTURE_ARM_BE },
96 : { "armv5tl", ARCHITECTURE_ARM },
97 : { "armv5tb", ARCHITECTURE_ARM_BE },
98 : { "armv5tel", ARCHITECTURE_ARM },
99 : { "armv5teb", ARCHITECTURE_ARM_BE },
100 : { "armv5tejl", ARCHITECTURE_ARM },
101 : { "armv5tejb", ARCHITECTURE_ARM_BE },
102 : { "armv6l", ARCHITECTURE_ARM },
103 : { "armv6b", ARCHITECTURE_ARM_BE },
104 : { "armv7l", ARCHITECTURE_ARM },
105 : { "armv7b", ARCHITECTURE_ARM_BE },
106 : { "armv7ml", ARCHITECTURE_ARM },
107 : { "armv7mb", ARCHITECTURE_ARM_BE },
108 : { "armv8l", ARCHITECTURE_ARM },
109 : { "armv8b", ARCHITECTURE_ARM_BE },
110 : #elif defined(__sh__) || defined(__sh64__)
111 : { "sh5", ARCHITECTURE_SH64 },
112 : { "sh2", ARCHITECTURE_SH },
113 : { "sh2a", ARCHITECTURE_SH },
114 : { "sh3", ARCHITECTURE_SH },
115 : { "sh4", ARCHITECTURE_SH },
116 : { "sh4a", ARCHITECTURE_SH },
117 : #elif defined(__m68k__)
118 : { "m68k", ARCHITECTURE_M68K },
119 : #elif defined(__tilegx__)
120 : { "tilegx", ARCHITECTURE_TILEGX },
121 : #elif defined(__cris__)
122 : { "crisv32", ARCHITECTURE_CRIS },
123 : #else
124 : #error "Please register your architecture here!"
125 : #endif
126 : };
127 :
128 : static int cached = _ARCHITECTURE_INVALID;
129 : struct utsname u;
130 : unsigned i;
131 :
132 5 : if (cached != _ARCHITECTURE_INVALID)
133 3 : return cached;
134 :
135 2 : assert_se(uname(&u) >= 0);
136 :
137 2 : for (i = 0; i < ELEMENTSOF(arch_map); i++)
138 2 : if (streq(arch_map[i].machine, u.machine))
139 2 : return cached = arch_map[i].arch;
140 :
141 0 : assert_not_reached("Couldn't identify architecture. You need to patch systemd.");
142 : return _ARCHITECTURE_INVALID;
143 : }
144 :
145 : static const char *const architecture_table[_ARCHITECTURE_MAX] = {
146 : [ARCHITECTURE_X86] = "x86",
147 : [ARCHITECTURE_X86_64] = "x86-64",
148 : [ARCHITECTURE_PPC] = "ppc",
149 : [ARCHITECTURE_PPC_LE] = "ppc-le",
150 : [ARCHITECTURE_PPC64] = "ppc64",
151 : [ARCHITECTURE_PPC64_LE] = "ppc64-le",
152 : [ARCHITECTURE_IA64] = "ia64",
153 : [ARCHITECTURE_PARISC] = "parisc",
154 : [ARCHITECTURE_PARISC64] = "parisc64",
155 : [ARCHITECTURE_S390] = "s390",
156 : [ARCHITECTURE_S390X] = "s390x",
157 : [ARCHITECTURE_SPARC] = "sparc",
158 : [ARCHITECTURE_SPARC64] = "sparc64",
159 : [ARCHITECTURE_MIPS] = "mips",
160 : [ARCHITECTURE_MIPS_LE] = "mips-le",
161 : [ARCHITECTURE_MIPS64] = "mips64",
162 : [ARCHITECTURE_MIPS64_LE] = "mips64-le",
163 : [ARCHITECTURE_ALPHA] = "alpha",
164 : [ARCHITECTURE_ARM] = "arm",
165 : [ARCHITECTURE_ARM_BE] = "arm-be",
166 : [ARCHITECTURE_ARM64] = "arm64",
167 : [ARCHITECTURE_ARM64_BE] = "arm64-be",
168 : [ARCHITECTURE_SH] = "sh",
169 : [ARCHITECTURE_SH64] = "sh64",
170 : [ARCHITECTURE_M68K] = "m68k",
171 : [ARCHITECTURE_TILEGX] = "tilegx",
172 : [ARCHITECTURE_CRIS] = "cris",
173 : };
174 :
175 64 : DEFINE_STRING_TABLE_LOOKUP(architecture, int);
|