Fix crash with kernel bpf self-tests
This commit is contained in:
		
							parent
							
								
									86a049a618
								
							
						
					
					
						commit
						5baf5a3c1f
					
				
							
								
								
									
										204
									
								
								0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,204 @@ | ||||
| From 5eb29c8b23b652b8dd8988621f5c91191b13ffe3 Mon Sep 17 00:00:00 2001 | ||||
| From: Yonghong Song <yhs@fb.com> | ||||
| 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 <yhs@fb.com> | ||||
| 
 | ||||
| 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<llvm::Value *> 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 | ||||
| 
 | ||||
| @ -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 <tstellar@redhat.com> - 9.0.1-2 | ||||
| - Fix crash with kernel bpf self-tests | ||||
| 
 | ||||
| * Thu Dec 19 2019 Tom Stellard <tstellar@redhat.com> - 9.0.1-1 | ||||
| - 9.0.1 Release | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user