@@ -369,37 +369,6 @@ static void SetOrigin(const void *dst, uptr size, u32 origin) {
369
369
*(u32 *)(end - kOriginAlign ) = origin;
370
370
}
371
371
372
- static void WriteShadowInRange (dfsan_label label, uptr beg_shadow_addr,
373
- uptr end_shadow_addr) {
374
- // TODO: After changing dfsan_label to 8bit, use internal_memset when label
375
- // is not 0.
376
- dfsan_label *labelp = (dfsan_label *)beg_shadow_addr;
377
- if (label) {
378
- for (; (uptr)labelp < end_shadow_addr; ++labelp) *labelp = label;
379
- return ;
380
- }
381
-
382
- for (; (uptr)labelp < end_shadow_addr; ++labelp) {
383
- // Don't write the label if it is already the value we need it to be.
384
- // In a program where most addresses are not labeled, it is common that
385
- // a page of shadow memory is entirely zeroed. The Linux copy-on-write
386
- // implementation will share all of the zeroed pages, making a copy of a
387
- // page when any value is written. The un-sharing will happen even if
388
- // the value written does not change the value in memory. Avoiding the
389
- // write when both |label| and |*labelp| are zero dramatically reduces
390
- // the amount of real memory used by large programs.
391
- if (!*labelp)
392
- continue ;
393
-
394
- *labelp = 0 ;
395
- }
396
- }
397
-
398
- static void WriteShadowWithSize (dfsan_label label, uptr shadow_addr,
399
- uptr size) {
400
- WriteShadowInRange (label, shadow_addr, shadow_addr + size * sizeof (label));
401
- }
402
-
403
372
#define RET_CHAIN_ORIGIN (id ) \
404
373
GET_CALLER_PC_BP_SP; \
405
374
(void )sp; \
@@ -451,21 +420,6 @@ void dfsan_copy_memory(void *dst, const void *src, uptr size) {
451
420
dfsan_mem_origin_transfer (dst, src, size);
452
421
}
453
422
454
- } // namespace __dfsan
455
-
456
- // If the label s is tainted, set the size bytes from the address p to be a new
457
- // origin chain with the previous ID o and the current stack trace. This is
458
- // used by instrumentation to reduce code size when too much code is inserted.
459
- extern " C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_maybe_store_origin (
460
- dfsan_label s, void *p, uptr size, dfsan_origin o) {
461
- if (UNLIKELY (s)) {
462
- GET_CALLER_PC_BP_SP;
463
- (void )sp;
464
- GET_STORE_STACK_TRACE_PC_BP (pc, bp);
465
- SetOrigin (p, size, ChainOrigin (o, &stack));
466
- }
467
- }
468
-
469
423
// Releases the pages within the origin address range.
470
424
static void ReleaseOrigins (void *addr, uptr size) {
471
425
const uptr beg_origin_addr = (uptr)__dfsan::origin_for (addr);
@@ -484,6 +438,19 @@ static void ReleaseOrigins(void *addr, uptr size) {
484
438
Die ();
485
439
}
486
440
441
+ static void WriteZeroShadowInRange (uptr beg, uptr end) {
442
+ // Don't write the label if it is already the value we need it to be.
443
+ // In a program where most addresses are not labeled, it is common that
444
+ // a page of shadow memory is entirely zeroed. The Linux copy-on-write
445
+ // implementation will share all of the zeroed pages, making a copy of a
446
+ // page when any value is written. The un-sharing will happen even if
447
+ // the value written does not change the value in memory. Avoiding the
448
+ // write when both |label| and |*labelp| are zero dramatically reduces
449
+ // the amount of real memory used by large programs.
450
+ if (!mem_is_zero ((const char *)beg, end - beg))
451
+ internal_memset ((void *)beg, 0 , end - beg);
452
+ }
453
+
487
454
// Releases the pages within the shadow address range, and sets
488
455
// the shadow addresses not on the pages to be 0.
489
456
static void ReleaseOrClearShadows (void *addr, uptr size) {
@@ -492,20 +459,22 @@ static void ReleaseOrClearShadows(void *addr, uptr size) {
492
459
const uptr end_shadow_addr = (uptr)__dfsan::shadow_for (end_addr);
493
460
494
461
if (end_shadow_addr - beg_shadow_addr <
495
- common_flags ()->clear_shadow_mmap_threshold )
496
- return WriteShadowWithSize (0 , beg_shadow_addr, size);
462
+ common_flags ()->clear_shadow_mmap_threshold ) {
463
+ WriteZeroShadowInRange (beg_shadow_addr, end_shadow_addr);
464
+ return ;
465
+ }
497
466
498
467
const uptr page_size = GetPageSizeCached ();
499
468
const uptr beg_aligned = RoundUpTo (beg_shadow_addr, page_size);
500
469
const uptr end_aligned = RoundDownTo (end_shadow_addr, page_size);
501
470
502
471
if (beg_aligned >= end_aligned) {
503
- WriteShadowWithSize ( 0 , beg_shadow_addr, size );
472
+ WriteZeroShadowInRange ( beg_shadow_addr, end_shadow_addr );
504
473
} else {
505
474
if (beg_aligned != beg_shadow_addr)
506
- WriteShadowInRange ( 0 , beg_shadow_addr, beg_aligned);
475
+ WriteZeroShadowInRange ( beg_shadow_addr, beg_aligned);
507
476
if (end_aligned != end_shadow_addr)
508
- WriteShadowInRange ( 0 , end_aligned, end_shadow_addr);
477
+ WriteZeroShadowInRange ( end_aligned, end_shadow_addr);
509
478
if (!MmapFixedSuperNoReserve (beg_aligned, end_aligned - beg_aligned))
510
479
Die ();
511
480
}
@@ -514,7 +483,7 @@ static void ReleaseOrClearShadows(void *addr, uptr size) {
514
483
void SetShadow (dfsan_label label, void *addr, uptr size, dfsan_origin origin) {
515
484
if (0 != label) {
516
485
const uptr beg_shadow_addr = (uptr)__dfsan::shadow_for (addr);
517
- WriteShadowWithSize (label, beg_shadow_addr, size);
486
+ internal_memset (( void *) beg_shadow_addr, label , size);
518
487
if (dfsan_get_track_origins ())
519
488
SetOrigin (addr, size, origin);
520
489
return ;
@@ -526,9 +495,24 @@ void SetShadow(dfsan_label label, void *addr, uptr size, dfsan_origin origin) {
526
495
ReleaseOrClearShadows (addr, size);
527
496
}
528
497
498
+ } // namespace __dfsan
499
+
500
+ // If the label s is tainted, set the size bytes from the address p to be a new
501
+ // origin chain with the previous ID o and the current stack trace. This is
502
+ // used by instrumentation to reduce code size when too much code is inserted.
503
+ extern " C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_maybe_store_origin (
504
+ dfsan_label s, void *p, uptr size, dfsan_origin o) {
505
+ if (UNLIKELY (s)) {
506
+ GET_CALLER_PC_BP_SP;
507
+ (void )sp;
508
+ GET_STORE_STACK_TRACE_PC_BP (pc, bp);
509
+ SetOrigin (p, size, ChainOrigin (o, &stack));
510
+ }
511
+ }
512
+
529
513
extern " C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_set_label (
530
514
dfsan_label label, dfsan_origin origin, void *addr, uptr size) {
531
- SetShadow (label, addr, size, origin);
515
+ __dfsan:: SetShadow (label, addr, size, origin);
532
516
}
533
517
534
518
SANITIZER_INTERFACE_ATTRIBUTE
@@ -539,7 +523,7 @@ void dfsan_set_label(dfsan_label label, void *addr, uptr size) {
539
523
GET_STORE_STACK_TRACE_PC_BP (pc, bp);
540
524
init_origin = ChainOrigin (0 , &stack, true );
541
525
}
542
- SetShadow (label, addr, size, init_origin);
526
+ __dfsan:: SetShadow (label, addr, size, init_origin);
543
527
}
544
528
545
529
SANITIZER_INTERFACE_ATTRIBUTE
0 commit comments