Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751672AbbHEB72 (ORCPT ); Tue, 4 Aug 2015 21:59:28 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:54813 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750920AbbHEB71 (ORCPT ); Tue, 4 Aug 2015 21:59:27 -0400 Message-ID: <55C16DC7.70408@huawei.com> Date: Wed, 5 Aug 2015 09:58:31 +0800 From: "Wangnan (F)" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Alexei Starovoitov , He Kuang , pi3orama CC: "linux-kernel@vger.kernel.org" , Subject: Re: Cc llvmdev: Re: llvm bpf debug info. Re: [RFC PATCH v4 3/3] bpf: Introduce function for outputing data to perf event References: <1436522587-136825-1-git-send-email-hekuang@huawei.com> <1436522587-136825-4-git-send-email-hekuang@huawei.com> <55A042DC.6030809@plumgrid.com> <55A3404B.6020904@huawei.com> <20150713135223.GB9917@danjae.kornet> <4D441676-21A7-46EE-AAB0-EB529D408082@163.com> <20150713140915.GD9917@danjae.kornet> <55A46928.9090708@plumgrid.com> <55A4F869.1020705@huawei.com> <55A88085.8090407@plumgrid.com> <55A88137.7020609@huawei.com> <55A88449.3030008@plumgrid.com> <55B0D5FC.6050406@huawei.com> <55B1535E.8090406@plumgrid.com> <55B1AEE9.1080207@plumgrid.com> <55B1BC03.9020708@huawei.com> <55B35F42.70803@huawei.com> <55B6E685.30905@plumgrid.com> <55B89F04.5030304@huawei.com> <55B909B2.2080606@plumgrid.com> <55BB4B8A.5000207@huawei.com> <55BFC4A0.9060100@plumgrid.com> <55C07F5B.6030107@huawei.com> In-Reply-To: <55C07F5B.6030107@huawei.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.111.66.109] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6726 Lines: 242 On 2015/8/4 17:01, Wangnan (F) wrote: > For people who in llvmdev: > > This mail is belong to a thread in linux kernel mailing list, the > first message > can be retrived from: > > http://lkml.kernel.org/r/55B1535E.8090406@plumgrid.com > > Our goal is to fild a way to make BPF program get an unique ID for > each type > so it can pass the ID to other part of kernel, then we can retrive the > type and > decode the structure using DWARF information. Currently we have two > problem > needs to solve: > > 1. Dwarf information generated by BPF backend lost all DW_AT_name field; > > 2. How to get typeid from local variable? I tried llvm.eh_typeid_for > but it support global variable only. > > Following is my response to Alexei. > > On 2015/8/4 3:44, Alexei Starovoitov wrote: >> On 7/31/15 3:18 AM, Wangnan (F) wrote: >> > > [SNIP] > >> didn't have time to look at it. >> from your llvm patches looks like you've got quite experienced >> with it already :) >> >>> I'll post 2 LLVM patches by replying this mail. Please have a look and >>> help me >>> send them to LLVM if you think my code is correct. >> >> patch 1: >> I don't quite understand the purpose of builtin_dwarf_cfa >> returning R11. It's a special register seen inside llvm codegen >> only. It doesn't have kernel meaning. >> > > Kernel side verifier allows us to do arithmetic computation using two > local variable > address or local variable address and R11. Therefore, we can compute > the location > of a local variable using: > > mark = &my_var_a - __builtin_frame_address(0); > > If the stack allocation is fixed (if the location is never reused), > the above 'mark' > can be uniquely identify a local variable. That's why I'm interesting > in it. However > I'm not sure whether the prerequestion is hold. > >> patch 2: >> do we really need to hack clang? >> Can you just define a function that aliases to intrinsic, >> like we do for ld_abs/ld_ind ? >> void bpf_store_half(void *skb, u64 off, u64 val) >> asm("llvm.bpf.store.half"); >> then no extra patches necessary. >> >>> struct my_str { >>> int x; >>> int y; >>> }; >>> struct my_str __str_my_str; >>> >>> struct my_str2 { >>> int x; >>> int y; >>> int z; >>> }; >>> struct my_str2 __str_my_str2; >>> >>> test_func(__builtin_bpf_typeid(&__str_my_str)); >>> test_func(__builtin_bpf_typeid(&__str_my_str2)); >>> mov r1, 1 >>> call 4660 >>> mov r1, 2 >>> call 4660 >> >> this part looks good. I think it's usable. >> >> > 1. llvm.eh_typeid_for can be used on global variables only. So for >> each >> > output >> > structure we have to define a global varable. >> >> why? I think it should work with local pointers as well. >> > > It is defined by LLVM, in lib/CodeGen/Analysis.cpp: > > /// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded > in V. > GlobalValue *llvm::ExtractTypeInfo(Value *V) { > ... > assert((GV || isa(V)) && > "TypeInfo must be a global variable or NULL"); <-- we can > use only constant pointers > return GV; > } > > So from llvm::Intrinsic::eh_typeid_for we can get type of global > variables only. > > We may need a new intrinsic for that. > > >> > 2. We still need to find a way to connect the fetchd typeid with DWARF >> > info. >> > Inserting that ID into DWARF may workable? >> >> hmm, that id should be the same id we're seeing in dwarf, right? > > There's no 'typeid' field in dwarf originally. I'm still looking for a > way > to inject this ID into dwarf infromation. > >> I think it's used in exception handling which is reusing some of >> the dwarf stuff for this, so the must be a way to connect that id >> to actual type info. Though last time I looked at EH was >> during g++ hacking days. No idea how llvm does it exactly, but >> I'm assuming the logic for rtti should be similar. >> > > I'm not sure whether RTTI use dwarf to deduce type information. I > think not, > because dwarf infos can be stripped out. > Hi Alexei, Just found that llvm::Intrinsic::eh_typeid_for is function specific. ID of same type in different functions may be different. Here is an example: static int (*bpf_output_event)(unsigned long, void *buf, int size) = (void *) 0x1234; struct my_str { int x; int y; }; struct my_str __str_my_str; struct my_str2 { int x; int y; int z; }; struct my_str2 __str_my_str2; int func(int *ctx) { struct my_str var_a; struct my_str2 var_b; bpf_output_event(__builtin_bpf_typeid(&__str_my_str), &var_a, sizeof(var_a)); bpf_output_event(__builtin_bpf_typeid(&__str_my_str2), &var_b, sizeof(var_b)); return 0; } int func2(int *ctx) { struct my_str var_a; struct my_str2 var_b; /* change order here */ bpf_output_event(__builtin_bpf_typeid(&__str_my_str2), &var_b, sizeof(var_b)); bpf_output_event(__builtin_bpf_typeid(&__str_my_str), &var_a, sizeof(var_a)) return 0; } This program uses __builtin_bpf_typeid(llvm::Intrinsic::eh_typeid_for) in func and func2 for same two types but in different order. We expect same type get same ID. Compiled with: $ clang -target bpf -S -O2 -c ./test_bpf_typeid.c The result is: .text .globl func .align 8 func: # @func # BB#0: # %entry mov r2, r10 addi r2, -8 mov r1, 1 mov r3, 8 call 4660 mov r2, r10 addi r2, -24 mov r1, 2 mov r3, 12 call 4660 mov r0, 0 ret .globl func2 .align 8 func2: # @func2 # BB#0: # %entry mov r2, r10 addi r2, -24 mov r1, 1 <--- we want 2 here. mov r3, 12 call 4660 mov r2, r10 addi r2, -8 mov r1, 2 <--- we want 1 here. mov r3, 8 call 4660 mov r0, 0 ret .comm __str_my_str,8,4 # @__str_my_str .comm __str_my_str2,12,4 # @__str_my_str2 Conclusion: llvm::Intrinsic::eh_typeid_for is not on the right direction... Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/