From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7471 invoked by alias); 3 Jun 2014 14:51:15 -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 7461 invoked by uid 89); 3 Jun 2014 14:51:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS,UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 03 Jun 2014 14:51:13 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s53EpAAC024339 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 3 Jun 2014 10:51:11 -0400 Received: from redacted.bos.redhat.com ([10.18.17.143]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s53Ep8fO012474 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Tue, 3 Jun 2014 10:51:10 -0400 Date: Tue, 03 Jun 2014 14:51:00 -0000 From: Kyle McMartin To: Andrew Pinski Cc: "gdb-patches@sourceware.org" Subject: Re: [PATCH 2/2] aarch64: implement walking over the stack protector Message-ID: <20140603145108.GF15355@redacted.bos.redhat.com> References: <20140603050011.GA15355@redacted.bos.redhat.com> <20140603050314.GC15355@redacted.bos.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2014-06/txt/msg00087.txt.bz2 On Mon, Jun 02, 2014 at 10:42:32PM -0700, Andrew Pinski wrote: > > + adrp x0, __stack_chk_guard > > + add x0, x0, #:lo12:__stack_chk_guard > > + ldr x0, [x0] > > + str x0, [x29, #end-of-stack] > > Can you expand this for ILP32? The sequence is the same except to use > w0 instead of x0. Otherwise I can put it on my todo list to after I > submit the gdb support for ILP32. > I'll look into it. Thanks Andrew. --Kyle > Thanks, > Andrew Pinski > > > + > > + Which loads the address of __stack_chk_guard, then loads the guard from it, > > + and stores it at the end of the stack. */ > > + > > +static CORE_ADDR > > +aarch64_skip_stack_chk_guard (CORE_ADDR pc, struct gdbarch *gdbarch) > > +{ > > + enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); > > + CORE_ADDR addr = pc; > > + CORE_ADDR loc = pc; > > + uint32_t insn; > > + int64_t imm; > > + int32_t imm32; > > + unsigned rd, rd2, rn, rt; > > + int page; > > + const int insn_size = 4; > > + struct bound_minimal_symbol stack_chk_guard; > > + > > + /* Attempt to find the label formation of __stack_chk_guard. */ > > + insn = read_memory_unsigned_integer (loc, insn_size, byte_order_for_code); > > + if (!decode_adrp (loc, insn, &page, &rd, &imm)) > > + return pc; > > + > > + /* Bail if we saw an ADR instruction, not an ADRP. */ > > + if (!page) > > + return pc; > > + > > + loc += insn_size; > > + addr &= ~((1 << 12) - 1); > > + addr += imm; > > + > > + insn = read_memory_unsigned_integer (loc, insn_size, byte_order_for_code); > > + if (!decode_add_sub_imm (loc, insn, &rd2, &rn, &imm32)) > > + return pc; > > + > > + /* Ensure ADD register matches the ADRP instruction. */ > > + if (rn != rd) > > + return pc; > > + > > + loc += insn_size; > > + addr += imm32; > > + > > + /* See if we calculated the address of the __stack_chk_guard symbol. */ > > + stack_chk_guard = lookup_minimal_symbol_by_pc (addr); > > + if (stack_chk_guard.minsym > > + && strncmp (MSYMBOL_LINKAGE_NAME (stack_chk_guard.minsym), > > + "__stack_chk_guard", strlen ("__stack_chk_guard")) != 0) > > + return pc; > > + > > + /* Check if the next instruction is a load from the same registers. */ > > + insn = read_memory_unsigned_integer (loc, insn_size, byte_order_for_code); > > + if (decode_masked_match (insn, 0xffc00000, 0xf9400000)) > > + { > > + rt = insn & 0x1F; > > + rn = (insn >> 5) & 0x1F; > > + > > + if (rn != rd2) > > + return pc; > > + } > > + else > > + return pc; > > + > > + /* Finally, look for a store of the guard to the stack. */ > > + loc += insn_size; > > + insn = read_memory_unsigned_integer (loc, insn_size, byte_order_for_code); > > + if (decode_masked_match (insn, 0xffc00000, 0xf9000000)) > > + { > > + unsigned rt2 = insn & 0x1F; > > + > > + /* Check we're storing the guard from the previous load instruction. */ > > + if (rt2 != rt) > > + return pc; > > + } > > + else > > + return pc; > > + > > + /* If we've made it this far, we've walked through the 4 instruction > > + sequence around __stack_chk_guard, and can skip over it in the function > > + prologue. */ > > + return loc + insn_size; > > +} > > + > > /* Implement the "skip_prologue" gdbarch method. */ > > > > static CORE_ADDR > > @@ -871,7 +964,11 @@ aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) > > = skip_prologue_using_sal (gdbarch, func_addr); > > > > if (post_prologue_pc != 0) > > - return max (pc, post_prologue_pc); > > + { > > + post_prologue_pc = aarch64_skip_stack_chk_guard (post_prologue_pc, > > + gdbarch); > > + return max (pc, post_prologue_pc); > > + } > > } > > > > /* Can't determine prologue from the symbol table, need to examine > > diff --git a/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.c b/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.c > > new file mode 100644 > > index 0000000..3cf52d9 > > --- /dev/null > > +++ b/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.c > > @@ -0,0 +1,28 @@ > > +/* This file is part of GDB, the GNU debugger. > > + > > + Copyright 2014 Free Software Foundation, Inc. > > + > > + This program is free software; you can redistribute it and/or modify > > + it under the terms of the GNU General Public License as published by > > + the Free Software Foundation; either version 3 of the License, or > > + (at your option) any later version. > > + > > + This program is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + GNU General Public License for more details. > > + > > + You should have received a copy of the GNU General Public License > > + along with this program. If not, see . */ > > + > > +int stack_chk_guard_fn(void) > > +{ > > + /* Needs to be large enough to trigger -fstack-protector. */ > > + char stack[64]; > > + return 0; /* Post function prologue statement. */ > > +} > > + > > +int main(void) > > +{ > > + return stack_chk_guard_fn(); > > +} > > diff --git a/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.exp b/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.exp > > new file mode 100644 > > index 0000000..7f60867 > > --- /dev/null > > +++ b/gdb/testsuite/gdb.arch/aarch64-stack_chk_guard.exp > > @@ -0,0 +1,43 @@ > > +# Copyright 2014 Free Software Foundation, Inc. > > +# > > +# This program is free software; you can redistribute it and/or modify > > +# it under the terms of the GNU General Public License as published by > > +# the Free Software Foundation; either version 3 of the License, or > > +# (at your option) any later version. > > +# > > +# This program is distributed in the hope that it will be useful, > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +# GNU General Public License for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with this program; if not, write to the Free Software > > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > > +# > > +# This file is part of the gdb testsuite. > > + > > +# Test that we single step past the __stack_chk_guard setup in the > > +# prologue of functions. > > + > > +if {![istarget "aarch64*"]} { > > + verbose "Skipping ${gdb_test_file_name}." > > + return > > +} > > + > > +standard_testfile > > +set additional_flags "additional_flags=-fstack-protector" > > +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } { > > + unsupported "compiler does not support -fstack-protector" > > + return > > +} > > + > > +clean_restart "${binfile}" > > +if ![runto_main] { > > + untested "could not run to main" > > + return -1 > > +} > > + > > +gdb_breakpoint "stack_chk_guard_fn" > > + > > +# Previously, we'd see a { as we're still in the function prologue. > > +gdb_continue_to_breakpoint "continue into stack_chk_guard_fn" ".*return 0;.*" > > -- > > 1.9.3 > >