lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150812045704.GA58476@Alexeis-MBP.westell.com>
Date:	Tue, 11 Aug 2015 21:57:05 -0700
From:	Alexei Starovoitov <alexei.starovoitov@...il.com>
To:	"Wangnan (F)" <wangnan0@...wei.com>
Cc:	Alexei Starovoitov <ast@...mgrid.com>,
	He Kuang <hekuang@...wei.com>, pi3orama <pi3orama@....com>,
	llvm-dev@...ts.llvm.org,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.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

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.

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.
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.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ