From 5baf5a3c1f1bd1a844baaf21b1551eb98a962f80 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 10 Jan 2020 01:45:35 +0000 Subject: [PATCH] Fix crash with kernel bpf self-tests --- ...ype-metadata-for-builtin-preseve_arr.patch | 204 ++++++++++++++++++ clang.spec | 8 +- 2 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch diff --git a/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch b/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch new file mode 100644 index 0000000..2062f00 --- /dev/null +++ b/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch @@ -0,0 +1,204 @@ +From 5eb29c8b23b652b8dd8988621f5c91191b13ffe3 Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Fri, 2 Aug 2019 21:28:28 +0000 +Subject: [PATCH] [BPF] annotate DIType metadata for builtin + preseve_array_access_index() + +Previously, debuginfo types are annotated to +IR builtin preserve_struct_access_index() and +preserve_union_access_index(), but not +preserve_array_access_index(). The debug info +is useful to identify the root type name which +later will be used for type comparison. + +For user access without explicit type conversions, +the previous scheme works as we can ignore intermediate +compiler generated type conversions (e.g., from union types to +union members) and still generate correct access index string. + +The issue comes with user explicit type conversions, e.g., +converting an array to a structure like below: + struct t { int a; char b[40]; }; + struct p { int c; int d; }; + struct t *var = ...; + ... __builtin_preserve_access_index(&(((struct p *)&(var->b[0]))->d)) ... +Although BPF backend can derive the type of &(var->b[0]), +explicit type annotation make checking more consistent +and less error prone. + +Another benefit is for multiple dimension array handling. +For example, + struct p { int c; int d; } g[8][9][10]; + ... __builtin_preserve_access_index(&g[2][3][4].d) ... +It would be possible to calculate the number of "struct p"'s +before accessing its member "d" if array debug info is +available as it contains each dimension range. + +This patch enables to annotate IR builtin preserve_array_access_index() +with proper debuginfo type. The unit test case and language reference +is updated as well. + +Signed-off-by: Yonghong Song + +Differential Revision: https://reviews.llvm.org/D65664 + +llvm-svn: 367724 +(cherry picked from commit d0ea05d5eff475a27a5d3bbe4d9fd389935f9cb2) +--- + clang/lib/CodeGen/CGExpr.cpp | 12 ++++++++--- + .../CodeGen/builtin-preserve-access-index-array.c | 18 +++++++++++++++++ + clang/test/CodeGen/builtin-preserve-access-index.c | 23 +++++++++++----------- + llvm/docs/LangRef.rst | 4 ++++ + llvm/include/llvm/IR/IRBuilder.h | 10 +++++++--- + llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll | 2 +- + 6 files changed, 51 insertions(+), 18 deletions(-) + create mode 100644 clang/test/CodeGen/builtin-preserve-access-index-array.c + +diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp +index b6c2567..21c4103 100644 +--- a/clang/lib/CodeGen/CGExpr.cpp ++++ b/clang/lib/CodeGen/CGExpr.cpp +@@ -3405,6 +3405,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, + ArrayRef indices, + QualType eltType, bool inbounds, + bool signedIndices, SourceLocation loc, ++ QualType *arrayType = nullptr, + const llvm::Twine &name = "arrayidx") { + // All the indices except that last must be zero. + #ifndef NDEBUG +@@ -3433,9 +3434,12 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, + } else { + // Remember the original array subscript for bpf target + unsigned idx = LastIndex->getZExtValue(); ++ llvm::DIType *DbgInfo = nullptr; ++ if (arrayType) ++ DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(*arrayType, loc); + eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getPointer(), + indices.size() - 1, +- idx); ++ idx, DbgInfo); + } + + return Address(eltPtr, eltAlign); +@@ -3572,19 +3576,21 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, + auto *Idx = EmitIdxAfterBase(/*Promote*/true); + + // Propagate the alignment from the array itself to the result. ++ QualType arrayType = Array->getType(); + Addr = emitArraySubscriptGEP( + *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, + E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices, +- E->getExprLoc()); ++ E->getExprLoc(), &arrayType); + EltBaseInfo = ArrayLV.getBaseInfo(); + EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType()); + } else { + // The base must be a pointer; emit it with an estimate of its alignment. + Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); + auto *Idx = EmitIdxAfterBase(/*Promote*/true); ++ QualType ptrType = E->getBase()->getType(); + Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(), + !getLangOpts().isSignedOverflowDefined(), +- SignedIndices, E->getExprLoc()); ++ SignedIndices, E->getExprLoc(), &ptrType); + } + + LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo); +diff --git a/clang/test/CodeGen/builtin-preserve-access-index-array.c b/clang/test/CodeGen/builtin-preserve-access-index-array.c +new file mode 100644 +index 0000000..a449b28 +--- /dev/null ++++ b/clang/test/CodeGen/builtin-preserve-access-index-array.c +@@ -0,0 +1,18 @@ ++// RUN: %clang -target x86_64 -emit-llvm -S -g %s -o - | FileCheck %s ++ ++#define _(x) (__builtin_preserve_access_index(x)) ++ ++struct s1 { ++ char a; ++ int b[4]; ++}; ++ ++const void *unit1(struct s1 *arg) { ++ return _(&arg->b[2]); ++} ++// CHECK: define dso_local i8* @unit1 ++// CHECK: call [4 x i32]* @llvm.preserve.struct.access.index.p0a4i32.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]] ++// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ARRAY:[0-9]+]] ++// ++// CHECK: ![[ARRAY]] = !DICompositeType(tag: DW_TAG_array_type ++// CHECK: ![[STRUCT_S1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1" +diff --git a/clang/test/CodeGen/builtin-preserve-access-index.c b/clang/test/CodeGen/builtin-preserve-access-index.c +index 954a3b8..1084416 100644 +--- a/clang/test/CodeGen/builtin-preserve-access-index.c ++++ b/clang/test/CodeGen/builtin-preserve-access-index.c +@@ -31,16 +31,16 @@ const void *unit4(const int *arg) { + } + // CHECK: define dso_local i8* @unit4 + // CHECK-NOT: getelementptr +-// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %{{[0-9a-z]+}}, i32 0, i32 1) ++// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %{{[0-9a-z]+}}, i32 0, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[POINTER:[0-9]+]] + + const void *unit5(const int *arg[5]) { + return _(&arg[1][2]); + } + // CHECK: define dso_local i8* @unit5 + // CHECK-NOT: getelementptr +-// CHECK: call i32** @llvm.preserve.array.access.index.p0p0i32.p0p0i32(i32** %{{[0-9a-z]+}}, i32 0, i32 1) ++// CHECK: call i32** @llvm.preserve.array.access.index.p0p0i32.p0p0i32(i32** %{{[0-9a-z]+}}, i32 0, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} + // CHECK-NOT: getelementptr +-// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %{{[0-9a-z]+}}, i32 0, i32 2) ++// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %{{[0-9a-z]+}}, i32 0, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[POINTER:[0-9]+]] + + struct s1 { + char a; +@@ -141,7 +141,7 @@ const void *unit13(struct s4 *arg) { + // CHECK: define dso_local i8* @unit13 + // CHECK: call %union.u* @llvm.preserve.struct.access.index.p0s_union.us.p0s_struct.s4s(%struct.s4* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S4:[0-9]+]] + // CHECK: call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %{{[0-9a-z]+}}, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_I_U:[0-9]+]] +-// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2) ++// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} + + const void *unit14(union u3 *arg) { + return _(&arg->c.b[2]); +@@ -149,13 +149,13 @@ const void *unit14(union u3 *arg) { + // CHECK: define dso_local i8* @unit14 + // CHECK: call %union.u3* @llvm.preserve.union.access.index.p0s_union.u3s.p0s_union.u3s(%union.u3* %{{[0-9a-z]+}}, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_U3:[0-9]+]] + // CHECK: call [4 x i32]* @llvm.preserve.struct.access.index.p0a4i32.p0s_struct.ss(%struct.s* %{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_I_S:[0-9]+]] +-// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2) ++// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} + + const void *unit15(struct s4 *arg) { + return _(&arg[2].c.a); + } + // CHECK: define dso_local i8* @unit15 +-// CHECK: call %struct.s4* @llvm.preserve.array.access.index.p0s_struct.s4s.p0s_struct.s4s(%struct.s4* %{{[0-9a-z]+}}, i32 0, i32 2) ++// CHECK: call %struct.s4* @llvm.preserve.array.access.index.p0s_struct.s4s.p0s_struct.s4s(%struct.s4* %{{[0-9a-z]+}}, i32 0, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} + // CHECK: call %union.u* @llvm.preserve.struct.access.index.p0s_union.us.p0s_struct.s4s(%struct.s4* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S4]] + // CHECK: call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %{{[0-9a-z]+}}, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_I_U]] + +@@ -163,15 +163,16 @@ const void *unit16(union u3 *arg) { + return _(&arg[2].a); + } + // CHECK: define dso_local i8* @unit16 +-// CHECK: call %union.u3* @llvm.preserve.array.access.index.p0s_union.u3s.p0s_union.u3s(%union.u3* %{{[0-9a-z]+}}, i32 0, i32 2) ++// CHECK: call %union.u3* @llvm.preserve.array.access.index.p0s_union.u3s.p0s_union.u3s(%union.u3* %{{[0-9a-z]+}}, i32 0, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} + // CHECK: call %union.u3* @llvm.preserve.union.access.index.p0s_union.u3s.p0s_union.u3s(%union.u3* %{{[0-9a-z]+}}, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_U3]] + ++// CHECK: ![[POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type ++// CHECK: ![[STRUCT_S4]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s4" ++// CHECK: ![[UNION_I_U]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u" ++// CHECK: ![[UNION_U3]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u3" ++// CHECK: ![[STRUCT_I_S]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s" + // CHECK: ![[STRUCT_S1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1" + // CHECK: ![[STRUCT_S2]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2" + // CHECK: ![[STRUCT_S3]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s3" + // CHECK: ![[UNION_U1]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1" + // CHECK: ![[UNION_U2]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u2" +-// CHECK: ![[STRUCT_S4]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s4" +-// CHECK: ![[UNION_I_U]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u" +-// CHECK: ![[UNION_U3]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u3" +-// CHECK: ![[STRUCT_I_S]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s" +-- +1.8.3.1 + diff --git a/clang.spec b/clang.spec index d259461..bbf443d 100644 --- a/clang.spec +++ b/clang.spec @@ -4,7 +4,7 @@ %global min_ver 0 %global patch_ver 1 #%%global rc_ver 3 -%global baserelease 1 +%global baserelease 2 %global clang_tools_binaries \ %{_bindir}/clangd \ @@ -82,6 +82,8 @@ Source1: http://%{?rc_ver:pre}releases.llvm.org/%{version}/%{?rc_ver:rc%{rc_ver} Patch4: 0002-gtest-reorg.patch Patch11: 0001-ToolChain-Add-lgcc_s-to-the-linker-flags-when-using-.patch Patch13: 0001-Make-funwind-tables-the-default-for-all-archs.patch +# Fix crash with kernel bpf self-tests +Patch14: 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch BuildRequires: gcc BuildRequires: gcc-c++ @@ -224,6 +226,7 @@ pathfix.py -i %{__python3} -pn \ %patch4 -p1 -b .gtest %patch11 -p1 -b .libcxx-fix +%patch14 -p2 -b .bpf-fix mv ../%{clang_tools_srcdir} tools/extra @@ -439,6 +442,9 @@ LD_LIBRARY_PATH=%{buildroot}%{_libdir} ninja check-all -C _build || \ %endif %changelog +* Fri Jan 10 2020 Tom Stellard - 9.0.1-2 +- Fix crash with kernel bpf self-tests + * Thu Dec 19 2019 Tom Stellard - 9.0.1-1 - 9.0.1 Release