dereference: fix a crash
[smatch.git] / target.c
blob8ae22d744f40344fa9c98f2e1ae8c63de8f6a60b
1 #include <stdio.h>
2 #include <string.h>
4 #include "symbol.h"
5 #include "target.h"
6 #include "machine.h"
8 struct symbol *ptrdiff_ctype;
9 struct symbol *intptr_ctype;
10 struct symbol *uintptr_ctype;
11 struct symbol *size_t_ctype = &ulong_ctype;
12 struct symbol *ssize_t_ctype = &long_ctype;
13 struct symbol *intmax_ctype = &long_ctype;
14 struct symbol *uintmax_ctype = &ulong_ctype;
15 struct symbol *int64_ctype = &long_ctype;
16 struct symbol *uint64_ctype = &ulong_ctype;
17 struct symbol *int32_ctype = &int_ctype;
18 struct symbol *uint32_ctype = &uint_ctype;
19 struct symbol *wchar_ctype = &int_ctype;
20 struct symbol *wint_ctype = &uint_ctype;
21 struct symbol *least8_ctype = &schar_ctype;
22 struct symbol *uleast8_ctype = &uchar_ctype;
23 struct symbol *least16_ctype = &short_ctype;
24 struct symbol *uleast16_ctype = &ushort_ctype;
25 struct symbol *least32_ctype = &int_ctype;
26 struct symbol *uleast32_ctype = &uint_ctype;
27 struct symbol *least64_ctype = &llong_ctype;
28 struct symbol *uleast64_ctype = &ullong_ctype;
29 struct symbol *fast8_ctype = &schar_ctype;
30 struct symbol *ufast8_ctype = &uchar_ctype;
31 struct symbol *fast16_ctype = &long_ctype;
32 struct symbol *ufast16_ctype = &ulong_ctype;
33 struct symbol *fast32_ctype = &long_ctype;
34 struct symbol *ufast32_ctype = &ulong_ctype;
35 struct symbol *fast64_ctype = &long_ctype;
36 struct symbol *ufast64_ctype = &ulong_ctype;
37 struct symbol *sig_atomic_ctype = &int_ctype;
40 * For "__attribute__((aligned))"
42 int max_alignment = 16;
45 * Integer data types
47 int bits_in_bool = 1;
48 int bits_in_char = 8;
49 int bits_in_short = 16;
50 int bits_in_int = 32;
51 int bits_in_long = 64;
52 int bits_in_longlong = 64;
53 int bits_in_longlonglong = 128;
55 int max_int_alignment = 8;
58 * Floating point data types
60 int bits_in_float = 32;
61 int bits_in_double = 64;
62 int bits_in_longdouble = 128;
64 int max_fp_alignment = 16;
67 * Pointer data type
69 int bits_in_pointer = 64;
70 int pointer_alignment = 8;
73 * Enum data types
75 int bits_in_enum = 32;
76 int enum_alignment = 4;
79 static const struct target *targets[] = {
80 [MACH_ALPHA] = &target_alpha,
81 [MACH_ARM] = &target_arm,
82 [MACH_ARM64] = &target_arm64,
83 [MACH_BFIN] = &target_bfin,
84 [MACH_H8300] = &target_h8300,
85 [MACH_I386] = &target_i386,
86 [MACH_M68K] = &target_m68k,
87 [MACH_MICROBLAZE] = &target_microblaze,
88 [MACH_MIPS32] = &target_mips32,
89 [MACH_MIPS64] = &target_mips64,
90 [MACH_NDS32] = &target_nds32,
91 [MACH_NIOS2] = &target_nios2,
92 [MACH_OPENRISC] = &target_openrisc,
93 [MACH_PPC32] = &target_ppc32,
94 [MACH_PPC64] = &target_ppc64,
95 [MACH_RISCV32] = &target_riscv32,
96 [MACH_RISCV64] = &target_riscv64,
97 [MACH_S390] = &target_s390,
98 [MACH_S390X] = &target_s390x,
99 [MACH_SH] = &target_sh,
100 [MACH_SPARC32] = &target_sparc32,
101 [MACH_SPARC64] = &target_sparc64,
102 [MACH_X86_64] = &target_x86_64,
103 [MACH_XTENSA] = &target_xtensa,
104 [MACH_UNKNOWN] = &target_default,
106 const struct target *arch_target = &target_default;
108 enum machine target_parse(const char *name)
110 static const struct arch {
111 const char *name;
112 enum machine mach;
113 char bits;
114 } archs[] = {
115 { "alpha", MACH_ALPHA, 64, },
116 { "aarch64", MACH_ARM64, 64, },
117 { "arm64", MACH_ARM64, 64, },
118 { "arm", MACH_ARM, 32, },
119 { "bfin", MACH_BFIN, 32, },
120 { "h8300", MACH_H8300, 32, },
121 { "i386", MACH_I386, 32, },
122 { "m68k", MACH_M68K, 32, },
123 { "microblaze", MACH_MICROBLAZE,32, },
124 { "mips", MACH_MIPS32, 0, },
125 { "nds32", MACH_NDS32, 32, },
126 { "nios2", MACH_NIOS2, 32, },
127 { "openrisc", MACH_OPENRISC, 32, },
128 { "powerpc", MACH_PPC32, 0, },
129 { "ppc", MACH_PPC32, 0, },
130 { "riscv", MACH_RISCV32, 0, },
131 { "s390x", MACH_S390X, 64, },
132 { "s390", MACH_S390, 32, },
133 { "sparc", MACH_SPARC32, 0, },
134 { "x86_64", MACH_X86_64, 64, },
135 { "x86-64", MACH_X86_64, 64, },
136 { "sh", MACH_SH, 32, },
137 { "xtensa", MACH_XTENSA, 32, },
138 { NULL },
140 const struct arch *p;
142 for (p = &archs[0]; p->name; p++) {
143 size_t len = strlen(p->name);
144 if (strncmp(p->name, name, len) == 0) {
145 enum machine mach = p->mach;
146 const char *suf = name + len;
147 int bits = p->bits;
149 if (bits == 0) {
150 if (!strcmp(suf, "") || !strcmp(suf, "32")) {
152 } else if (!strcmp(suf, "64")) {
153 mach += 1;
154 } else {
155 die("invalid architecture: %s", name);
157 } else {
158 if (strcmp(suf, ""))
159 die("invalid architecture: %s", name);
162 return mach;
166 return MACH_UNKNOWN;
169 void target_os(const char *name)
171 static const struct os {
172 const char *name;
173 int os;
174 } oses[] = {
175 { "cygwin", OS_CYGWIN },
176 { "darwin", OS_DARWIN },
177 { "freebsd", OS_FREEBSD },
178 { "linux", OS_LINUX },
179 { "native", OS_NATIVE, },
180 { "netbsd", OS_NETBSD },
181 { "none", OS_NONE },
182 { "openbsd", OS_OPENBSD },
183 { "sunos", OS_SUNOS },
184 { "unix", OS_UNIX },
185 { NULL },
186 }, *p;
188 for (p = &oses[0]; p->name; p++) {
189 if (!strcmp(p->name, name)) {
190 arch_os = p->os;
191 return;
195 die("invalid os: %s", name);
199 void target_config(enum machine mach)
201 const struct target *target = targets[mach];
203 arch_target = target;
204 arch_m64 = target->bitness;
205 arch_big_endian = target->big_endian;
207 funsigned_char = target->unsigned_char;
211 void target_init(void)
213 const struct target *target = arch_target;
215 switch (arch_m64) {
216 case ARCH_X32:
217 if (target->target_x32bit)
218 target = target->target_x32bit;
219 goto case_32bit;
221 case ARCH_LP32:
222 max_int_alignment = 4;
223 if (target->target_32bit)
224 target = target->target_32bit;
225 /* fallthrough */
226 case_32bit:
227 bits_in_long = 32;
228 bits_in_pointer = 32;
229 pointer_alignment = 4;
230 size_t_ctype = &uint_ctype;
231 ssize_t_ctype = &int_ctype;
232 int64_ctype = &llong_ctype;
233 uint64_ctype = &ullong_ctype;
234 intmax_ctype = &llong_ctype;
235 uintmax_ctype = &ullong_ctype;
236 fast64_ctype = &llong_ctype;
237 ufast64_ctype = &ullong_ctype;
238 break;
240 case ARCH_LLP64:
241 bits_in_long = 32;
242 size_t_ctype = &ullong_ctype;
243 ssize_t_ctype = &llong_ctype;
244 int64_ctype = &llong_ctype;
245 uint64_ctype = &ullong_ctype;
246 intmax_ctype = &llong_ctype;
247 uintmax_ctype = &ullong_ctype;
248 /* fallthrough */
249 case ARCH_LP64:
250 if (target->target_64bit)
251 target = target->target_64bit;
252 break;
254 arch_target = target;
256 if (fpie > fpic)
257 fpic = fpie;
259 if (target->wchar)
260 wchar_ctype = target->wchar;
261 if (target->wint)
262 wint_ctype = target->wint;
263 if (target->bits_in_longdouble)
264 bits_in_longdouble = target->bits_in_longdouble;
265 if (target->max_fp_alignment)
266 max_fp_alignment = target->max_fp_alignment;
268 if (target->init)
269 target->init(target);
271 if (arch_msize_long || target->size_t_long) {
272 size_t_ctype = &ulong_ctype;
273 ssize_t_ctype = &long_ctype;
275 if (fshort_wchar)
276 wchar_ctype = &ushort_ctype;