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