test.c (4740B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifdef DEF 6 DEF(This) 7 DEF(is) 8 DEF(a) 9 DEF(test) 10 DEF(of) 11 DEF(string) 12 DEF(array) 13 DEF(for) 14 DEF(use) 15 DEF(with) 16 DEF(elfhack) 17 DEF(to) 18 DEF(see) 19 DEF(whether) 20 DEF(it) 21 DEF(breaks) 22 DEF(anything) 23 DEF(but) 24 DEF(one) 25 DEF(needs) 26 DEF(quite) 27 DEF(some) 28 DEF(strings) 29 DEF(before) 30 DEF(the) 31 DEF(program) 32 DEF(can) 33 DEF(do) 34 DEF(its) 35 DEF(work) 36 DEF(efficiently) 37 DEF(Without) 38 DEF(enough) 39 DEF(data) 40 DEF(relocation) 41 DEF(sections) 42 DEF(are) 43 // clang-format off 44 DEF(not) 45 // clang-format on 46 DEF(sufficiently) 47 DEF(large) 48 DEF(and) 49 DEF(injected) 50 DEF(code) 51 DEF(wouldnt) 52 DEF(fit) 53 DEF(Said) 54 DEF(otherwise) 55 DEF(we) 56 DEF(need) 57 DEF(more) 58 DEF(words) 59 DEF(than) 60 DEF(up) 61 DEF(here) 62 DEF(so) 63 DEF(that) 64 DEF(relocations) 65 DEF(take) 66 DEF(significant) 67 DEF(bytes) 68 DEF(amounts) 69 DEF(which) 70 DEF(isnt) 71 DEF(exactly) 72 DEF(easily) 73 DEF(achieved) 74 DEF(like) 75 DEF(this) 76 DEF(Actually) 77 DEF(I) 78 DEF(must) 79 DEF(cheat) 80 DEF(by) 81 DEF(including) 82 DEF(these) 83 DEF(phrases) 84 DEF(several) 85 DEF(times) 86 87 #else 88 # pragma GCC visibility push(default) 89 # include <stdlib.h> 90 # include <stdio.h> 91 92 # define DEF(w) static const char str_##w[] = #w; 93 # include "test.c" 94 # undef DEF 95 96 const char* strings[] = { 97 # define DEF(w) str_##w, 98 # include "test.c" 99 # include "test.c" 100 # include "test.c" 101 }; 102 103 /* Create a hole between two zones of relative relocations */ 104 int small_hole[] = {42, 42, 42, 42}; 105 106 const char* strings2[] = { 107 # include "test.c" 108 # include "test.c" 109 # include "test.c" 110 # include "test.c" 111 # include "test.c" 112 }; 113 114 /* Create a bigger hole between two zones of relative relocations */ 115 int bigger_hole[] = { 116 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 117 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 118 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 119 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 120 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 121 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 122 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 123 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 124 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 125 }; 126 127 const char* strings3[] = { 128 # include "test.c" 129 # include "test.c" 130 # include "test.c" 131 # include "test.c" 132 # include "test.c" 133 # include "test.c" 134 # include "test.c" 135 # include "test.c" 136 # include "test.c" 137 # include "test.c" 138 # include "test.c" 139 # include "test.c" 140 # include "test.c" 141 # include "test.c" 142 # include "test.c" 143 # include "test.c" 144 # include "test.c" 145 # include "test.c" 146 # include "test.c" 147 # include "test.c" 148 # include "test.c" 149 # include "test.c" 150 # include "test.c" 151 # include "test.c" 152 # include "test.c" 153 # include "test.c" 154 # include "test.c" 155 # undef DEF 156 }; 157 158 static int ret = 1; 159 160 int print_status() { 161 fprintf(stderr, "%s\n", ret ? "FAIL" : "PASS"); 162 return ret; 163 } 164 165 /* On ARM, this creates a .tbss section before .init_array, which 166 * elfhack could then pick instead of .init_array. 167 * Also, when .tbss is big enough, elfhack may wrongfully consider 168 * following sections as part of the PT_TLS segment. 169 * Finally, gold makes TLS segments end on an aligned virtual address, 170 * even when the underlying section ends before that, and elfhack 171 * sanity checks may yield an error. */ 172 __thread int foo; 173 __thread long long int bar[512]; 174 175 /* We need a .bss that can hold at least 2 pointers. The static in 176 * end_test() plus this variable should do. */ 177 size_t dummy; 178 179 void end_test() { 180 static size_t count = 0; 181 /* Only exit when both constructors have been called */ 182 if (++count == 2) { 183 ret = 0; 184 // Avoid the dummy variable being stripped out at link time because 185 // it's unused. 186 dummy = 1; 187 } 188 } 189 190 void test() { 191 int i = 0, j = 0, k = 0; 192 # define DEF_(a, i, w) \ 193 if (a[i++] != str_##w) return; 194 # define DEF(w) DEF_(strings, i, w) 195 # include "test.c" 196 # include "test.c" 197 # include "test.c" 198 # undef DEF 199 # define DEF(w) DEF_(strings2, j, w) 200 # include "test.c" 201 # include "test.c" 202 # include "test.c" 203 # include "test.c" 204 # include "test.c" 205 # undef DEF 206 # define DEF(w) DEF_(strings3, k, w) 207 # include "test.c" 208 # include "test.c" 209 # include "test.c" 210 # include "test.c" 211 # include "test.c" 212 # undef DEF 213 if (i != sizeof(strings) / sizeof(strings[0]) && 214 j != sizeof(strings2) / sizeof(strings2[0]) && 215 k != sizeof(strings3) / sizeof(strings3[0])) 216 fprintf(stderr, "WARNING: Test doesn't cover the whole array\n"); 217 end_test(); 218 } 219 220 # pragma GCC visibility pop 221 #endif