From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4594 invoked by alias); 3 Oct 2012 15:59:35 -0000 Received: (qmail 4583 invoked by uid 22791); 3 Oct 2012 15:59:34 -0000 X-SWARE-Spam-Status: No, hits=-3.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_XF X-Spam-Check-By: sourceware.org Received: from mail-vc0-f169.google.com (HELO mail-vc0-f169.google.com) (209.85.220.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 03 Oct 2012 15:59:29 +0000 Received: by vcbfl17 with SMTP id fl17so9609138vcb.0 for ; Wed, 03 Oct 2012 08:59:28 -0700 (PDT) MIME-Version: 1.0 Received: by 10.58.116.212 with SMTP id jy20mr635136veb.5.1349279968783; Wed, 03 Oct 2012 08:59:28 -0700 (PDT) Received: by 10.58.146.138 with HTTP; Wed, 3 Oct 2012 08:59:28 -0700 (PDT) In-Reply-To: <201210031543.q93FhTPo021324@glazunov.sibelius.xs4all.nl> References: <201210031543.q93FhTPo021324@glazunov.sibelius.xs4all.nl> Date: Wed, 03 Oct 2012 15:59:00 -0000 Message-ID: Subject: Re: PING: PATCH: PR backtrace/14646: [x32] backtrace doesn't work From: "H.J. Lu" To: Mark Kettenis Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 X-IsSubscribed: yes 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 X-SW-Source: 2012-10/txt/msg00040.txt.bz2 On Wed, Oct 3, 2012 at 8:43 AM, Mark Kettenis wrote: >> Date: Wed, 3 Oct 2012 08:26:34 -0700 >> From: "H.J. Lu" >> >> On Sun, Sep 30, 2012 at 2:40 PM, H.J. Lu wrote: >> > Hi, >> > >> > amd64_x32_init_abi has >> > >> > tdep->sp_regnum_from_eax = AMD64_RSP_REGNUM; >> > tdep->pc_regnum_from_eax = AMD64_RIP_REGNUM; >> > >> > But unwind frame info is based on the real RSP/RIP >> > registers. Pseudo sp/pc registers don't work with >> > frame related codes: >> > >> > [hjl@gnu-tools-1 gdb]$ egrep "pc_regnum|sp_regnum" *fram*.c >> > dwarf2-frame.c: if (regnum == gdbarch_pc_regnum (gdbarch)) >> > dwarf2-frame.c: else if (regnum == gdbarch_sp_regnum (gdbarch)) >> > dwarf2-frame.c: == gdbarch_sp_regnum (gdbarch))) >> > dwarf2-frame-tailcall.c: if (regnum == gdbarch_pc_regnum >> > (this_gdbarch)) >> > dwarf2-frame-tailcall.c: else if (cache->prev_sp_p && regnum == >> > gdbarch_sp_regnum (this_gdbarch)) >> > dwarf2-frame-tailcall.c: int sp_regnum; >> > dwarf2-frame-tailcall.c: sp_regnum = gdbarch_sp_regnum >> > (prev_gdbarch); >> > dwarf2-frame-tailcall.c: if (sp_regnum == -1) >> > dwarf2-frame-tailcall.c: prev_sp = frame_unwind_register_unsigned >> > (this_frame, sp_regnum); >> > frame.c: && gdbarch_pc_regnum (gdbarch) >= 0 >> > frame.c: gdbarch_pc_regnum (gdbarch), >> > frame.c: gdbarch_pc_regnum (gdbarch), >> > frame.c: the gdbarch_sp_regnum register is meaningful. */ >> > frame.c: if (gdbarch_sp_regnum (gdbarch) >= 0) >> > frame.c: gdbarch_sp_regnum (gdbarch)); >> > [hjl@gnu-tools-1 gdb]$ >> > >> > It is nice to print >> > >> > (gdb) p $sp >> > $1 = (void *) 0xffffd028 >> > >> > instead of >> > >> > (gdb) p $sp >> > $1 = 4294955048 >> > >> > But it breaks frame unwind. This patch removes pseudo sp/pc regnum from >> > x32. "p $sp" and "p $pc" will print 64bit integers. But "p $esp" and >> > "p $esp" work fine. OK for trunk and 4.5 branch? >> > >> > Thanks. >> > >> > >> > H.J. >> > --- >> > 2012-09-30 H.J. Lu >> > >> > PR backtrace/14646 >> > PR gdb/14647 >> > * i386-tdep.h (gdbarch_tdep): Remove sp_regnum_from_eax and >> > pc_regnum_from_eax. >> > * i386-tdep.c (i386_gdbarch_init): Don't use sp_regnum_from_eax >> > nor pc_regnum_from_eax. >> > * amd64-tdep.c (amd64_x32_init_abi): Don't set sp_regnum_from_eax >> > nor pc_regnum_from_eax. >> > > > There's got to be a better way to handle that. Did you look into > using dwarf2_frame_set_init_reg() to establish mappings to the "raw" > rip and rsp registers? It doesn't work for x32 since gdbarch_sp_regnum and gdbarch_pc_regnum are used like: if (get_frame_func_if_available (this_frame, &entry_pc)) { /* Decode the insns in the FDE up to the entry PC. */ instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, entry_pc, fs); if (fs->regs.cfa_how == CFA_REG_OFFSET && (gdbarch_dwarf2_reg_to_regnum (gdbarch, fs->regs.cfa_reg) == gdbarch_sp_regnum (gdbarch))) { entry_cfa_sp_offset = fs->regs.cfa_offset; entry_cfa_sp_offset_p = 1; } } gdbarch_sp_regnum will return the wrong register number. If there are gdbarch_frame_sp_regnum and gdbarch_frame_pc_regnum, which default to gdbarch_sp_regnum and gdbarch_pc_regnum, respectively, and use them everywhere, except for "p $pc/$sp", x32 can set up proper gdbarch_frame_sp_regnum and gdbarch_frame_pc_regnum. -- H.J.