From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 50406 invoked by alias); 15 Nov 2016 19:25:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 50375 invoked by uid 89); 15 Nov 2016 19:25:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.7 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-Spam-User: qpsmtpd, 2 recipients X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 15 Nov 2016 19:25:47 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0521616; Tue, 15 Nov 2016 11:25:46 -0800 (PST) Received: from [192.168.1.19] (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 70A003F218; Tue, 15 Nov 2016 11:25:44 -0800 (PST) Subject: Re: [1/9][RFC][DWARF] Reserve three DW_OP numbers in vendor extension space To: Jiong Wang , Jakub Jelinek , mjw@tucnak.zalov.cz References: <72418e98-a400-c503-e8ce-c3fbe1ecc4a7@foss.arm.com> <20161111193859.GJ3541@tucnak.redhat.com> <20161115161817.GL3541@tucnak.redhat.com> <5896be40-51de-55f7-f4a1-4c5af7ff9aec@foss.arm.com> Cc: gcc-patches , gdb-patches@sourceware.org, Binutils From: "Richard Earnshaw (lists)" Message-ID: Date: Tue, 15 Nov 2016 19:25:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <5896be40-51de-55f7-f4a1-4c5af7ff9aec@foss.arm.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-11/txt/msg00388.txt.bz2 On 15/11/16 16:48, Jiong Wang wrote: > > > On 15/11/16 16:18, Jakub Jelinek wrote: >> On Tue, Nov 15, 2016 at 04:00:40PM +0000, Jiong Wang wrote: >>>>> Takes one signed LEB128 offset and retrieves 8-byte contents >>>>> from the address >>>>> calculated by CFA plus this offset, the contents then >>>>> authenticated as per A >>>>> key for instruction pointer using current CFA as salt. The >>>>> result is pushed >>>>> onto the stack. >>>> I'd like to point out that especially the vendor range of DW_OP_* is >>>> extremely scarce resource, we have only a couple of unused values, >>>> so taking >>>> 3 out of the remaining unused 12 for a single architecture is IMHO >>>> too much. >>>> Can't you use just a single opcode and encode which of the 3 >>>> operations it is >>>> in say the low 2 bits of a LEB 128 operand? >>>> We'll likely need to do RSN some multiplexing even for the generic GNU >>>> opcodes if we need just a few further ones (say 0xff as an extension, >>>> followed by uleb128 containing the opcode - 0xff). >>>> In the non-vendor area we still have 54 values left, so there is >>>> more space >>>> for future expansion. >>> Seperate DWARF operations are introduced instead of combining all >>> of them into >>> one are mostly because these operations are going to be used for most >>> of the >>> functions once return address signing are enabled, and they are used for >>> describing frame unwinding that they will go into unwind table for >>> C++ program >>> or C program compiled with -fexceptions, the impact on unwind table >>> size is >>> significant. So I was trying to lower the unwind table size overhead >>> as much as >>> I can. >>> >>> IMHO, three numbers actually is not that much for one architecture >>> in DWARF >>> operation vendor extension space as vendors can overlap with each >>> other. The >>> only painful thing from my understand is there are platform vendors, >>> for example >>> "GNU" and "LLVM" etc, for which architecture vendor can't overlap with. >> For DW_OP_*, there aren't two vendor ranges like e.g. in ELF, there is >> just >> one range, so ideally the opcodes would be unique everywhere, if not, >> there >> is just a single GNU vendor, there is no separate range for Aarch64, that >> can overlap with range for x86_64, and powerpc, etc. >> >> Perhaps we could declare that certain opcode subrange for the GNU >> vendor is >> architecture specific and document that the meaning of opcodes in that >> range >> and count/encoding of their arguments depends on the architecture, but >> then >> we should document how to figure out the architecture too (e.g. for ELF >> base it on the containing EM_*). All the tools that look at DWARF >> (readelf, >> objdump, eu-readelf, libdw, libunwind, gdb, dwz, ...) would need to >> agree on that >> though. >> >> I know nothing about the aarch64 return address signing, would all 3 >> or say >> 2 usually appear together without any separate pc advance, or are they >> all >> going to appear frequently and at different pcs? > > I think it's the latter, the DW_OP_AARCH64_paciasp and > DW_OP_AARCH64_paciasp_deref are going to appear frequently and at > different pcs. > For example, the following function prologue, there are three > instructions > at 0x0, 0x4, 0x8. > > After the first instruction at 0x0, LR/X30 will be mangled. The > "paciasp" always > mangle LR register using SP as salt and write back the value into LR. > We then generate > DW_OP_AARCH64_paciasp to notify any unwinder that the original LR is > mangled in this > way so they can unwind the original value properly. > > After the second instruction at 0x4, The mangled value of LR/X30 will > be pushed on > to stack, unlike usual .cfi_offset, the unwind rule for LR/X30 becomes: > first fetch the > mangled value from stack offset -16, then do whatever to restore the > original value > from the mangled value. This is represented by > (DW_OP_AARCH64_paciasp_deref, offset). > > .cfi_startproc > 0x0 paciasp (this instruction sign return address register LR/X30) > .cfi_val_expression 30, DW_OP_AARCH64_paciasp > 0x4 stp x29, x30, [sp, -32]! > .cfi_val_expression 30, DW_OP_AARCH64_paciasp_deref, -16 > .cfi_offset 29, -32 > .cfi_def_cfa_offset 32 > 0x8 add x29, sp, 0 > Now I'm confused. I was thinking that we needed one opcode for the sign operation in the prologue and one for the unsign/validate operation in the epilogue (to support non-call exceptions. But why do we need a separate code to say that a previously signed value has now been pushed on the stack? Surely that's just a normal store operation that can be tracked through the unwinding state machine. I was expecting the third opcode to be needed for the special operations that are not frequently used by the compiler. R. >> Perhaps if there is just 1 >> opcode and has all the info encoded just in one bigger uleb128 or >> something >> similar... >