/src/systemd/src/basic/architecture.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | | |
3 | | #include <sys/utsname.h> |
4 | | |
5 | | #include "architecture.h" |
6 | | #include "macro.h" |
7 | | #include "string-table.h" |
8 | | #include "string-util.h" |
9 | | |
10 | 115 | int uname_architecture(void) { |
11 | 115 | |
12 | 115 | /* Return a sanitized enum identifying the architecture we are |
13 | 115 | * running on. This is based on uname(), and the user may |
14 | 115 | * hence control what this returns by using |
15 | 115 | * personality(). This puts the user in control on systems |
16 | 115 | * that can run binaries of multiple architectures. |
17 | 115 | * |
18 | 115 | * We do not translate the string returned by uname() |
19 | 115 | * 1:1. Instead we try to clean it up and break down the |
20 | 115 | * confusion on x86 and arm in particular. |
21 | 115 | * |
22 | 115 | * We do not try to distinguish CPUs not CPU features, but |
23 | 115 | * actual architectures, i.e. that have genuinely different |
24 | 115 | * code. */ |
25 | 115 | |
26 | 115 | static const struct { |
27 | 115 | const char *machine; |
28 | 115 | int arch; |
29 | 115 | } arch_map[] = { |
30 | 115 | #if defined(__x86_64__) || defined(__i386__) |
31 | 115 | { "x86_64", ARCHITECTURE_X86_64 }, |
32 | 115 | { "i686", ARCHITECTURE_X86 }, |
33 | 115 | { "i586", ARCHITECTURE_X86 }, |
34 | 115 | { "i486", ARCHITECTURE_X86 }, |
35 | 115 | { "i386", ARCHITECTURE_X86 }, |
36 | | #elif defined(__powerpc__) || defined(__powerpc64__) |
37 | | { "ppc64", ARCHITECTURE_PPC64 }, |
38 | | { "ppc64le", ARCHITECTURE_PPC64_LE }, |
39 | | { "ppc", ARCHITECTURE_PPC }, |
40 | | { "ppcle", ARCHITECTURE_PPC_LE }, |
41 | | #elif defined(__ia64__) |
42 | | { "ia64", ARCHITECTURE_IA64 }, |
43 | | #elif defined(__hppa__) || defined(__hppa64__) |
44 | | { "parisc64", ARCHITECTURE_PARISC64 }, |
45 | | { "parisc", ARCHITECTURE_PARISC }, |
46 | | #elif defined(__s390__) || defined(__s390x__) |
47 | | { "s390x", ARCHITECTURE_S390X }, |
48 | | { "s390", ARCHITECTURE_S390 }, |
49 | | #elif defined(__sparc__) |
50 | | { "sparc64", ARCHITECTURE_SPARC64 }, |
51 | | { "sparc", ARCHITECTURE_SPARC }, |
52 | | #elif defined(__mips__) || defined(__mips64__) |
53 | | { "mips64", ARCHITECTURE_MIPS64 }, |
54 | | { "mips", ARCHITECTURE_MIPS }, |
55 | | #elif defined(__alpha__) |
56 | | { "alpha" , ARCHITECTURE_ALPHA }, |
57 | | #elif defined(__arm__) || defined(__aarch64__) |
58 | | { "aarch64", ARCHITECTURE_ARM64 }, |
59 | | { "aarch64_be", ARCHITECTURE_ARM64_BE }, |
60 | | { "armv4l", ARCHITECTURE_ARM }, |
61 | | { "armv4b", ARCHITECTURE_ARM_BE }, |
62 | | { "armv4tl", ARCHITECTURE_ARM }, |
63 | | { "armv4tb", ARCHITECTURE_ARM_BE }, |
64 | | { "armv5tl", ARCHITECTURE_ARM }, |
65 | | { "armv5tb", ARCHITECTURE_ARM_BE }, |
66 | | { "armv5tel", ARCHITECTURE_ARM }, |
67 | | { "armv5teb" , ARCHITECTURE_ARM_BE }, |
68 | | { "armv5tejl", ARCHITECTURE_ARM }, |
69 | | { "armv5tejb", ARCHITECTURE_ARM_BE }, |
70 | | { "armv6l", ARCHITECTURE_ARM }, |
71 | | { "armv6b", ARCHITECTURE_ARM_BE }, |
72 | | { "armv7l", ARCHITECTURE_ARM }, |
73 | | { "armv7b", ARCHITECTURE_ARM_BE }, |
74 | | { "armv7ml", ARCHITECTURE_ARM }, |
75 | | { "armv7mb", ARCHITECTURE_ARM_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 | | { "armv8l", ARCHITECTURE_ARM }, |
93 | | { "armv8b", ARCHITECTURE_ARM_BE }, |
94 | | #elif defined(__sh__) || defined(__sh64__) |
95 | | { "sh5", ARCHITECTURE_SH64 }, |
96 | | { "sh2", ARCHITECTURE_SH }, |
97 | | { "sh2a", ARCHITECTURE_SH }, |
98 | | { "sh3", ARCHITECTURE_SH }, |
99 | | { "sh4", ARCHITECTURE_SH }, |
100 | | { "sh4a", ARCHITECTURE_SH }, |
101 | | #elif defined(__m68k__) |
102 | | { "m68k", ARCHITECTURE_M68K }, |
103 | | #elif defined(__tilegx__) |
104 | | { "tilegx", ARCHITECTURE_TILEGX }, |
105 | | #elif defined(__cris__) |
106 | | { "crisv32", ARCHITECTURE_CRIS }, |
107 | | #elif defined(__nios2__) |
108 | | { "nios2", ARCHITECTURE_NIOS2 }, |
109 | | #elif defined(__riscv__) || defined(__riscv) |
110 | | /* __riscv__ is obsolete, remove in 2018 */ |
111 | | { "riscv32", ARCHITECTURE_RISCV32 }, |
112 | | { "riscv64", ARCHITECTURE_RISCV64 }, |
113 | | # if __SIZEOF_POINTER__ == 4 |
114 | | { "riscv", ARCHITECTURE_RISCV32 }, |
115 | | # elif __SIZEOF_POINTER__ == 8 |
116 | | { "riscv", ARCHITECTURE_RISCV64 }, |
117 | | # endif |
118 | | #elif defined(__arc__) |
119 | | { "arc", ARCHITECTURE_ARC }, |
120 | | { "arceb", ARCHITECTURE_ARC_BE }, |
121 | | #else |
122 | | #error "Please register your architecture here!" |
123 | | #endif |
124 | | }; |
125 | 115 | |
126 | 115 | static int cached = _ARCHITECTURE_INVALID; |
127 | 115 | struct utsname u; |
128 | 115 | unsigned i; |
129 | 115 | |
130 | 115 | if (cached != _ARCHITECTURE_INVALID) |
131 | 112 | return cached; |
132 | 3 | |
133 | 3 | assert_se(uname(&u) >= 0); |
134 | 3 | |
135 | 3 | for (i = 0; i < ELEMENTSOF(arch_map); i++) |
136 | 3 | if (streq(arch_map[i].machine, u.machine)) |
137 | 3 | return cached = arch_map[i].arch; |
138 | 3 | |
139 | 3 | assert_not_reached("Couldn't identify architecture. You need to patch systemd."); |
140 | 0 | return _ARCHITECTURE_INVALID; |
141 | 0 | } |
142 | | |
143 | | static const char *const architecture_table[_ARCHITECTURE_MAX] = { |
144 | | [ARCHITECTURE_X86] = "x86", |
145 | | [ARCHITECTURE_X86_64] = "x86-64", |
146 | | [ARCHITECTURE_PPC] = "ppc", |
147 | | [ARCHITECTURE_PPC_LE] = "ppc-le", |
148 | | [ARCHITECTURE_PPC64] = "ppc64", |
149 | | [ARCHITECTURE_PPC64_LE] = "ppc64-le", |
150 | | [ARCHITECTURE_IA64] = "ia64", |
151 | | [ARCHITECTURE_PARISC] = "parisc", |
152 | | [ARCHITECTURE_PARISC64] = "parisc64", |
153 | | [ARCHITECTURE_S390] = "s390", |
154 | | [ARCHITECTURE_S390X] = "s390x", |
155 | | [ARCHITECTURE_SPARC] = "sparc", |
156 | | [ARCHITECTURE_SPARC64] = "sparc64", |
157 | | [ARCHITECTURE_MIPS] = "mips", |
158 | | [ARCHITECTURE_MIPS_LE] = "mips-le", |
159 | | [ARCHITECTURE_MIPS64] = "mips64", |
160 | | [ARCHITECTURE_MIPS64_LE] = "mips64-le", |
161 | | [ARCHITECTURE_ALPHA] = "alpha", |
162 | | [ARCHITECTURE_ARM] = "arm", |
163 | | [ARCHITECTURE_ARM_BE] = "arm-be", |
164 | | [ARCHITECTURE_ARM64] = "arm64", |
165 | | [ARCHITECTURE_ARM64_BE] = "arm64-be", |
166 | | [ARCHITECTURE_SH] = "sh", |
167 | | [ARCHITECTURE_SH64] = "sh64", |
168 | | [ARCHITECTURE_M68K] = "m68k", |
169 | | [ARCHITECTURE_TILEGX] = "tilegx", |
170 | | [ARCHITECTURE_CRIS] = "cris", |
171 | | [ARCHITECTURE_NIOS2] = "nios2", |
172 | | [ARCHITECTURE_RISCV32] = "riscv32", |
173 | | [ARCHITECTURE_RISCV64] = "riscv64", |
174 | | [ARCHITECTURE_ARC] = "arc", |
175 | | [ARCHITECTURE_ARC_BE] = "arc-be", |
176 | | }; |
177 | | |
178 | | DEFINE_STRING_TABLE_LOOKUP(architecture, int); |