Cheng Shao pushed to branch wip/terrorjack/asan at Glasgow Haskell Compiler / GHC

Commits:

9 changed files:

Changes:

  • rts/Hash.c
    ... ... @@ -283,6 +283,7 @@ allocHashList (HashTable *table)
    283 283
         if (table->freeList != NULL) {
    
    284 284
             HashList *hl = table->freeList;
    
    285 285
             table->freeList = hl->next;
    
    286
    +        __asan_unpoison_memory_region(hl, offsetof(HashList, next));
    
    286 287
             return hl;
    
    287 288
         } else {
    
    288 289
             /* We allocate one block of memory which contains:
    
    ... ... @@ -302,8 +303,11 @@ allocHashList (HashTable *table)
    302 303
     
    
    303 304
             table->freeList = hl + 1;
    
    304 305
             HashList *p = table->freeList;
    
    305
    -        for (; p < hl + HCHUNK - 1; p++)
    
    306
    +        for (; p < hl + HCHUNK - 1; p++) {
    
    307
    +            __asan_poison_memory_region(p, offsetof(HashList, next));
    
    306 308
                 p->next = p + 1;
    
    309
    +        }
    
    310
    +        __asan_poison_memory_region(p, offsetof(HashList, next));
    
    307 311
             p->next = NULL;
    
    308 312
             return hl;
    
    309 313
         }
    
    ... ... @@ -318,6 +322,7 @@ freeHashList (HashTable *table, HashList *hl)
    318 322
         // HashListChunks.
    
    319 323
         hl->next = table->freeList;
    
    320 324
         table->freeList = hl;
    
    325
    +    __asan_poison_memory_region(hl, offsetof(HashList, next));
    
    321 326
     }
    
    322 327
     
    
    323 328
     STATIC_INLINE void
    
    ... ... @@ -388,9 +393,10 @@ removeHashTable_inlined(HashTable *table, StgWord key, const void *data,
    388 393
                     table->dir[segment][index] = hl->next;
    
    389 394
                 else
    
    390 395
                     prev->next = hl->next;
    
    396
    +            void *hl_data = (void*)hl->data;
    
    391 397
                 freeHashList(table,hl);
    
    392 398
                 table->kcount--;
    
    393
    -            return (void *) hl->data;
    
    399
    +            return hl_data;
    
    394 400
             }
    
    395 401
             prev = hl;
    
    396 402
         }
    

  • rts/Task.c
    ... ... @@ -183,6 +183,7 @@ freeTask (Task *task)
    183 183
             stgFree(incall);
    
    184 184
         }
    
    185 185
         for (incall = task->spare_incalls; incall != NULL; incall = next) {
    
    186
    +        __asan_unpoison_memory_region(incall, sizeof(InCall));
    
    186 187
             next = incall->next;
    
    187 188
             stgFree(incall);
    
    188 189
         }
    
    ... ... @@ -252,6 +253,7 @@ newInCall (Task *task)
    252 253
     
    
    253 254
         if (task->spare_incalls != NULL) {
    
    254 255
             incall = task->spare_incalls;
    
    256
    +        __asan_unpoison_memory_region(incall, sizeof(InCall));
    
    255 257
             task->spare_incalls = incall->next;
    
    256 258
             task->n_spare_incalls--;
    
    257 259
         } else {
    
    ... ... @@ -283,6 +285,7 @@ endInCall (Task *task)
    283 285
             stgFree(incall);
    
    284 286
         } else {
    
    285 287
             incall->next = task->spare_incalls;
    
    288
    +        __asan_poison_memory_region(incall, sizeof(InCall));
    
    286 289
             task->spare_incalls = incall;
    
    287 290
             task->n_spare_incalls++;
    
    288 291
         }
    

  • rts/include/Stg.h
    ... ... @@ -331,6 +331,7 @@ external prototype return neither of these types to workaround #11395.
    331 331
     #include "stg/MachRegsForHost.h"
    
    332 332
     #include "stg/Regs.h"
    
    333 333
     #include "stg/Ticky.h"
    
    334
    +#include "rts/ASANUtils.h"
    
    334 335
     #include "rts/TSANUtils.h"
    
    335 336
     
    
    336 337
     #if IN_STG_CODE
    

  • rts/include/rts/ASANUtils.h
    1
    +#pragma once
    
    2
    +
    
    3
    +#if defined(__SANITIZE_ADDRESS__)
    
    4
    +#define ASAN_ENABLED
    
    5
    +#elif defined(__has_feature)
    
    6
    +#if __has_feature(address_sanitizer)
    
    7
    +#define ASAN_ENABLED
    
    8
    +#endif
    
    9
    +#endif
    
    10
    +
    
    11
    +#if defined(ASAN_ENABLED)
    
    12
    +#include <sanitizer/asan_interface.h>
    
    13
    +#else
    
    14
    +
    
    15
    +#include <stdlib.h>
    
    16
    +
    
    17
    +static inline void __asan_poison_memory_region(void const volatile *addr
    
    18
    +                                               __attribute__((unused)),
    
    19
    +                                               size_t size
    
    20
    +                                               __attribute__((unused))) {}
    
    21
    +
    
    22
    +static inline void __asan_unpoison_memory_region(void const volatile *addr
    
    23
    +                                                 __attribute__((unused)),
    
    24
    +                                                 size_t size
    
    25
    +                                                 __attribute__((unused))) {}
    
    26
    +
    
    27
    +#endif

  • rts/rts.cabal
    ... ... @@ -292,6 +292,7 @@ library
    292 292
                             -- ^ generated
    
    293 293
                             rts/ghc_ffi.h
    
    294 294
                             rts/Adjustor.h
    
    295
    +                        rts/ASANUtils.h
    
    295 296
                             rts/ExecPage.h
    
    296 297
                             rts/BlockSignals.h
    
    297 298
                             rts/Bytecodes.h
    

  • rts/sm/BlockAlloc.c
    ... ... @@ -261,6 +261,8 @@ initGroup(bdescr *head)
    261 261
           head[i].flags = 0;
    
    262 262
       }
    
    263 263
     #endif
    
    264
    +
    
    265
    +  __asan_unpoison_memory_region(head->start, (W_)head->blocks * BLOCK_SIZE);
    
    264 266
     }
    
    265 267
     
    
    266 268
     #if SIZEOF_VOID_P == SIZEOF_LONG
    
    ... ... @@ -474,6 +476,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
    474 476
             bd = alloc_mega_group_from_free_list(&deferred_free_mblock_list[node], n, &best);
    
    475 477
             if(bd)
    
    476 478
             {
    
    479
    +            __asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
    
    477 480
                 return bd;
    
    478 481
             }
    
    479 482
             else if(!best)
    
    ... ... @@ -490,6 +493,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
    490 493
     
    
    491 494
         if (bd)
    
    492 495
         {
    
    496
    +        __asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
    
    493 497
             return bd;
    
    494 498
         }
    
    495 499
         else if (best)
    
    ... ... @@ -500,6 +504,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
    500 504
                               (best_mblocks-mblocks)*MBLOCK_SIZE);
    
    501 505
     
    
    502 506
             best->blocks = MBLOCK_GROUP_BLOCKS(best_mblocks - mblocks);
    
    507
    +        __asan_unpoison_memory_region(MBLOCK_ROUND_DOWN(bd), mblocks * MBLOCK_SIZE);
    
    503 508
             initMBlock(MBLOCK_ROUND_DOWN(bd), node);
    
    504 509
         }
    
    505 510
         else
    
    ... ... @@ -880,6 +885,8 @@ free_mega_group (bdescr *mg)
    880 885
     
    
    881 886
             IF_DEBUG(sanity, checkFreeListSanity());
    
    882 887
         }
    
    888
    +
    
    889
    +    __asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
    
    883 890
     }
    
    884 891
     
    
    885 892
     static void
    
    ... ... @@ -927,6 +934,8 @@ free_deferred_mega_groups (uint32_t node)
    927 934
             // coalesce forwards
    
    928 935
             coalesce_mblocks(mg);
    
    929 936
     
    
    937
    +        __asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
    
    938
    +
    
    930 939
             // initialize search for next round
    
    931 940
             prev = mg;
    
    932 941
             bd = prev->link;
    
    ... ... @@ -1050,6 +1059,8 @@ freeGroup(bdescr *p)
    1050 1059
       setup_tail(p);
    
    1051 1060
       free_list_insert(node,p);
    
    1052 1061
     
    
    1062
    +  __asan_poison_memory_region(p->start, (W_)p->blocks * BLOCK_SIZE);
    
    1063
    +
    
    1053 1064
       IF_DEBUG(sanity, checkFreeListSanity());
    
    1054 1065
     }
    
    1055 1066
     
    

  • rts/sm/GCUtils.c
    ... ... @@ -348,6 +348,7 @@ alloc_todo_block (gen_workspace *ws, uint32_t size)
    348 348
             } else {
    
    349 349
                 if (gct->free_blocks) {
    
    350 350
                     bd = gct->free_blocks;
    
    351
    +                __asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
    
    351 352
                     gct->free_blocks = bd->link;
    
    352 353
                 } else {
    
    353 354
                     // We allocate in chunks of at most 16 blocks, use one
    
    ... ... @@ -357,6 +358,9 @@ alloc_todo_block (gen_workspace *ws, uint32_t size)
    357 358
                     StgWord n_blocks = stg_min(chunk_size, 1 << (MBLOCK_SHIFT - BLOCK_SHIFT - 1));
    
    358 359
                     allocBlocks_sync(n_blocks, &bd);
    
    359 360
                     gct->free_blocks = bd->link;
    
    361
    +                for (bdescr *bd = gct->free_blocks; bd; bd = bd->link) {
    
    362
    +                    __asan_poison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
    
    363
    +                }
    
    360 364
                 }
    
    361 365
             }
    
    362 366
             initBdescr(bd, ws->gen, ws->gen->to);
    

  • rts/sm/MBlock.c
    ... ... @@ -641,6 +641,8 @@ getMBlocks(uint32_t n)
    641 641
     
    
    642 642
         ret = getCommittedMBlocks(n);
    
    643 643
     
    
    644
    +    __asan_unpoison_memory_region(ret, (W_)n * MBLOCK_SIZE);
    
    645
    +
    
    644 646
         debugTrace(DEBUG_gc, "allocated %d megablock(s) at %p",n,ret);
    
    645 647
     
    
    646 648
         mblocks_allocated += n;
    
    ... ... @@ -673,6 +675,8 @@ freeMBlocks(void *addr, uint32_t n)
    673 675
     
    
    674 676
         mblocks_allocated -= n;
    
    675 677
     
    
    678
    +    __asan_poison_memory_region(addr, (W_)n * MBLOCK_SIZE);
    
    679
    +
    
    676 680
         decommitMBlocks(addr, n);
    
    677 681
     }
    
    678 682
     
    

  • rts/sm/Storage.c
    ... ... @@ -1242,6 +1242,10 @@ start_new_pinned_block(Capability *cap)
    1242 1242
             ACQUIRE_SM_LOCK;
    
    1243 1243
             bd = allocNursery(cap->node, NULL, PINNED_EMPTY_SIZE);
    
    1244 1244
             RELEASE_SM_LOCK;
    
    1245
    +
    
    1246
    +        for (bdescr *pbd = bd; pbd; pbd = pbd->link) {
    
    1247
    +            __asan_poison_memory_region(pbd->start, (W_)pbd->blocks * BLOCK_SIZE);
    
    1248
    +        }
    
    1245 1249
         }
    
    1246 1250
     
    
    1247 1251
         // Bump up the nursery pointer to avoid the pathological situation
    
    ... ... @@ -1267,6 +1271,7 @@ start_new_pinned_block(Capability *cap)
    1267 1271
         }
    
    1268 1272
     
    
    1269 1273
         cap->pinned_object_empty = bd->link;
    
    1274
    +    __asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
    
    1270 1275
         newNurseryBlock(bd);
    
    1271 1276
         if (bd->link != NULL) {
    
    1272 1277
           bd->link->u.back = cap->pinned_object_empty;