Skip to content

Instantly share code, notes, and snippets.

@Birch-san
Created July 25, 2020 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Birch-san/dcb77ef11b2df81759dbbeab6874cb8f to your computer and use it in GitHub Desktop.
Save Birch-san/dcb77ef11b2df81759dbbeab6874cb8f to your computer and use it in GitHub Desktop.
5-byte memcpy, 8-byte-aligned goes bang (LLVM IR)
; ModuleID = 'bpftrace'
source_filename = "bpftrace"
target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128"
target triple = "bpf-pc-linux"
%helper_error_t = type <{ i64, i64, i32, i8 }>
; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
define i64 @"uprobe:./tests/testprogs/string_args:print"(i8*) local_unnamed_addr section "s_uprobe:./tests/testprogs/string_args:print_1" {
entry:
%helper_error_t = alloca %helper_error_t, align 8
%key = alloca i32, align 4
%"struct F.s" = alloca [5 x i8], align 1
%1 = getelementptr i8, i8* %0, i64 112
%2 = bitcast i8* %1 to i64*
%arg0 = load volatile i64, i64* %2, align 8
%3 = getelementptr inbounds [5 x i8], [5 x i8]* %"struct F.s", i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %3)
%probe_read = call i64 inttoptr (i64 4 to i64 ([5 x i8]*, i32, i64)*)([5 x i8]* nonnull %"struct F.s", i32 5, i64 %arg0)
%4 = bitcast i32* %key to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %4)
store i32 0, i32* %key, align 4
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%"lookup_$a_map" = call [5 x i8]* inttoptr (i64 1 to [5 x i8]* (i64, i32*)*)(i64 %pseudo, i32* nonnull %key)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %4)
%5 = icmp eq [5 x i8]* %"lookup_$a_map", null
br i1 %5, label %helper_failure, label %helper_merge
helper_failure: ; preds = %entry
%6 = bitcast %helper_error_t* %helper_error_t to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %6)
%7 = getelementptr inbounds %helper_error_t, %helper_error_t* %helper_error_t, i64 0, i32 0
store i64 30006, i64* %7, align 8
%8 = getelementptr inbounds %helper_error_t, %helper_error_t* %helper_error_t, i64 0, i32 1
store i64 0, i64* %8, align 8
%9 = getelementptr inbounds %helper_error_t, %helper_error_t* %helper_error_t, i64 0, i32 2
store i32 0, i32* %9, align 8
%10 = getelementptr inbounds %helper_error_t, %helper_error_t* %helper_error_t, i64 0, i32 3
store i8 1, i8* %10, align 4
%pseudo1 = call i64 @llvm.bpf.pseudo(i64 1, i64 2)
%perf_event_output = call i64 inttoptr (i64 25 to i64 (i8*, i64, i64, %helper_error_t*, i64)*)(i8* nonnull %0, i64 %pseudo1, i64 4294967295, %helper_error_t* nonnull %helper_error_t, i64 21)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %6)
ret i64 0
helper_merge: ; preds = %entry
%11 = getelementptr inbounds [5 x i8], [5 x i8]* %"lookup_$a_map", i64 0, i64 0
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 %11, i8* nonnull align 8 %3, i64 5, i1 false)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %3)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment