From patchwork Mon Apr 24 16:22:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 68226 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8B9223857355 for ; Mon, 24 Apr 2023 16:23:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8B9223857355 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1682353430; bh=0Z3fgiV3BgE1Z1MsWOJJ7s6WtvzdnqHNvZiLrxafghM=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=HERQBcYjwOxCkZcm082LEyMBwJfcfjZQCQ5XaXMzYP01jitEUO1hVpd/FcszTigLp jvCvCq2VhWNu2dbj+0lHkrRBV42+/VHc4+s49YxQMIyftkQ3i/rXI8ebFzQwW3wARy 3BPQiKXoQh5WKkk7Z/XUJndxqPvVUtuV5c8/u3Hc= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd36.google.com (mail-io1-xd36.google.com [IPv6:2607:f8b0:4864:20::d36]) by sourceware.org (Postfix) with ESMTPS id 7EC93385840E for ; Mon, 24 Apr 2023 16:22:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7EC93385840E Received: by mail-io1-xd36.google.com with SMTP id ca18e2360f4ac-763c3429aa6so115036539f.2 for ; Mon, 24 Apr 2023 09:22:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682353349; x=1684945349; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0Z3fgiV3BgE1Z1MsWOJJ7s6WtvzdnqHNvZiLrxafghM=; b=MDmSCLgvhHCIZ21b8Hy7G/GoaBByI4yVo/P0mVFUOkfrllE249S+i1XE3tu6nol3vS j7AFV++x3g0+Q2cwTGPfnVLJheaqszGcM9CLTavF0hARmhj4Qia4/3ANeE3fNqh5hGV2 pX/chX2124I4gWB4K/dKP6StvXvDPa8atF2LM9ByHdfnHhWUdLoZtSMXMjZpKymMVThm 0LNGD1tiZsg97mm53l+tmh2uCneigpLK/4+pkbwQ93ovsG4NBOmdDo5J4Ev5qABMyT+o KwuCdRfpgBGvC2Kh4jQs+ZFed0qrn5mdLD5ttDK8qVHo2fJQJ9hCe1h4mg/n8zY7IRk9 s+rQ== X-Gm-Message-State: AAQBX9d2McFTmLNdsDdvO3cc7Y1KZgR4tRhqbLZeXfFuyE8PbokkmOcf Abgctlj4nJlYYOIP2saedVmLIBdop8IHNMNoFiivWg== X-Google-Smtp-Source: AKy350aKZppSdl2RUl9dnQMzFCAHlqZhehK8+fsTWVRTuON6IeHZKnCymyKpy0LtOUCGK9PP+7BU6A== X-Received: by 2002:a6b:e30f:0:b0:760:ac0c:480e with SMTP id u15-20020a6be30f000000b00760ac0c480emr6247456ioc.18.1682353349658; Mon, 24 Apr 2023 09:22:29 -0700 (PDT) Received: from localhost.localdomain (71-211-191-82.hlrn.qwest.net. [71.211.191.82]) by smtp.gmail.com with ESMTPSA id cx27-20020a056638491b00b0040fa19472bcsm3444049jab.92.2023.04.24.09.22.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Apr 2023 09:22:29 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFC 10/10] Use unrelocated_addr in dwarf2_fde Date: Mon, 24 Apr 2023 10:22:11 -0600 Message-Id: <20230424162211.682763-11-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230424162211.682763-1-tromey@adacore.com> References: <20230424162211.682763-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This changes dwarf2_fde to use the unrelocated_addr type. This pointed out a latent bug in dwarf2_frame_cache, where a relocated address is compared to an unrelocated address. --- gdb/dwarf2/frame.c | 71 +++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index 705e2a7eeb9..940a01e9612 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -112,14 +112,21 @@ typedef std::unordered_map dwarf2_cie_table; struct dwarf2_fde { + /* Return the final location in this FDE. */ + unrelocated_addr end_addr () const + { + return (unrelocated_addr) ((ULONGEST) initial_location + + address_range); + } + /* CIE for this FDE. */ struct dwarf2_cie *cie; /* First location associated with this FDE. */ - CORE_ADDR initial_location; + unrelocated_addr initial_location; /* Number of bytes of program instructions described by this FDE. */ - CORE_ADDR address_range; + ULONGEST address_range; /* Instruction sequence. */ const gdb_byte *instructions; @@ -173,10 +180,10 @@ static struct dwarf2_fde *dwarf2_frame_find_fde static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum, int eh_frame_p); -static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding, - int ptr_len, const gdb_byte *buf, - unsigned int *bytes_read_ptr, - CORE_ADDR func_base); +static ULONGEST read_encoded_value (struct comp_unit *unit, gdb_byte encoding, + int ptr_len, const gdb_byte *buf, + unsigned int *bytes_read_ptr, + unrelocated_addr func_base); /* See dwarf2/frame.h. */ @@ -948,8 +955,8 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache) LONGEST entry_cfa_sp_offset; int entry_cfa_sp_offset_p = 0; if (get_frame_func_if_available (this_frame, &entry_pc) - && fde->initial_location <= entry_pc - && entry_pc < fde->initial_location + fde->address_range) + && fde->initial_location <= (unrelocated_addr) (entry_pc - text_offset) + && (unrelocated_addr) (entry_pc - text_offset) < fde->end_addr ()) { /* Decode the insns in the FDE up to the entry PC. */ instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, @@ -1469,14 +1476,14 @@ encoding_for_size (unsigned int size) } } -static CORE_ADDR +static ULONGEST read_encoded_value (struct comp_unit *unit, gdb_byte encoding, int ptr_len, const gdb_byte *buf, unsigned int *bytes_read_ptr, - CORE_ADDR func_base) + unrelocated_addr func_base) { ptrdiff_t offset; - CORE_ADDR base; + ULONGEST base; /* GCC currently doesn't generate DW_EH_PE_indirect encodings for FDE's. */ @@ -1501,7 +1508,7 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding, base = unit->tbase; break; case DW_EH_PE_funcrel: - base = func_base; + base = (ULONGEST) func_base; break; case DW_EH_PE_aligned: base = 0; @@ -1576,9 +1583,9 @@ find_cie (const dwarf2_cie_table &cie_table, ULONGEST cie_pointer) } static inline int -bsearch_fde_cmp (const dwarf2_fde *fde, CORE_ADDR seek_pc) +bsearch_fde_cmp (const dwarf2_fde *fde, unrelocated_addr seek_pc) { - if (fde->initial_location + fde->address_range <= seek_pc) + if (fde->end_addr () <= seek_pc) return -1; if (fde->initial_location <= seek_pc) return 0; @@ -1619,7 +1626,6 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile) for (objfile *objfile : current_program_space->objfiles ()) { CORE_ADDR offset; - CORE_ADDR seek_pc; if (objfile->obfd == nullptr) continue; @@ -1640,15 +1646,15 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile) offset = objfile->text_section_offset (); gdb_assert (!fde_table->empty ()); - if (*pc < offset + (*fde_table)[0]->initial_location) + unrelocated_addr seek_pc = (unrelocated_addr) (*pc - offset); + if (seek_pc < (*fde_table)[0]->initial_location) continue; - seek_pc = *pc - offset; auto it = gdb::binary_search (fde_table->begin (), fde_table->end (), seek_pc, bsearch_fde_cmp); if (it != fde_table->end ()) { - *pc = (*it)->initial_location + offset; + *pc = (CORE_ADDR) (*it)->initial_location + offset; if (out_per_objfile != nullptr) *out_per_objfile = get_dwarf2_per_objfile (objfile); @@ -1884,7 +1890,7 @@ decode_frame_entry_1 (struct gdbarch *gdbarch, /* Skip. Avoid indirection since we throw away the result. */ gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect; read_encoded_value (unit, encoding, cie->ptr_size, - buf, &bytes_read, 0); + buf, &bytes_read, (unrelocated_addr) 0); buf += bytes_read; augmentation++; } @@ -1920,7 +1926,6 @@ decode_frame_entry_1 (struct gdbarch *gdbarch, { /* This is a FDE. */ struct dwarf2_fde *fde; - CORE_ADDR addr; /* Check that an FDE was expected. */ if ((entry_type & EH_FDE_TYPE_ID) == 0) @@ -1953,16 +1958,19 @@ decode_frame_entry_1 (struct gdbarch *gdbarch, gdb_assert (fde->cie != NULL); - addr = read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size, - buf, &bytes_read, 0); - fde->initial_location = gdbarch_adjust_dwarf2_addr (gdbarch, addr); + ULONGEST init_addr + = read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size, + buf, &bytes_read, (unrelocated_addr) 0); + fde->initial_location + = (unrelocated_addr) gdbarch_adjust_dwarf2_addr (gdbarch, init_addr); buf += bytes_read; - fde->address_range = - read_encoded_value (unit, fde->cie->encoding & 0x0f, - fde->cie->ptr_size, buf, &bytes_read, 0); - addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + fde->address_range); - fde->address_range = addr - fde->initial_location; + ULONGEST range + = read_encoded_value (unit, fde->cie->encoding & 0x0f, + fde->cie->ptr_size, buf, &bytes_read, + (unrelocated_addr) 0); + ULONGEST addr = gdbarch_adjust_dwarf2_addr (gdbarch, init_addr + range); + fde->address_range = addr - (ULONGEST) fde->initial_location; buf += bytes_read; /* A 'z' augmentation in the CIE implies the presence of an @@ -2214,7 +2222,7 @@ dwarf2_build_frame_info (struct objfile *objfile) one. */ for (struct dwarf2_fde *fde : fde_table) { - if (fde->initial_location != 0) + if (fde->initial_location != (unrelocated_addr) 0) { first_non_zero_fde = fde; break; @@ -2226,10 +2234,9 @@ dwarf2_build_frame_info (struct objfile *objfile) Also discard leftovers from --gc-sections. */ for (struct dwarf2_fde *fde : fde_table) { - if (fde->initial_location == 0 + if (fde->initial_location == (unrelocated_addr) 0 && first_non_zero_fde != NULL - && (first_non_zero_fde->initial_location - < fde->initial_location + fde->address_range)) + && first_non_zero_fde->initial_location < fde->end_addr ()) continue; if (fde_prev != NULL