@@ -395,6 +395,7 @@ class BaseReport {
395
395
access_size(access_size),
396
396
untagged_addr(UntagAddr(tagged_addr)),
397
397
ptr_tag(GetTagFromPointer(tagged_addr)),
398
+ mismatch_offset(FindMismatchOffset()),
398
399
heap(CopyHeapChunk()),
399
400
allocations(CopyAllocations()),
400
401
candidate(FindBufferOverflowCandidate()),
@@ -442,6 +443,7 @@ class BaseReport {
442
443
tag_t short_tags[ARRAY_SIZE(tags)] = {};
443
444
};
444
445
446
+ sptr FindMismatchOffset () const ;
445
447
Shadow CopyShadow () const ;
446
448
tag_t GetTagCopy (uptr addr) const ;
447
449
tag_t GetShortTagCopy (uptr addr) const ;
@@ -461,6 +463,7 @@ class BaseReport {
461
463
const uptr access_size = 0 ;
462
464
const uptr untagged_addr = 0 ;
463
465
const tag_t ptr_tag = 0 ;
466
+ const sptr mismatch_offset = 0 ;
464
467
465
468
const HeapChunk heap;
466
469
const Allocations allocations;
@@ -469,6 +472,37 @@ class BaseReport {
469
472
const Shadow shadow ;
470
473
};
471
474
475
+ sptr BaseReport::FindMismatchOffset () const {
476
+ if (!access_size)
477
+ return 0 ;
478
+ sptr offset =
479
+ __hwasan_test_shadow (reinterpret_cast <void *>(tagged_addr), access_size);
480
+ CHECK_GE (offset, 0 );
481
+ CHECK_LT (offset, static_cast <sptr>(access_size));
482
+ tag_t *tag_ptr =
483
+ reinterpret_cast <tag_t *>(MemToShadow (untagged_addr + offset));
484
+ tag_t mem_tag = *tag_ptr;
485
+
486
+ if (mem_tag && mem_tag < kShadowAlignment ) {
487
+ tag_t *granule_ptr = reinterpret_cast <tag_t *>((untagged_addr + offset) &
488
+ ~(kShadowAlignment - 1 ));
489
+ // If offset is 0, (untagged_addr + offset) is not aligned to granules.
490
+ // This is the offset of the leftmost accessed byte within the bad granule.
491
+ u8 in_granule_offset = (untagged_addr + offset) & (kShadowAlignment - 1 );
492
+ tag_t short_tag = granule_ptr[kShadowAlignment - 1 ];
493
+ // The first mismatch was a short granule that matched the ptr_tag.
494
+ if (short_tag == ptr_tag) {
495
+ // If the access starts after the end of the short granule, then the first
496
+ // bad byte is the first byte of the access; otherwise it is the first
497
+ // byte past the end of the short granule
498
+ if (mem_tag > in_granule_offset) {
499
+ offset += mem_tag - in_granule_offset;
500
+ }
501
+ }
502
+ }
503
+ return offset;
504
+ }
505
+
472
506
BaseReport::Shadow BaseReport::CopyShadow () const {
473
507
Shadow result;
474
508
if (!MemIsApp (untagged_addr))
@@ -917,31 +951,12 @@ TagMismatchReport::~TagMismatchReport() {
917
951
918
952
Thread *t = GetCurrentThread ();
919
953
920
- sptr offset =
921
- __hwasan_test_shadow (reinterpret_cast <void *>(tagged_addr), access_size);
922
- CHECK_GE (offset, 0 );
923
- CHECK_LT (offset, static_cast <sptr>(access_size));
924
- tag_t *tag_ptr =
925
- reinterpret_cast <tag_t *>(MemToShadow (untagged_addr + offset));
926
- tag_t mem_tag = *tag_ptr;
954
+ tag_t mem_tag = GetTagCopy (MemToShadow (untagged_addr + mismatch_offset));
927
955
928
956
Printf (" %s" , d.Access ());
929
957
if (mem_tag && mem_tag < kShadowAlignment ) {
930
- tag_t *granule_ptr = reinterpret_cast <tag_t *>((untagged_addr + offset) &
931
- ~(kShadowAlignment - 1 ));
932
- // If offset is 0, (untagged_addr + offset) is not aligned to granules.
933
- // This is the offset of the leftmost accessed byte within the bad granule.
934
- u8 in_granule_offset = (untagged_addr + offset) & (kShadowAlignment - 1 );
935
- tag_t short_tag = granule_ptr[kShadowAlignment - 1 ];
936
- // The first mismatch was a short granule that matched the ptr_tag.
937
- if (short_tag == ptr_tag) {
938
- // If the access starts after the end of the short granule, then the first
939
- // bad byte is the first byte of the access; otherwise it is the first
940
- // byte past the end of the short granule
941
- if (mem_tag > in_granule_offset) {
942
- offset += mem_tag - in_granule_offset;
943
- }
944
- }
958
+ tag_t short_tag =
959
+ GetShortTagCopy (MemToShadow (untagged_addr + mismatch_offset));
945
960
Printf (
946
961
" %s of size %zu at %p tags: %02x/%02x(%02x) (ptr/mem) in thread T%zd\n " ,
947
962
is_store ? " WRITE" : " READ" , access_size, untagged_addr, ptr_tag,
@@ -951,16 +966,16 @@ TagMismatchReport::~TagMismatchReport() {
951
966
is_store ? " WRITE" : " READ" , access_size, untagged_addr, ptr_tag,
952
967
mem_tag, t->unique_id ());
953
968
}
954
- if (offset != 0 )
955
- Printf (" Invalid access starting at offset %zu\n " , offset );
969
+ if (mismatch_offset )
970
+ Printf (" Invalid access starting at offset %zu\n " , mismatch_offset );
956
971
Printf (" %s" , d.Default ());
957
972
958
973
stack->Print ();
959
974
960
975
PrintAddressDescription ();
961
976
t->Announce ();
962
977
963
- PrintTags (untagged_addr + offset );
978
+ PrintTags (untagged_addr + mismatch_offset );
964
979
965
980
if (registers_frame)
966
981
ReportRegisters (registers_frame, pc);
0 commit comments