From patchwork Fri Aug 9 15:03:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 34017 Received: (qmail 42553 invoked by alias); 9 Aug 2019 15:03:17 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 42545 invoked by uid 89); 9 Aug 2019 15:03:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=belonging X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Aug 2019 15:03:15 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 4E332B008; Fri, 9 Aug 2019 15:03:13 +0000 (UTC) Subject: Re: [PATCH][gdb] Fix gdb.arch/amd64-tailcall-*.exp with -fPIE/-pie To: Pedro Alves , gdb-patches@sourceware.org Cc: Jan Kratochvil References: <20190809104848.GA6563@delia> <57ada901-a8d8-b632-f7d8-e42283314b5a@redhat.com> From: Tom de Vries Openpgp: preference=signencrypt Message-ID: <38825791-ad92-3f7e-d3ae-2ac123dd6422@suse.de> Date: Fri, 9 Aug 2019 17:03:12 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <57ada901-a8d8-b632-f7d8-e42283314b5a@redhat.com> X-IsSubscribed: yes On 09-08-19 15:57, Pedro Alves wrote: > On 8/9/19 11:48 AM, Tom de Vries wrote: >> @@ -240,14 +242,38 @@ pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache) >> gdb_assert (next_levels >= 0); >> >> if (next_levels < chain->callees) >> - return chain->call_site[chain->length - next_levels - 1]->pc; >> + { >> + struct call_site *call_site >> + = chain->call_site[chain->length - next_levels - 1]; >> + CORE_ADDR addr = call_site->pc; >> + struct dwarf2_per_objfile *dwarf2_per_objfile >> + = call_site->per_cu->dwarf2_per_objfile; >> + struct objfile *objfile = dwarf2_per_objfile->objfile; >> + CORE_ADDR baseaddr >> + = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); >> + struct gdbarch *gdbarch = get_objfile_arch (objfile); >> + addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr); >> + return addr; >> + } >> next_levels -= chain->callees; >> >> /* Otherwise CHAIN->CALLEES are already covered by CHAIN->CALLERS. */ >> if (chain->callees != chain->length) >> { >> if (next_levels < chain->callers) >> - return chain->call_site[chain->callers - next_levels - 1]->pc; >> + { >> + struct call_site *call_site >> + = chain->call_site[chain->callers - next_levels - 1]; >> + CORE_ADDR addr = call_site->pc; >> + struct dwarf2_per_objfile *dwarf2_per_objfile >> + = call_site->per_cu->dwarf2_per_objfile; >> + struct objfile *objfile = dwarf2_per_objfile->objfile; >> + CORE_ADDR baseaddr >> + = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); >> + struct gdbarch *gdbarch = get_objfile_arch (objfile); >> + addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr); >> + return addr; >> + } > > It seems like there's a repeated pattern here. How about > factoring out the common code to a function? Indeed. How about this? Thanks, - Tom [gdb] Fix gdb.arch/amd64-tailcall-*.exp with -fPIE/-pie When running gdb.arch/amd64-tailcall-*.exp with target board unix/-fPIE/-pie, we get: ... FAIL: gdb.arch/amd64-tailcall-cxx.exp: bt FAIL: gdb.arch/amd64-tailcall-noret.exp: bt FAIL: gdb.arch/amd64-tailcall-self.exp: bt ... The first FAIL in more detail, compared to a nopie run: ... (gdb) bt #0 b () -#1 0x00000000004004df in a (q=) +#1 0x0000000000000672 in ?? () -#2 0x00000000004003d5 in main (argc=, argv=) +#2 0x0000555555554535 in main (argc=, argv=) -(gdb) PASS: gdb.arch/amd64-tailcall-self.exp: bt +(gdb) FAIL: gdb.arch/amd64-tailcall-self.exp: bt ... shows an unrelocated address for function a. The problem is that pretend_pc uses the pc field from a struct call_site without adding the missing relocation offset. Fix this by adding the appropriate offset. Tested on x86_64-linux, with and without -fPIE/-pie. gdb/ChangeLog: 2019-08-09 Tom de Vries * dwarf2-frame-tailcall.c (relocate_text_addr): New function. (pretend_pc): Add relocation offset to pc field of struct call_site. --- gdb/dwarf2-frame-tailcall.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/gdb/dwarf2-frame-tailcall.c b/gdb/dwarf2-frame-tailcall.c index e8f5aaf9c7..2cd2d532f9 100644 --- a/gdb/dwarf2-frame-tailcall.c +++ b/gdb/dwarf2-frame-tailcall.c @@ -29,6 +29,8 @@ #include "value.h" #include "dwarf2-frame.h" #include "gdbarch.h" +#include "dwarf2read.h" +#include "objfiles.h" /* Contains struct tailcall_cache indexed by next_bottom_frame. */ static htab_t cache_htab; @@ -225,6 +227,19 @@ tailcall_frame_this_id (struct frame_info *this_frame, void **this_cache, gdb_assert ((*this_id).artificial_depth > 0); } +/* Given an unrelocated address ADDR belonging to the text section of OBJFILE, + return the relocated address. */ + +static CORE_ADDR +relocate_text_addr (CORE_ADDR addr, struct objfile *objfile) +{ + CORE_ADDR baseaddr + = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + struct gdbarch *gdbarch = get_objfile_arch (objfile); + addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr); + return addr; +} + /* Find PC to be unwound from THIS_FRAME. THIS_FRAME must be a part of CACHE. */ @@ -240,14 +255,25 @@ pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache) gdb_assert (next_levels >= 0); if (next_levels < chain->callees) - return chain->call_site[chain->length - next_levels - 1]->pc; + { + struct call_site *call_site + = chain->call_site[chain->length - next_levels - 1]; + struct objfile *objfile = call_site->per_cu->dwarf2_per_objfile->objfile; + return relocate_text_addr (call_site->pc, objfile); + } next_levels -= chain->callees; /* Otherwise CHAIN->CALLEES are already covered by CHAIN->CALLERS. */ if (chain->callees != chain->length) { if (next_levels < chain->callers) - return chain->call_site[chain->callers - next_levels - 1]->pc; + { + struct call_site *call_site + = chain->call_site[chain->callers - next_levels - 1]; + struct objfile *objfile + = call_site->per_cu->dwarf2_per_objfile->objfile; + return relocate_text_addr (call_site->pc, objfile); + } next_levels -= chain->callers; }