1 | __#ifndef UTILS_H__ |

2 | __#define UTILS_H__ |

3 | |

4 | **inline** *void* break_optimization(*void* *arg) { |

5 | **__asm__** *__volatile__*("" : : "r" (arg) : "memory" ); |

6 | } |

7 | |

8 | *// Tests will instantiate this class to pad out bit sets to test out the* |

9 | *// various ways we can represent the bit set (32-bit inline, 64-bit inline,* |

10 | *// memory). Instantiating this class will trigger the instantiation of I* |

11 | *// templates with I virtual tables for classes deriving from T, I-2 of which* |

12 | *// will be of size sizeof(void*) * 5, 1 of which will be of size sizeof(void*)* |

13 | *// * 3, and 1 of which will be of size sizeof(void*) * 9. (Under the MS ABI* |

14 | *// each virtual table will be sizeof(void*) bytes smaller). Each category* |

15 | *// of virtual tables is aligned to a different power of 2, precluding the* |

16 | *// all-ones optimization. As a result, the bit vector for the base class will* |

17 | *// need to contain at least I*2 entries to accommodate all the derived virtual* |

18 | *// tables.* |

19 | **template** <**typename** T, *unsigned* I> |

20 | **struct** Deriver : T { |

21 | Deriver() { |

22 | break_optimization(**new** Deriver<T, I-`1`>); |

23 | } |

24 | **virtual** *void* f() {} |

25 | **virtual** *void* g() {} |

26 | **virtual** *void* h() {} |

27 | }; |

28 | |

29 | **template** <**typename** T> |

30 | **struct** Deriver<T, `0`> : T { |

31 | **virtual** *void* f() {} |

32 | *void* g() {} |

33 | }; |

34 | |

35 | **template** <**typename** T> |

36 | **struct** Deriver<T, `1`> : T { |

37 | Deriver() { |

38 | break_optimization(**new** Deriver<T, `0`>); |

39 | } |

40 | **virtual** *void* f() {} |

41 | **virtual** *void* g() {} |

42 | **virtual** *void* h() {} |

43 | **virtual** *void* i() {} |

44 | **virtual** *void* j() {} |

45 | **virtual** *void* k() {} |

46 | **virtual** *void* l() {} |

47 | }; |

48 | |

49 | *// Instantiate enough classes to force CFI checks for type T to use bit* |

50 | *// vectors of size 32 (if B32 defined), 64 (if B64 defined) or >64 (if BM* |

51 | *// defined).* |

52 | **template** <**typename** T> |

53 | *void* create_derivers() { |

54 | __#ifdef B32__ |

55 | break_optimization(**new** Deriver<T, `10`>); |

56 | __#endif__ |

57 | |

58 | __#ifdef B64__ |

59 | break_optimization(**new** Deriver<T, `25`>); |

60 | __#endif__ |

61 | |

62 | __#ifdef BM__ |

63 | break_optimization(**new** Deriver<T, `40`>); |

64 | __#endif__ |

65 | } |

66 | |

67 | __#endif__ |

68 | |