]>
Commit | Line | Data |
---|---|---|
3dcc8d3b | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
ddbcf45e WB |
2 | From: Gerd Hoffmann <kraxel@redhat.com> |
3 | Date: Fri, 1 Sep 2017 14:57:39 +0200 | |
3dcc8d3b | 4 | Subject: [PATCH] vga: stop passing pointers to vga_draw_line* functions |
ddbcf45e WB |
5 | |
6 | Instead pass around the address (aka offset into vga memory). | |
7 | Add vga_read_* helper functions which apply vbe_size_mask to | |
8 | the address, to make sure the address stays within the valid | |
9 | range, similar to the cirrus blitter fixes (commits ffaf857778 | |
10 | and 026aeffcb4). | |
11 | ||
12 | Impact: DoS for privileged guest users. qemu crashes with | |
13 | a segfault, when hitting the guard page after vga memory | |
14 | allocation, while reading vga memory for display updates. | |
15 | ||
16 | Fixes: CVE-2017-13672 | |
17 | Cc: P J P <ppandit@redhat.com> | |
18 | Reported-by: David Buchanan <d@vidbuchanan.co.uk> | |
19 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | |
20 | Message-id: 20170828122906.18993-1-kraxel@redhat.com | |
21 | --- | |
22 | hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++--------------------- | |
23 | hw/display/vga.c | 5 +- | |
24 | hw/display/vga_int.h | 1 + | |
25 | 3 files changed, 114 insertions(+), 94 deletions(-) | |
26 | ||
27 | diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h | |
28 | index 94f6de2046..5a752b3f9e 100644 | |
29 | --- a/hw/display/vga-helpers.h | |
30 | +++ b/hw/display/vga-helpers.h | |
31 | @@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize, | |
32 | } while (--h); | |
33 | } | |
34 | ||
35 | +static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr) | |
36 | +{ | |
37 | + return vga->vram_ptr[addr & vga->vbe_size_mask]; | |
38 | +} | |
39 | + | |
40 | +static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr) | |
41 | +{ | |
42 | + uint32_t offset = addr & vga->vbe_size_mask & ~1; | |
43 | + uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset); | |
44 | + return lduw_le_p(ptr); | |
45 | +} | |
46 | + | |
47 | +static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr) | |
48 | +{ | |
49 | + uint32_t offset = addr & vga->vbe_size_mask & ~1; | |
50 | + uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset); | |
51 | + return lduw_be_p(ptr); | |
52 | +} | |
53 | + | |
54 | +static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr) | |
55 | +{ | |
56 | + uint32_t offset = addr & vga->vbe_size_mask & ~3; | |
57 | + uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset); | |
58 | + return ldl_le_p(ptr); | |
59 | +} | |
60 | + | |
61 | /* | |
62 | * 4 color mode | |
63 | */ | |
64 | -static void vga_draw_line2(VGACommonState *s1, uint8_t *d, | |
65 | - const uint8_t *s, int width) | |
66 | +static void vga_draw_line2(VGACommonState *vga, uint8_t *d, | |
67 | + uint32_t addr, int width) | |
68 | { | |
69 | uint32_t plane_mask, *palette, data, v; | |
70 | int x; | |
71 | ||
72 | - palette = s1->last_palette; | |
73 | - plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
74 | + palette = vga->last_palette; | |
75 | + plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
76 | width >>= 3; | |
77 | for(x = 0; x < width; x++) { | |
78 | - data = ((uint32_t *)s)[0]; | |
79 | + data = vga_read_dword_le(vga, addr); | |
80 | data &= plane_mask; | |
81 | v = expand2[GET_PLANE(data, 0)]; | |
82 | v |= expand2[GET_PLANE(data, 2)] << 2; | |
83 | @@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d, | |
84 | ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; | |
85 | ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; | |
86 | d += 32; | |
87 | - s += 4; | |
88 | + addr += 4; | |
89 | } | |
90 | } | |
91 | ||
92 | @@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d, | |
93 | /* | |
94 | * 4 color mode, dup2 horizontal | |
95 | */ | |
96 | -static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, | |
97 | - const uint8_t *s, int width) | |
98 | +static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d, | |
99 | + uint32_t addr, int width) | |
100 | { | |
101 | uint32_t plane_mask, *palette, data, v; | |
102 | int x; | |
103 | ||
104 | - palette = s1->last_palette; | |
105 | - plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
106 | + palette = vga->last_palette; | |
107 | + plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
108 | width >>= 3; | |
109 | for(x = 0; x < width; x++) { | |
110 | - data = ((uint32_t *)s)[0]; | |
111 | + data = vga_read_dword_le(vga, addr); | |
112 | data &= plane_mask; | |
113 | v = expand2[GET_PLANE(data, 0)]; | |
114 | v |= expand2[GET_PLANE(data, 2)] << 2; | |
115 | @@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, | |
116 | PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); | |
117 | PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); | |
118 | d += 64; | |
119 | - s += 4; | |
120 | + addr += 4; | |
121 | } | |
122 | } | |
123 | ||
124 | /* | |
125 | * 16 color mode | |
126 | */ | |
127 | -static void vga_draw_line4(VGACommonState *s1, uint8_t *d, | |
128 | - const uint8_t *s, int width) | |
129 | +static void vga_draw_line4(VGACommonState *vga, uint8_t *d, | |
130 | + uint32_t addr, int width) | |
131 | { | |
132 | uint32_t plane_mask, data, v, *palette; | |
133 | int x; | |
134 | ||
135 | - palette = s1->last_palette; | |
136 | - plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
137 | + palette = vga->last_palette; | |
138 | + plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
139 | width >>= 3; | |
140 | for(x = 0; x < width; x++) { | |
141 | - data = ((uint32_t *)s)[0]; | |
142 | + data = vga_read_dword_le(vga, addr); | |
143 | data &= plane_mask; | |
144 | v = expand4[GET_PLANE(data, 0)]; | |
145 | v |= expand4[GET_PLANE(data, 1)] << 1; | |
146 | @@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d, | |
147 | ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; | |
148 | ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; | |
149 | d += 32; | |
150 | - s += 4; | |
151 | + addr += 4; | |
152 | } | |
153 | } | |
154 | ||
155 | /* | |
156 | * 16 color mode, dup2 horizontal | |
157 | */ | |
158 | -static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, | |
159 | - const uint8_t *s, int width) | |
160 | +static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d, | |
161 | + uint32_t addr, int width) | |
162 | { | |
163 | uint32_t plane_mask, data, v, *palette; | |
164 | int x; | |
165 | ||
166 | - palette = s1->last_palette; | |
167 | - plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
168 | + palette = vga->last_palette; | |
169 | + plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; | |
170 | width >>= 3; | |
171 | for(x = 0; x < width; x++) { | |
172 | - data = ((uint32_t *)s)[0]; | |
173 | + data = vga_read_dword_le(vga, addr); | |
174 | data &= plane_mask; | |
175 | v = expand4[GET_PLANE(data, 0)]; | |
176 | v |= expand4[GET_PLANE(data, 1)] << 1; | |
177 | @@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, | |
178 | PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); | |
179 | PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); | |
180 | d += 64; | |
181 | - s += 4; | |
182 | + addr += 4; | |
183 | } | |
184 | } | |
185 | ||
186 | @@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, | |
187 | * | |
188 | * XXX: add plane_mask support (never used in standard VGA modes) | |
189 | */ | |
190 | -static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, | |
191 | - const uint8_t *s, int width) | |
192 | +static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d, | |
193 | + uint32_t addr, int width) | |
194 | { | |
195 | uint32_t *palette; | |
196 | int x; | |
197 | ||
198 | - palette = s1->last_palette; | |
199 | + palette = vga->last_palette; | |
200 | width >>= 3; | |
201 | for(x = 0; x < width; x++) { | |
202 | - PUT_PIXEL2(d, 0, palette[s[0]]); | |
203 | - PUT_PIXEL2(d, 1, palette[s[1]]); | |
204 | - PUT_PIXEL2(d, 2, palette[s[2]]); | |
205 | - PUT_PIXEL2(d, 3, palette[s[3]]); | |
206 | + PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]); | |
207 | + PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]); | |
208 | + PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]); | |
209 | + PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]); | |
210 | d += 32; | |
211 | - s += 4; | |
212 | + addr += 4; | |
213 | } | |
214 | } | |
215 | ||
216 | @@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, | |
217 | * | |
218 | * XXX: add plane_mask support (never used in standard VGA modes) | |
219 | */ | |
220 | -static void vga_draw_line8(VGACommonState *s1, uint8_t *d, | |
221 | - const uint8_t *s, int width) | |
222 | +static void vga_draw_line8(VGACommonState *vga, uint8_t *d, | |
223 | + uint32_t addr, int width) | |
224 | { | |
225 | uint32_t *palette; | |
226 | int x; | |
227 | ||
228 | - palette = s1->last_palette; | |
229 | + palette = vga->last_palette; | |
230 | width >>= 3; | |
231 | for(x = 0; x < width; x++) { | |
232 | - ((uint32_t *)d)[0] = palette[s[0]]; | |
233 | - ((uint32_t *)d)[1] = palette[s[1]]; | |
234 | - ((uint32_t *)d)[2] = palette[s[2]]; | |
235 | - ((uint32_t *)d)[3] = palette[s[3]]; | |
236 | - ((uint32_t *)d)[4] = palette[s[4]]; | |
237 | - ((uint32_t *)d)[5] = palette[s[5]]; | |
238 | - ((uint32_t *)d)[6] = palette[s[6]]; | |
239 | - ((uint32_t *)d)[7] = palette[s[7]]; | |
240 | + ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)]; | |
241 | + ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)]; | |
242 | + ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)]; | |
243 | + ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)]; | |
244 | + ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)]; | |
245 | + ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)]; | |
246 | + ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)]; | |
247 | + ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)]; | |
248 | d += 32; | |
249 | - s += 8; | |
250 | + addr += 8; | |
251 | } | |
252 | } | |
253 | ||
254 | /* | |
255 | * 15 bit color | |
256 | */ | |
257 | -static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, | |
258 | - const uint8_t *s, int width) | |
259 | +static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d, | |
260 | + uint32_t addr, int width) | |
261 | { | |
262 | int w; | |
263 | uint32_t v, r, g, b; | |
264 | ||
265 | w = width; | |
266 | do { | |
267 | - v = lduw_le_p((void *)s); | |
268 | + v = vga_read_word_le(vga, addr); | |
269 | r = (v >> 7) & 0xf8; | |
270 | g = (v >> 2) & 0xf8; | |
271 | b = (v << 3) & 0xf8; | |
272 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
273 | - s += 2; | |
274 | + addr += 2; | |
275 | d += 4; | |
276 | } while (--w != 0); | |
277 | } | |
278 | ||
279 | -static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, | |
280 | - const uint8_t *s, int width) | |
281 | +static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d, | |
282 | + uint32_t addr, int width) | |
283 | { | |
284 | int w; | |
285 | uint32_t v, r, g, b; | |
286 | ||
287 | w = width; | |
288 | do { | |
289 | - v = lduw_be_p((void *)s); | |
290 | + v = vga_read_word_be(vga, addr); | |
291 | r = (v >> 7) & 0xf8; | |
292 | g = (v >> 2) & 0xf8; | |
293 | b = (v << 3) & 0xf8; | |
294 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
295 | - s += 2; | |
296 | + addr += 2; | |
297 | d += 4; | |
298 | } while (--w != 0); | |
299 | } | |
300 | @@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, | |
301 | /* | |
302 | * 16 bit color | |
303 | */ | |
304 | -static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, | |
305 | - const uint8_t *s, int width) | |
306 | +static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d, | |
307 | + uint32_t addr, int width) | |
308 | { | |
309 | int w; | |
310 | uint32_t v, r, g, b; | |
311 | ||
312 | w = width; | |
313 | do { | |
314 | - v = lduw_le_p((void *)s); | |
315 | + v = vga_read_word_le(vga, addr); | |
316 | r = (v >> 8) & 0xf8; | |
317 | g = (v >> 3) & 0xfc; | |
318 | b = (v << 3) & 0xf8; | |
319 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
320 | - s += 2; | |
321 | + addr += 2; | |
322 | d += 4; | |
323 | } while (--w != 0); | |
324 | } | |
325 | ||
326 | -static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, | |
327 | - const uint8_t *s, int width) | |
328 | +static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d, | |
329 | + uint32_t addr, int width) | |
330 | { | |
331 | int w; | |
332 | uint32_t v, r, g, b; | |
333 | ||
334 | w = width; | |
335 | do { | |
336 | - v = lduw_be_p((void *)s); | |
337 | + v = vga_read_word_be(vga, addr); | |
338 | r = (v >> 8) & 0xf8; | |
339 | g = (v >> 3) & 0xfc; | |
340 | b = (v << 3) & 0xf8; | |
341 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
342 | - s += 2; | |
343 | + addr += 2; | |
344 | d += 4; | |
345 | } while (--w != 0); | |
346 | } | |
347 | @@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, | |
348 | /* | |
349 | * 24 bit color | |
350 | */ | |
351 | -static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, | |
352 | - const uint8_t *s, int width) | |
353 | +static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d, | |
354 | + uint32_t addr, int width) | |
355 | { | |
356 | int w; | |
357 | uint32_t r, g, b; | |
358 | ||
359 | w = width; | |
360 | do { | |
361 | - b = s[0]; | |
362 | - g = s[1]; | |
363 | - r = s[2]; | |
364 | + b = vga_read_byte(vga, addr + 0); | |
365 | + g = vga_read_byte(vga, addr + 1); | |
366 | + r = vga_read_byte(vga, addr + 2); | |
367 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
368 | - s += 3; | |
369 | + addr += 3; | |
370 | d += 4; | |
371 | } while (--w != 0); | |
372 | } | |
373 | ||
374 | -static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, | |
375 | - const uint8_t *s, int width) | |
376 | +static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d, | |
377 | + uint32_t addr, int width) | |
378 | { | |
379 | int w; | |
380 | uint32_t r, g, b; | |
381 | ||
382 | w = width; | |
383 | do { | |
384 | - r = s[0]; | |
385 | - g = s[1]; | |
386 | - b = s[2]; | |
387 | + r = vga_read_byte(vga, addr + 0); | |
388 | + g = vga_read_byte(vga, addr + 1); | |
389 | + b = vga_read_byte(vga, addr + 2); | |
390 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
391 | - s += 3; | |
392 | + addr += 3; | |
393 | d += 4; | |
394 | } while (--w != 0); | |
395 | } | |
396 | @@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, | |
397 | /* | |
398 | * 32 bit color | |
399 | */ | |
400 | -static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, | |
401 | - const uint8_t *s, int width) | |
402 | +static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d, | |
403 | + uint32_t addr, int width) | |
404 | { | |
405 | -#ifndef HOST_WORDS_BIGENDIAN | |
406 | - memcpy(d, s, width * 4); | |
407 | -#else | |
408 | int w; | |
409 | uint32_t r, g, b; | |
410 | ||
411 | w = width; | |
412 | do { | |
413 | - b = s[0]; | |
414 | - g = s[1]; | |
415 | - r = s[2]; | |
416 | + b = vga_read_byte(vga, addr + 0); | |
417 | + g = vga_read_byte(vga, addr + 1); | |
418 | + r = vga_read_byte(vga, addr + 2); | |
419 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
420 | - s += 4; | |
421 | + addr += 4; | |
422 | d += 4; | |
423 | } while (--w != 0); | |
424 | -#endif | |
425 | } | |
426 | ||
427 | -static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, | |
428 | - const uint8_t *s, int width) | |
429 | +static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d, | |
430 | + uint32_t addr, int width) | |
431 | { | |
432 | -#ifdef HOST_WORDS_BIGENDIAN | |
433 | - memcpy(d, s, width * 4); | |
434 | -#else | |
435 | int w; | |
436 | uint32_t r, g, b; | |
437 | ||
438 | w = width; | |
439 | do { | |
440 | - r = s[1]; | |
441 | - g = s[2]; | |
442 | - b = s[3]; | |
443 | + r = vga_read_byte(vga, addr + 1); | |
444 | + g = vga_read_byte(vga, addr + 2); | |
445 | + b = vga_read_byte(vga, addr + 3); | |
446 | ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); | |
447 | - s += 4; | |
448 | + addr += 4; | |
449 | d += 4; | |
450 | } while (--w != 0); | |
451 | -#endif | |
452 | } | |
453 | diff --git a/hw/display/vga.c b/hw/display/vga.c | |
454 | index 533d8d7895..13e4a5d55d 100644 | |
455 | --- a/hw/display/vga.c | |
456 | +++ b/hw/display/vga.c | |
457 | @@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) | |
458 | } | |
459 | ||
460 | typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, | |
461 | - const uint8_t *s, int width); | |
462 | + uint32_t srcaddr, int width); | |
463 | ||
464 | #include "vga-helpers.h" | |
465 | ||
466 | @@ -1666,7 +1666,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) | |
467 | if (y_start < 0) | |
468 | y_start = y; | |
469 | if (!(is_buffer_shared(surface))) { | |
470 | - vga_draw_line(s, d, s->vram_ptr + addr, width); | |
471 | + vga_draw_line(s, d, addr, width); | |
472 | if (s->cursor_draw_line) | |
473 | s->cursor_draw_line(s, d, y); | |
474 | } | |
475 | @@ -2170,6 +2170,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) | |
476 | if (!s->vbe_size) { | |
477 | s->vbe_size = s->vram_size; | |
478 | } | |
479 | + s->vbe_size_mask = s->vbe_size - 1; | |
480 | ||
481 | s->is_vbe_vmstate = 1; | |
482 | memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size, | |
483 | diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h | |
484 | index dd6c958da3..ad34a1f048 100644 | |
485 | --- a/hw/display/vga_int.h | |
486 | +++ b/hw/display/vga_int.h | |
487 | @@ -94,6 +94,7 @@ typedef struct VGACommonState { | |
488 | uint32_t vram_size; | |
489 | uint32_t vram_size_mb; /* property */ | |
490 | uint32_t vbe_size; | |
491 | + uint32_t vbe_size_mask; | |
492 | uint32_t latch; | |
493 | bool has_chain4_alias; | |
494 | MemoryRegion chain4_alias; | |
495 | -- | |
496 | 2.11.0 | |
497 |