[llvm] r367030 - [BPF] fix CO-RE incorrect index access string

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 29 01:58:29 PDT 2019


Merged to release_90 in r367210.

On Thu, Jul 25, 2019 at 6:00 PM Yonghong Song via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: yhs
> Date: Thu Jul 25 09:01:26 2019
> New Revision: 367030
>
> URL: http://llvm.org/viewvc/llvm-project?rev=367030&view=rev
> Log:
> [BPF] fix CO-RE incorrect index access string
>
> Currently, we expect the CO-RE offset relocation records
> a string encoding the original getelementptr access index,
> so kernel bpf loader can decode it correctly.
>
> For example,
>   struct s { int a; int b; };
>   struct t { int c; int d; };
>   #define _(x) (__builtin_preserve_access_index(x))
>   int get_value(const void *addr1, const void *addr2);
>   int test(struct s *arg1, struct t *arg2) {
>     return get_value(_(&arg1->b), _(&arg2->d));
>   }
>
> We expect two offset relocations:
>   reloc 1: type s, access index 0, 1
>   reloc 2: type t, access index 0, 1
>
> Two globals are created to retain access indexes for the
> above two relocations with global variable names.
> The first global has a name "0:1:". Unfortunately,
> the second global has the name "0:1:.1" as the llvm
> internals automatically add suffix ".1" to a global
> with the same name. Later on, the BPF peels the last
> character and record "0:1" and "0:1:." in the
> relocation table.
>
> This is not desirable. BPF backend could use the global
> variable suffix knowledge to generate correct access str.
> This patch rather took an approach not relying on
> that knowledge. It generates "s:0:1:" and "t:0:1:" to
> avoid global variable suffixes and later on generate
> correct index access string "0:1" for both records.
>
> Signed-off-by: Yonghong Song <yhs at fb.com>
>
> Differential Revision: https://reviews.llvm.org/D65258
>
> Added:
>     llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll
> Modified:
>     llvm/trunk/lib/Target/BPF/BPFAbstractMemberAccess.cpp
>     llvm/trunk/lib/Target/BPF/BTFDebug.cpp
>
> Modified: llvm/trunk/lib/Target/BPF/BPFAbstractMemberAccess.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFAbstractMemberAccess.cpp?rev=367030&r1=367029&r2=367030&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/BPF/BPFAbstractMemberAccess.cpp (original)
> +++ llvm/trunk/lib/Target/BPF/BPFAbstractMemberAccess.cpp Thu Jul 25 09:01:26 2019
> @@ -116,9 +116,8 @@ private:
>    void replaceWithGEP(std::vector<CallInst *> &CallList,
>                        uint32_t NumOfZerosIndex, uint32_t DIIndex);
>
> -  Value *computeBaseAndAccessStr(CallInst *Call, std::string &AccessStr,
> -                                 std::string &AccessKey, uint32_t Kind,
> -                                 MDNode *&TypeMeta);
> +  Value *computeBaseAndAccessKey(CallInst *Call, std::string &AccessKey,
> +                                 uint32_t Kind, MDNode *&TypeMeta);
>    bool getAccessIndex(const Value *IndexValue, uint64_t &AccessIndex);
>    bool transformGEPChain(Module &M, CallInst *Call, uint32_t Kind);
>  };
> @@ -340,8 +339,7 @@ bool BPFAbstractMemberAccess::getAccessI
>  /// Compute the base of the whole preserve_*_access_index chains, i.e., the base
>  /// pointer of the first preserve_*_access_index call, and construct the access
>  /// string, which will be the name of a global variable.
> -Value *BPFAbstractMemberAccess::computeBaseAndAccessStr(CallInst *Call,
> -                                                        std::string &AccessStr,
> +Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call,
>                                                          std::string &AccessKey,
>                                                          uint32_t Kind,
>                                                          MDNode *&TypeMeta) {
> @@ -392,16 +390,16 @@ Value *BPFAbstractMemberAccess::computeB
>    if (!LastTypeName.size() || AccessIndices.size() > TypeNameIndex + 2)
>      return nullptr;
>
> -  // Construct the type string AccessStr.
> +  // Construct the type string AccessKey.
>    for (unsigned I = 0; I < AccessIndices.size(); ++I)
> -    AccessStr = std::to_string(AccessIndices[I]) + ":" + AccessStr;
> +    AccessKey = std::to_string(AccessIndices[I]) + ":" + AccessKey;
>
>    if (TypeNameIndex == AccessIndices.size() - 1)
> -    AccessStr = "0:" + AccessStr;
> +    AccessKey = "0:" + AccessKey;
>
>    // Access key is the type name + access string, uniquely identifying
>    // one kernel memory access.
> -  AccessKey = LastTypeName + ":" + AccessStr;
> +  AccessKey = LastTypeName + ":" + AccessKey;
>
>    return Base;
>  }
> @@ -410,10 +408,10 @@ Value *BPFAbstractMemberAccess::computeB
>  /// transformation to a chain of relocable GEPs.
>  bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call,
>                                                  uint32_t Kind) {
> -  std::string AccessStr, AccessKey;
> +  std::string AccessKey;
>    MDNode *TypeMeta = nullptr;
>    Value *Base =
> -      computeBaseAndAccessStr(Call, AccessStr, AccessKey, Kind, TypeMeta);
> +      computeBaseAndAccessKey(Call, AccessKey, Kind, TypeMeta);
>    if (!Base)
>      return false;
>
> @@ -432,7 +430,7 @@ bool BPFAbstractMemberAccess::transformG
>
>    if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
>      GV = new GlobalVariable(M, Type::getInt64Ty(BB->getContext()), false,
> -                            GlobalVariable::ExternalLinkage, NULL, AccessStr);
> +                            GlobalVariable::ExternalLinkage, NULL, AccessKey);
>      GV->addAttribute(BPFCoreSharedInfo::AmaAttr);
>      // Set the metadata (debuginfo types) for the global.
>      if (TypeMeta)
>
> Modified: llvm/trunk/lib/Target/BPF/BTFDebug.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BTFDebug.cpp?rev=367030&r1=367029&r2=367030&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/BPF/BTFDebug.cpp (original)
> +++ llvm/trunk/lib/Target/BPF/BTFDebug.cpp Thu Jul 25 09:01:26 2019
> @@ -1006,19 +1006,20 @@ void BTFDebug::generateOffsetReloc(const
>    unsigned RootId = populateStructType(RootTy);
>    setTypeFromId(RootId, &PrevStructType, &PrevArrayType);
>    unsigned RootTySize = PrevStructType->getStructSize();
> +  StringRef IndexPattern = AccessPattern.substr(AccessPattern.find_first_of(':') + 1);
>
>    BTFOffsetReloc OffsetReloc;
>    OffsetReloc.Label = ORSym;
> -  OffsetReloc.OffsetNameOff = addString(AccessPattern.drop_back());
> +  OffsetReloc.OffsetNameOff = addString(IndexPattern.drop_back());
>    OffsetReloc.TypeID = RootId;
>
>    uint32_t Start = 0, End = 0, Offset = 0;
>    bool FirstAccess = true;
> -  for (auto C : AccessPattern) {
> +  for (auto C : IndexPattern) {
>      if (C != ':') {
>        End++;
>      } else {
> -      std::string SubStr = AccessPattern.substr(Start, End - Start);
> +      std::string SubStr = IndexPattern.substr(Start, End - Start);
>        int Loc = std::stoi(SubStr);
>
>        if (FirstAccess) {
> @@ -1043,7 +1044,7 @@ void BTFDebug::generateOffsetReloc(const
>        End = Start;
>      }
>    }
> -  AccessOffsets[RootTy->getName().str() + ":" + AccessPattern.str()] = Offset;
> +  AccessOffsets[AccessPattern.str()] = Offset;
>    OffsetRelocTable[SecNameOff].push_back(OffsetReloc);
>  }
>
> @@ -1227,7 +1228,7 @@ bool BTFDebug::InstLower(const MachineIn
>          MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
>          DIType *Ty = dyn_cast<DIType>(MDN);
>          std::string TypeName = Ty->getName();
> -        int64_t Imm = AccessOffsets[TypeName + ":" + GVar->getName().str()];
> +        int64_t Imm = AccessOffsets[GVar->getName().str()];
>
>          // Emit "mov ri, <imm>" for abstract member accesses.
>          OutMI.setOpcode(BPF::MOV_ri);
>
> Added: llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll?rev=367030&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll (added)
> +++ llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll Thu Jul 25 09:01:26 2019
> @@ -0,0 +1,95 @@
> +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s
> +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s
> +;
> +; Source code:
> +;   struct s { int a; int b; };
> +;   struct t { int c; int d; };
> +;   #define _(x) (__builtin_preserve_access_index(x))
> +;   int get_value(const void *addr1, const void *addr2);
> +;   int test(struct s *arg1, struct t *arg2) {
> +;     return get_value(_(&arg1->b), _(&arg2->d));
> +;   }
> +; clang -target bpf -S -O2 -g -emit-llvm test.c
> +
> +%struct.s = type { i32, i32 }
> +%struct.t = type { i32, i32 }
> +
> +; Function Attrs: nounwind
> +define dso_local i32 @test(%struct.s* %arg1, %struct.t* %arg2) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  call void @llvm.dbg.value(metadata %struct.s* %arg1, metadata !22, metadata !DIExpression()), !dbg !24
> +  call void @llvm.dbg.value(metadata %struct.t* %arg2, metadata !23, metadata !DIExpression()), !dbg !24
> +  %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* %arg1, i32 1, i32 1), !dbg !25, !llvm.preserve.access.index !12
> +  %1 = bitcast i32* %0 to i8*, !dbg !25
> +  %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t* %arg2, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !17
> +  %3 = bitcast i32* %2 to i8*, !dbg !26
> +  %call = tail call i32 @get_value(i8* %1, i8* %3) #4, !dbg !27
> +  ret i32 %call, !dbg !28
> +}
> +
> +; CHECK:             .section        .BTF,"", at progbits
> +; CHECK:             .ascii  ".text"                 # string offset=[[SEC_INDEX:[0-9]+]]
> +; CHECK-NEXT:        .byte   0
> +; CHECK:             .ascii  "0:1"                   # string offset=[[ACCESS_STR:[0-9]+]]
> +; CHECK-NEXT:        .byte   0
> +; CHECK:             .section        .BTF.ext,"", at progbits
> +; CHECK:             .long   12                      # OffsetReloc
> +; CHECK-NEXT:        .long   [[SEC_INDEX]]           # Offset reloc section string offset=[[SEC_INDEX]]
> +; CHECK-NEXT:        .long   2
> +; CHECK-NEXT:        .long   .Ltmp{{[0-9]+}}
> +; CHECK-NEXT:        .long   {{[0-9]+}}
> +; CHECK-NEXT:        .long   [[ACCESS_STR]]
> +; CHECK-NEXT:        .long   .Ltmp{{[0-9]+}}
> +; CHECK-NEXT:        .long   {{[0-9]+}}
> +; CHECK-NEXT:        .long   [[ACCESS_STR]]
> +
> +declare dso_local i32 @get_value(i8*, i8*) local_unnamed_addr #1
> +
> +; Function Attrs: nounwind readnone
> +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone
> +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.value(metadata, metadata, metadata) #3
> +
> +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind readnone speculatable }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
> +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"}
> +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !21)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11, !16}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
> +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !13)
> +!13 = !{!14, !15}
> +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32)
> +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32, offset: 32)
> +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64)
> +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !1, line: 2, size: 64, elements: !18)
> +!18 = !{!19, !20}
> +!19 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !17, file: !1, line: 2, baseType: !10, size: 32)
> +!20 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !17, file: !1, line: 2, baseType: !10, size: 32, offset: 32)
> +!21 = !{!22, !23}
> +!22 = !DILocalVariable(name: "arg1", arg: 1, scope: !7, file: !1, line: 5, type: !11)
> +!23 = !DILocalVariable(name: "arg2", arg: 2, scope: !7, file: !1, line: 5, type: !16)
> +!24 = !DILocation(line: 0, scope: !7)
> +!25 = !DILocation(line: 6, column: 20, scope: !7)
> +!26 = !DILocation(line: 6, column: 33, scope: !7)
> +!27 = !DILocation(line: 6, column: 10, scope: !7)
> +!28 = !DILocation(line: 6, column: 3, scope: !7)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list