| @@ -47,26 +47,54 @@ | | | @@ -47,26 +47,54 @@ |
47 | | | 47 | |
48 | static int | | 48 | static int |
49 | open_kcov(void) | | 49 | open_kcov(void) |
50 | { | | 50 | { |
51 | int fd; | | 51 | int fd; |
52 | | | 52 | |
53 | fd = open("/dev/kcov", O_RDWR); | | 53 | fd = open("/dev/kcov", O_RDWR); |
54 | if (fd == -1) | | 54 | if (fd == -1) |
55 | atf_tc_skip("Failed to open /dev/kcov"); | | 55 | atf_tc_skip("Failed to open /dev/kcov"); |
56 | | | 56 | |
57 | return fd; | | 57 | return fd; |
58 | } | | 58 | } |
59 | | | 59 | |
| | | 60 | static int |
| | | 61 | pick_unassigned_fd(int greater_than_fd) |
| | | 62 | { |
| | | 63 | int fd2; |
| | | 64 | |
| | | 65 | fd2 = greater_than_fd; |
| | | 66 | do { |
| | | 67 | ++fd2; |
| | | 68 | } while (fcntl(fd2, F_GETFL) != -1 || errno != EBADF); |
| | | 69 | |
| | | 70 | return fd2; |
| | | 71 | } |
| | | 72 | |
| | | 73 | ATF_TC_WITHOUT_HEAD(kcov_dup2); |
| | | 74 | ATF_TC_BODY(kcov_dup2, tc) |
| | | 75 | { |
| | | 76 | int fd1, fd2; |
| | | 77 | fd1 = open_kcov(); |
| | | 78 | |
| | | 79 | fd2 = pick_unassigned_fd(fd1); |
| | | 80 | |
| | | 81 | /* Test the dup2(2) trick used by syzkaller */ |
| | | 82 | ATF_REQUIRE_EQ(dup2(fd1, fd2), fd2); |
| | | 83 | |
| | | 84 | close(fd1); |
| | | 85 | close(fd2); |
| | | 86 | } |
| | | 87 | |
60 | ATF_TC_WITHOUT_HEAD(kcov_multiopen); | | 88 | ATF_TC_WITHOUT_HEAD(kcov_multiopen); |
61 | ATF_TC_BODY(kcov_multiopen, tc) | | 89 | ATF_TC_BODY(kcov_multiopen, tc) |
62 | { | | 90 | { |
63 | int fd1, fd2; | | 91 | int fd1, fd2; |
64 | fd1 = open_kcov(); | | 92 | fd1 = open_kcov(); |
65 | | | 93 | |
66 | fd2 = open("/dev/kcov", O_RDWR); | | 94 | fd2 = open("/dev/kcov", O_RDWR); |
67 | ATF_REQUIRE(fd2 != -1); | | 95 | ATF_REQUIRE(fd2 != -1); |
68 | | | 96 | |
69 | close(fd1); | | 97 | close(fd1); |
70 | close(fd2); | | 98 | close(fd2); |
71 | } | | 99 | } |
72 | | | 100 | |
| @@ -206,31 +234,27 @@ ATF_TC_BODY(kcov_enable, tc) | | | @@ -206,31 +234,27 @@ ATF_TC_BODY(kcov_enable, tc) |
206 | ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0); | | 234 | ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0); |
207 | | | 235 | |
208 | /* We need to enable before disable */ | | 236 | /* We need to enable before disable */ |
209 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1); | | 237 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1); |
210 | | | 238 | |
211 | /* Check enabling works only with a valid trace method */ | | 239 | /* Check enabling works only with a valid trace method */ |
212 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | 240 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); |
213 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1); | | 241 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1); |
214 | | | 242 | |
215 | /* Disable should only be called once */ | | 243 | /* Disable should only be called once */ |
216 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); | | 244 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); |
217 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1); | | 245 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1); |
218 | | | 246 | |
219 | /* Re-enabling should also work */ | | 247 | /* Re-enabling and changing mode should also work */ |
220 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | | |
221 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); | | | |
222 | | | | |
223 | /* Re-enablibling and changing mode should also work */ | | | |
224 | mode = KCOV_MODE_NONE; | | 248 | mode = KCOV_MODE_NONE; |
225 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | 249 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); |
226 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); | | 250 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); |
227 | mode = KCOV_MODE_TRACE_PC; | | 251 | mode = KCOV_MODE_TRACE_PC; |
228 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | 252 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); |
229 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); | | 253 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); |
230 | mode = KCOV_MODE_TRACE_CMP; | | 254 | mode = KCOV_MODE_TRACE_CMP; |
231 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | 255 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); |
232 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); | | 256 | ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0); |
233 | | | 257 | |
234 | close(fd); | | 258 | close(fd); |
235 | } | | 259 | } |
236 | | | 260 | |
| @@ -252,89 +276,120 @@ ATF_TC_WITHOUT_HEAD(kcov_enable_no_disab | | | @@ -252,89 +276,120 @@ ATF_TC_WITHOUT_HEAD(kcov_enable_no_disab |
252 | ATF_TC_BODY(kcov_enable_no_disable_no_close, tc) | | 276 | ATF_TC_BODY(kcov_enable_no_disable_no_close, tc) |
253 | { | | 277 | { |
254 | int fd; | | 278 | int fd; |
255 | uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE; | | 279 | uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE; |
256 | int mode; | | 280 | int mode; |
257 | | | 281 | |
258 | fd = open_kcov(); | | 282 | fd = open_kcov(); |
259 | ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0); | | 283 | ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0); |
260 | mode = KCOV_MODE_NONE; | | 284 | mode = KCOV_MODE_NONE; |
261 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); | | 285 | ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0); |
262 | } | | 286 | } |
263 | | | 287 | |
264 | static void * | | 288 | static void * |
265 | common_head(int *fdp) | | 289 | common_head_raw(bool fd_dup, int *fdp) |
266 | { | | 290 | { |
267 | void *data; | | 291 | void *data; |
268 | int fd; | | 292 | int fd, fd2; |
269 | uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE; | | 293 | uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE; |
270 | | | 294 | |
271 | fd = open_kcov(); | | 295 | fd = open_kcov(); |
272 | | | 296 | |
| | | 297 | /* Test the dup2(2) trick used by syzkaller */ |
| | | 298 | if (fd_dup) { |
| | | 299 | fd2 = pick_unassigned_fd(fd); |
| | | 300 | ATF_REQUIRE_EQ(dup2(fd, fd2), fd2); |
| | | 301 | close(fd); |
| | | 302 | fd = fd2; |
| | | 303 | } |
| | | 304 | |
273 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0, | | 305 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0, |
274 | "Unable to set the kcov buffer size"); | | 306 | "Unable to set the kcov buffer size"); |
275 | | | 307 | |
276 | data = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | | 308 | data = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
277 | ATF_REQUIRE_MSG(data != MAP_FAILED, "Unable to mmap the kcov buffer"); | | 309 | ATF_REQUIRE_MSG(data != MAP_FAILED, "Unable to mmap the kcov buffer"); |
278 | | | 310 | |
279 | *fdp = fd; | | 311 | *fdp = fd; |
280 | return data; | | 312 | return data; |
281 | } | | 313 | } |
282 | | | 314 | |
| | | 315 | static void * |
| | | 316 | common_head(int *fdp) |
| | | 317 | { |
| | | 318 | |
| | | 319 | return common_head_raw(false, fdp); |
| | | 320 | } |
| | | 321 | |
283 | static void | | 322 | static void |
284 | common_tail(int fd, kcov_int_t *data) | | 323 | common_tail(int fd, kcov_int_t *data) |
285 | { | | 324 | { |
286 | | | 325 | |
287 | ATF_REQUIRE_MSG(munmap(__UNVOLATILE(data), PAGE_SIZE) == 0, | | 326 | ATF_REQUIRE_MSG(munmap(__UNVOLATILE(data), PAGE_SIZE) == 0, |
288 | "Unable to unmap the kcov buffer"); | | 327 | "Unable to unmap the kcov buffer"); |
289 | | | 328 | |
290 | close(fd); | | 329 | close(fd); |
291 | } | | 330 | } |
292 | | | 331 | |
293 | static void | | 332 | static void |
294 | kcov_basic(int mode) | | 333 | kcov_basic(bool fd_dup, int mode) |
295 | { | | 334 | { |
296 | kcov_int_t *buf; | | 335 | kcov_int_t *buf; |
297 | int fd; | | 336 | int fd; |
298 | | | 337 | |
299 | buf = common_head(&fd); | | 338 | buf = common_head_raw(fd_dup, &fd); |
300 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0, | | 339 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0, |
301 | "Unable to enable kcov "); | | 340 | "Unable to enable kcov "); |
302 | | | 341 | |
303 | KCOV_STORE(buf[0], 0); | | 342 | KCOV_STORE(buf[0], 0); |
304 | | | 343 | |
305 | sleep(0); /* XXX: Is it enough for all trace types? */ | | 344 | sleep(0); /* XXX: Is it enough for all trace types? */ |
306 | ATF_REQUIRE_MSG(KCOV_LOAD(buf[0]) != 0, "No records found"); | | 345 | ATF_REQUIRE_MSG(KCOV_LOAD(buf[0]) != 0, "No records found"); |
307 | | | 346 | |
308 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0, | | 347 | ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0, |
309 | "Unable to disable kcov"); | | 348 | "Unable to disable kcov"); |
310 | | | 349 | |
311 | common_tail(fd, buf); | | 350 | common_tail(fd, buf); |
312 | } | | 351 | } |
313 | | | 352 | |
314 | ATF_TC_WITHOUT_HEAD(kcov_basic_pc); | | 353 | ATF_TC_WITHOUT_HEAD(kcov_basic_pc); |
315 | ATF_TC_BODY(kcov_basic_pc, tc) | | 354 | ATF_TC_BODY(kcov_basic_pc, tc) |
316 | { | | 355 | { |
317 | | | 356 | |
318 | kcov_basic(KCOV_MODE_TRACE_PC); | | 357 | kcov_basic(false, KCOV_MODE_TRACE_PC); |
319 | } | | 358 | } |
320 | | | 359 | |
321 | ATF_TC_WITHOUT_HEAD(kcov_basic_cmp); | | 360 | ATF_TC_WITHOUT_HEAD(kcov_basic_cmp); |
322 | ATF_TC_BODY(kcov_basic_cmp, tc) | | 361 | ATF_TC_BODY(kcov_basic_cmp, tc) |
323 | { | | 362 | { |
324 | | | 363 | |
325 | atf_tc_skip("XXX: GCC8 needed"); | | 364 | atf_tc_skip("XXX: GCC8 needed"); |
326 | | | 365 | |
327 | kcov_basic(KCOV_MODE_TRACE_CMP); | | 366 | kcov_basic(false, KCOV_MODE_TRACE_CMP); |
| | | 367 | } |
| | | 368 | |
| | | 369 | ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_pc); |
| | | 370 | ATF_TC_BODY(kcov_basic_dup2_pc, tc) |
| | | 371 | { |
| | | 372 | |
| | | 373 | kcov_basic(true, KCOV_MODE_TRACE_PC); |
| | | 374 | } |
| | | 375 | |
| | | 376 | ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_cmp); |
| | | 377 | ATF_TC_BODY(kcov_basic_dup2_cmp, tc) |
| | | 378 | { |
| | | 379 | |
| | | 380 | atf_tc_skip("XXX: GCC8 needed"); |
| | | 381 | |
| | | 382 | kcov_basic(true, KCOV_MODE_TRACE_CMP); |
328 | } | | 383 | } |
329 | | | 384 | |
330 | ATF_TC_WITHOUT_HEAD(kcov_multienable_on_the_same_thread); | | 385 | ATF_TC_WITHOUT_HEAD(kcov_multienable_on_the_same_thread); |
331 | ATF_TC_BODY(kcov_multienable_on_the_same_thread, tc) | | 386 | ATF_TC_BODY(kcov_multienable_on_the_same_thread, tc) |
332 | { | | 387 | { |
333 | kcov_int_t *buf1, *buf2; | | 388 | kcov_int_t *buf1, *buf2; |
334 | int fd1, fd2; | | 389 | int fd1, fd2; |
335 | int mode; | | 390 | int mode; |
336 | | | 391 | |
337 | buf1 = common_head(&fd1); | | 392 | buf1 = common_head(&fd1); |
338 | buf2 = common_head(&fd2); | | 393 | buf2 = common_head(&fd2); |
339 | mode = KCOV_MODE_NONE; | | 394 | mode = KCOV_MODE_NONE; |
340 | ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_ENABLE, &mode) == 0, | | 395 | ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_ENABLE, &mode) == 0, |
| @@ -476,35 +531,38 @@ ATF_TC_BODY(kcov_multiple_threads##n, tc | | | @@ -476,35 +531,38 @@ ATF_TC_BODY(kcov_multiple_threads##n, tc |
476 | \ | | 531 | \ |
477 | kcov_multiple_threads(n); \ | | 532 | kcov_multiple_threads(n); \ |
478 | } | | 533 | } |
479 | | | 534 | |
480 | KCOV_MULTIPLE_THREADS(2) | | 535 | KCOV_MULTIPLE_THREADS(2) |
481 | KCOV_MULTIPLE_THREADS(4) | | 536 | KCOV_MULTIPLE_THREADS(4) |
482 | KCOV_MULTIPLE_THREADS(8) | | 537 | KCOV_MULTIPLE_THREADS(8) |
483 | KCOV_MULTIPLE_THREADS(16) | | 538 | KCOV_MULTIPLE_THREADS(16) |
484 | KCOV_MULTIPLE_THREADS(32) | | 539 | KCOV_MULTIPLE_THREADS(32) |
485 | | | 540 | |
486 | ATF_TP_ADD_TCS(tp) | | 541 | ATF_TP_ADD_TCS(tp) |
487 | { | | 542 | { |
488 | | | 543 | |
| | | 544 | ATF_TP_ADD_TC(tp, kcov_dup2); |
489 | ATF_TP_ADD_TC(tp, kcov_multiopen); | | 545 | ATF_TP_ADD_TC(tp, kcov_multiopen); |
490 | ATF_TP_ADD_TC(tp, kcov_open_close_open); | | 546 | ATF_TP_ADD_TC(tp, kcov_open_close_open); |
491 | ATF_TP_ADD_TC(tp, kcov_bufsize); | | 547 | ATF_TP_ADD_TC(tp, kcov_bufsize); |
492 | ATF_TP_ADD_TC(tp, kcov_mmap); | | 548 | ATF_TP_ADD_TC(tp, kcov_mmap); |
493 | ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap); | | 549 | ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap); |
494 | ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap_no_close); | | 550 | ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap_no_close); |
495 | ATF_TP_ADD_TC(tp, kcov_enable); | | 551 | ATF_TP_ADD_TC(tp, kcov_enable); |
496 | ATF_TP_ADD_TC(tp, kcov_enable_no_disable); | | 552 | ATF_TP_ADD_TC(tp, kcov_enable_no_disable); |
497 | ATF_TP_ADD_TC(tp, kcov_enable_no_disable_no_close); | | 553 | ATF_TP_ADD_TC(tp, kcov_enable_no_disable_no_close); |
498 | ATF_TP_ADD_TC(tp, kcov_mmap_enable_thread_close); | | 554 | ATF_TP_ADD_TC(tp, kcov_mmap_enable_thread_close); |
499 | ATF_TP_ADD_TC(tp, kcov_basic_pc); | | 555 | ATF_TP_ADD_TC(tp, kcov_basic_pc); |
500 | ATF_TP_ADD_TC(tp, kcov_basic_cmp); | | 556 | ATF_TP_ADD_TC(tp, kcov_basic_cmp); |
| | | 557 | ATF_TP_ADD_TC(tp, kcov_basic_dup2_pc); |
| | | 558 | ATF_TP_ADD_TC(tp, kcov_basic_dup2_cmp); |
501 | ATF_TP_ADD_TC(tp, kcov_multienable_on_the_same_thread); | | 559 | ATF_TP_ADD_TC(tp, kcov_multienable_on_the_same_thread); |
502 | ATF_TP_ADD_TC(tp, kcov_buffer_access_from_custom_thread); | | 560 | ATF_TP_ADD_TC(tp, kcov_buffer_access_from_custom_thread); |
503 | ATF_TP_ADD_TC(tp, kcov_thread); | | 561 | ATF_TP_ADD_TC(tp, kcov_thread); |
504 | ATF_TP_ADD_TC(tp, kcov_multiple_threads2); | | 562 | ATF_TP_ADD_TC(tp, kcov_multiple_threads2); |
505 | ATF_TP_ADD_TC(tp, kcov_multiple_threads4); | | 563 | ATF_TP_ADD_TC(tp, kcov_multiple_threads4); |
506 | ATF_TP_ADD_TC(tp, kcov_multiple_threads8); | | 564 | ATF_TP_ADD_TC(tp, kcov_multiple_threads8); |
507 | ATF_TP_ADD_TC(tp, kcov_multiple_threads16); | | 565 | ATF_TP_ADD_TC(tp, kcov_multiple_threads16); |
508 | ATF_TP_ADD_TC(tp, kcov_multiple_threads32); | | 566 | ATF_TP_ADD_TC(tp, kcov_multiple_threads32); |
509 | return atf_no_error(); | | 567 | return atf_no_error(); |
510 | } | | 568 | } |