slicegrow_override.ll raw

   1  ; Diagnostic alloc override - traps huge allocation requests with backtrace.
   2  ; Also overrides sliceGrow to call free.
   3  
   4  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
   5  target triple = "x86_64-unknown-linux-musleabihf"
   6  
   7  @runtime.zeroSizedAlloc = external hidden global i8
   8  declare ptr @calloc(i64, i64)
   9  declare void @free(ptr)
  10  declare i64 @write(i32, ptr, i64)
  11  declare void @exit(i32) noreturn
  12  declare i32 @snprintf(ptr, i64, ptr, ...)
  13  declare hidden void @runtime.memmove(ptr, ptr, i64, ptr)
  14  declare hidden i64 @runtime.uintptrLen(i64, ptr)
  15  declare hidden void @runtime.runtimePanic(ptr, i64, i64, ptr)
  16  
  17  @diag.msg = internal constant [128 x i8] c"\n\n!!! ALLOC TRAP: huge size requested. size=0x%lx (%lu) caller_ra=%p\nlast_szlt=0x%lx slt=0x%lx\nNN\0"
  18  @diag.buf = internal global [256 x i8] zeroinitializer
  19  
  20  define hidden noalias nonnull ptr @runtime.alloc(i64 %size, ptr %layout, ptr %context) #0 {
  21  entry:
  22    %zero = icmp eq i64 %size, 0
  23    br i1 %zero, label %ret_zero, label %check_huge
  24  
  25  ret_zero:
  26    ret ptr @runtime.zeroSizedAlloc
  27  
  28  check_huge:
  29    ; Sizes > 256MB are almost certainly bugs in compiler
  30    %threshold = icmp ugt i64 %size, 268435456
  31    br i1 %threshold, label %trap_huge, label %normal
  32  
  33  trap_huge:
  34    %ra = call ptr @llvm.returnaddress(i32 0)
  35    %nbytes = call i32 (ptr, i64, ptr, ...) @snprintf(
  36      ptr getelementptr ([256 x i8], ptr @diag.buf, i64 0, i64 0),
  37      i64 256,
  38      ptr getelementptr ([128 x i8], ptr @diag.msg, i64 0, i64 0),
  39      i64 %size,
  40      i64 %size,
  41      ptr %ra,
  42      i64 0,
  43      i64 0)
  44    %nb64 = sext i32 %nbytes to i64
  45    call i64 @write(i32 2,
  46      ptr getelementptr ([256 x i8], ptr @diag.buf, i64 0, i64 0),
  47      i64 %nb64)
  48    call void @exit(i32 134) noreturn
  49    unreachable
  50  
  51  normal:
  52    %aligned = add i64 %size, 15
  53    %size16 = and i64 %aligned, -16
  54    %total = add i64 %size16, 16
  55    %base = call ptr @calloc(i64 1, i64 %total)
  56    %ok = icmp ne ptr %base, null
  57    br i1 %ok, label %done, label %oom
  58  
  59  oom:
  60    call void @exit(i32 134) noreturn
  61    unreachable
  62  
  63  done:
  64    store i64 -6872988504188559820, ptr %base, align 8
  65    %user = getelementptr i8, ptr %base, i64 16
  66    ret ptr %user
  67  }
  68  
  69  declare ptr @llvm.returnaddress(i32)
  70  declare hidden ptr @runtime.alloc(i64, ptr, ptr)
  71  declare hidden void @runtime.memmove(ptr, ptr, i64, ptr)
  72  declare hidden void @runtime.negativeShiftPanic(ptr)
  73  declare hidden i32 @"math/bits.Len"(i32, ptr)
  74  declare hidden ptr @"(internal/gclayout.Layout).AsPtr"(i64, ptr)
  75  
  76  define hidden { ptr, i64, i64 } @runtime.sliceGrow(ptr %oldBuf, i64 %oldLen, i64 %oldCap, i64 %newCap, i64 %elemSize, ptr %context) #0 {
  77  entry:
  78    %0 = icmp uge i64 %oldCap, %newCap
  79    br i1 %0, label %no_grow, label %grow
  80  
  81  no_grow:
  82    %r0 = insertvalue { ptr, i64, i64 } zeroinitializer, ptr %oldBuf, 0
  83    %r1 = insertvalue { ptr, i64, i64 } %r0, i64 %oldLen, 1
  84    %r2 = insertvalue { ptr, i64, i64 } %r1, i64 %oldCap, 2
  85    ret { ptr, i64, i64 } %r2
  86  
  87  grow:
  88    %tr = trunc i64 %newCap to i32
  89    %bits = call i32 @"math/bits.Len"(i32 %tr, ptr undef)
  90    %neg = icmp slt i32 %bits, 0
  91    br i1 %neg, label %shift_throw, label %shift_ok
  92  
  93  shift_ok:
  94    %overflow = icmp uge i32 %bits, 64
  95    %ext = zext i32 %bits to i64
  96    %shifted = shl i64 1, %ext
  97    %roundCap = select i1 %overflow, i64 0, i64 %shifted
  98    %small = icmp ult i64 %elemSize, 8
  99    br i1 %small, label %set_layout, label %do_alloc
 100  
 101  set_layout:
 102    %lay = call ptr @"(internal/gclayout.Layout).AsPtr"(i64 3, ptr undef)
 103    br label %do_alloc
 104  
 105  do_alloc:
 106    %layout = phi ptr [ null, %shift_ok ], [ %lay, %set_layout ]
 107    %totalSz = mul i64 %roundCap, %elemSize
 108    %buf = call ptr @runtime.alloc(i64 %totalSz, ptr %layout, ptr undef)
 109    %hasData = icmp ugt i64 %oldLen, 0
 110    br i1 %hasData, label %copy, label %free_old
 111  
 112  copy:
 113    %copySz = mul i64 %oldLen, %elemSize
 114    call void @runtime.memmove(ptr %buf, ptr %oldBuf, i64 %copySz, ptr undef)
 115    br label %free_old
 116  
 117  free_old:
 118    %oldNotNull = icmp ne ptr %oldBuf, null
 119    br i1 %oldNotNull, label %do_free, label %ret
 120  
 121  do_free:
 122    call void @free(ptr %oldBuf)
 123    br label %ret
 124  
 125  ret:
 126    %s0 = insertvalue { ptr, i64, i64 } zeroinitializer, ptr %buf, 0
 127    %s1 = insertvalue { ptr, i64, i64 } %s0, i64 %oldLen, 1
 128    %s2 = insertvalue { ptr, i64, i64 } %s1, i64 %roundCap, 2
 129    ret { ptr, i64, i64 } %s2
 130  
 131  shift_throw:
 132    call void @runtime.negativeShiftPanic(ptr undef)
 133    unreachable
 134  }
 135  
 136  attributes #0 = { noinline nounwind }
 137