Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933572AbbHLFkV (ORCPT ); Wed, 12 Aug 2015 01:40:21 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:63029 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933494AbbHLFkT (ORCPT ); Wed, 12 Aug 2015 01:40:19 -0400 Message-ID: <55CAD991.4090002@huawei.com> Date: Wed, 12 Aug 2015 13:28:49 +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 CC: Alexei Starovoitov , He Kuang , pi3orama , , "linux-kernel@vger.kernel.org" Subject: Re: [llvm-dev] llvm bpf debug info. Re: [RFC PATCH v4 3/3] bpf: Introduce function for outputing data to perf event References: <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> <55CAB0C3.40805@huawei.com> <20150812045704.GA58476@Alexeis-MBP.westell.com> In-Reply-To: <20150812045704.GA58476@Alexeis-MBP.westell.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 X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.55CAD9AB.0008,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 05bea2e9fc1b818d5d780e06aa8f36dd Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5404 Lines: 136 On 2015/8/12 12:57, Alexei Starovoitov wrote: > On Wed, Aug 12, 2015 at 10:34:43AM +0800, Wangnan (F) via llvm-dev wrote: >> Think about a program like this: >> >> struct strA { int a; } >> struct strB { int b; } >> int func() { >> struct strA a; >> struct strB b; >> >> a.a = 1; >> b.b = 2; >> bpf_output(gettype(a), &a); >> bpf_output(gettype(b), &b); >> return 0; >> } >> >> BPF backend can't (and needn't) tell the difference between local >> variables a and b in theory. In LLVM implementation, it filters type >> information out using ComputeValueVTs(). Please have a look at >> SelectionDAGBuilder::visitIntrinsicCall in >> lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp and >> SelectionDAGBuilder::visitTargetIntrinsic in the same file. in >> visitTargetIntrinsic, ComputeValueVTs acts as a barrier which strips >> type information out from CallInst ("I"), and leave SDValue and SDVTList >> ("Ops" and "VTs") to target code. SDValue and SDVTList are wrappers of >> EVT and MVT, all information we concern won't be passed here. >> >> I think now we have 2 choices: >> >> 1. Hacking into clang, implement target specific builtin function. Now I >> have worked out a ugly but workable patch which setup a builtin function: >> __builtin_bpf_typeid(), which accepts local or global variable then >> returns different constant for different types. >> >> 2. Implementing an LLVM intrinsic call (llvm.typeid), make it be processed >> in >> visitIntrinsicCall(). I think we can get something useful if it is >> processed >> with that function. > Yeah. You're right about pure target intrinsics. > I think llvm.typeid might work. imo it's cleaner than > doing it at clang level. > >> The next thing should be generating debug information to map type and >> constants which issued by __builtin_bpf_typeid() or llvm.typeid. Now we >> have a crazy idea that, if we limit the name of the structure to 8 bytes, >> we can insert the name into a u64, then there would be no need to consider >> type information in DWARF. For example, in the above sample code, gettype(a) >> will issue 0x0000000041727473 because its type is "strA". What do you think? > that's way too hacky. > I was thinking when compiling we can keep llvm ir along with .o > instead of dwarf and extract type info from there. > dwarf has names and other things that we don't need. We only > care about actual field layout of the structs. > But it probably won't be easy to parse llvm ir on perf side > instead of dwarf. Shipping both llvm IR and .o to perf makes it harder to use. I'm not sure whether it is a good idea. If we are unable to encode the structure using a u64, let's still dig into dwarf. We have another idea that we can utilize dwarf's existing feature. For example, when __buildin_bpf_typeid() get called, define an enumerate type in dwarf info, so you'll find: <1><2a>: Abbrev Number: 2 (DW_TAG_enumeration_type) <2b> DW_AT_name : (indirect string, offset: 0xec): TYPEINFO <2f> DW_AT_byte_size : 4 <30> DW_AT_decl_file : 1 <31> DW_AT_decl_line : 3 <2><32>: Abbrev Number: 3 (DW_TAG_enumerator) <33> DW_AT_name : (indirect string, offset: 0xcc): __typeinfo_strA <37> DW_AT_const_value : 2 <2><38>: Abbrev Number: 3 (DW_TAG_enumerator) <39> DW_AT_name : (indirect string, offset: 0xdc): __typeinfo_strB <3d> DW_AT_const_value : 3 or this: <3><54>: Abbrev Number: 4 (DW_TAG_variable) <55> DW_AT_const_value : 2 <66> DW_AT_name : (indirect string, offset: 0x1e): __typeinfo_strA <6a> DW_AT_decl_file : 1 <6b> DW_AT_decl_line : 29 <6c> DW_AT_type : <0x72> then from DW_AT_name and DW_AT_const_value we can do the mapping. Drawback is that all __typeinfo_ prefixed names become reserved. > btw, if you haven't looked at iovisor/bcc, there we're solving > similar problem differently. There we use clang rewriter, so all > structs fields are visible at this level, then we use bpf backend > in JIT mode and push bpf instructions into the kernel on the fly > completely skipping ELF and .o > For example in: > https://github.com/iovisor/bcc/blob/master/examples/distributed_bridge/tunnel.c > when you see > struct ethernet_t { > unsigned long long dst:48; > unsigned long long src:48; > unsigned int type:16; > } BPF_PACKET_HEADER; > struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); > ... ethernet->src ... > is recognized by clang rewriter and ->src is converted to a different > C code that is sent again into clang. > So there is no need to use dwarf or patch clang/llvm. clang rewriter > has all the info. Could you please give us further information about your clang rewriter? I guess you need a new .so when injecting those code into kernel? > I'm not sure you can live with clang/llvm on the host where you > want to run the tracing bits, but if you can that's an easier option. > I'm not sure. Our target platform should be embedded devices like smartphone. Bringing full clang/llvm environment there is not acceptable. 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/