From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757155AbdESUys (ORCPT ); Fri, 19 May 2017 16:54:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:17185 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754506AbdESUyp (ORCPT ); Fri, 19 May 2017 16:54:45 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A10504DB15 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jpoimboe@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A10504DB15 Date: Fri, 19 May 2017 15:53:54 -0500 From: Josh Poimboeuf To: linux-kernel@vger.kernel.org Cc: Jiri Slaby , Andrew Morton , live-patching@vger.kernel.org, Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , the arch/x86 maintainers , Andy Lutomirski , Jiri Kosina , Linus Torvalds Subject: Re: [PATCH 7/7] DWARF: add the config option Message-ID: <20170519205354.caeyqri2k6gvso3w@treble> References: <20170505122200.31436-1-jslaby@suse.cz> <20170505122200.31436-7-jslaby@suse.cz> <20170507165524.cdxfuwbd5alr7v6k@treble> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20170507165524.cdxfuwbd5alr7v6k@treble> User-Agent: Mutt/1.6.0.1 (2016-04-01) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 19 May 2017 20:53:55 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, May 07, 2017 at 11:55:24AM -0500, Josh Poimboeuf wrote: > I'm thinking/hoping that information can be expressed in a simple, easy > to parse, reasonably sized data structure. Something like a sorted > array of this: > > struct undwarf { > unsigned int ip; /* instruction pointer (relative offset from base) */ > unsigned prev_frame:13; /* offset to previous frame from current stack pointer */ > unsigned regs:1; /* whether prev_frame contains entry regs (regs->ip) */ > unsigned align:2; /* some details for dealing with gcc stack realignment */ > } __packed; > > extern struct undwarf undwarves[]; > > One instance of the structure would exist for each time the stack > pointer changes, e.g. for every function entry, push/pop, and rsp > add/subtract. The data could be assembled and sorted offline, possibly > derived from DWARF, or more likely, generated by objtool. After doing > some rough calculations, I think the section size would be comparable to > the sizes of the DWARF .eh_frame sections it would replace. > > If it worked, the "undwarf" unwinder would be a lot simpler than a real > DWARF unwinder. And validating the sanity of the data at runtime would > be a lot more straightforward. It could ensure that each stack pointer > is within the bounds of the current stack, like our current unwinder > does. I've been hacking away at this, and so far it's working well. The code is much simpler than a DWARF unwinder. Right now the kernel piece is only ~350 lines of code. The vast majority of the changes are in objtool. It's now successfully unwinding through entry code and most other asm files, dumping entry regs, dealing with aligned stacks, dynamic stacks, etc. Here's the struct in its current state: #define UNDWARF_REG_UNDEFINED 0 #define UNDWARF_REG_CFA 1 #define UNDWARF_REG_SP 2 #define UNDWARF_REG_FP 3 #define UNDWARF_REG_SP_INDIRECT 4 #define UNDWARF_REG_FP_INDIRECT 5 #define UNDWARF_REG_R10 6 #define UNDWARF_REG_DI 7 #define UNDWARF_REG_DX 8 #define UNDWARF_TYPE_NORMAL 0 #define UNDWARF_TYPE_REGS 1 #define UNDWARF_TYPE_REGS_IRET 2 struct undwarf_state { int ip; unsigned int len; short cfa_offset; short fp_offset; unsigned cfa_reg:4; unsigned fp_reg:4; unsigned type:2; }; With frame pointers disabled, around 300,000 of those structs are needed for my kernel, which works out to be 4.7M of data. By comparison, the DWARF eh_frame sections would be 2.1M. I think we should be able to compress it down to a comparable size by rearranging the data a little bit. The entry code needs some annotations to give some hints to objtool about how to generate the data, but it's not bad: https://paste.fedoraproject.org/paste/Xq3bPlx5An0Si7AshZTdkF5M1UNdIGYhyRLivL9gydE= I still have a lot of work to do on the tooling side: module support, sorting the undwarf table at build time, and a lot of cleanups. But overall it's looking feasible. -- Josh