From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by sourceware.org (Postfix) with ESMTPS id 9F37A3858C2B for ; Mon, 23 Jan 2023 23:13:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9F37A3858C2B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-lf1-x12c.google.com with SMTP id bp15so20541114lfb.13 for ; Mon, 23 Jan 2023 15:13:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=mime-version:user-agent:references:message-id:in-reply-to:subject :cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=WfekJsD2yf32GXC8bBKliX8UYayl1iou3O9p2kr6+jU=; b=XwWd8524xr20GRn6wLGEyDw9okl4guAwvB8+xV8z5WnI6T5Vqcs7Hdx3Hl1GScRAmV wTQhMxRm+3j0gWT0cfByRgobpQC70lqE8LtHlzBskscHnUPCACzKsZUWgrVEn0gr50QW AaRFzpgdlUsJLj7jbSP5JffPqtiWV4Liwa/xV0pbODvXOiD4DkkdDGZUfN89s0GKjc24 KWk2wh8m0uDWlDmQVoNyLfJlMHjiPK6hlc+V9CwcVb6zhsFu2505fE0L76kBmtCAy4WR vNdpqNPNONltiDFTzS3gUaQotinAt2xvXNLQC1sUaVBjQ8/NhcwgvQCoA2K/lD2UBwrb AZLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:references:message-id:in-reply-to:subject :cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=WfekJsD2yf32GXC8bBKliX8UYayl1iou3O9p2kr6+jU=; b=hORwrt4WaB3LqMoRNqE04DrvH31XAQ/FZ6NqzD1vnp722Pt2SjJP+a4KQRU5r/1Zn7 hiU51fJVfx5Y48hFdwj7I65khivxipndPiwyOoDvBr+vXUJl1CpOOtTSRi+Up0qKt/+L CGEA/7HWWsPSoXPNTlXCqOkMcj+n2NnI6r7W1r6HwomnlBgJ1QPjgFKXooAly8HZzlbI pp3AhaVzrMIQnpuqrXwmdOXrlZd4fXgfN1oKuVM9x5R5zHvGkILvf6eJsMq/xCgB8+4K jY8coxpwsLlwh44PxUUnrCFrTAu3axB6MbMP4b7zU9l7UyamFkWPu8cAdLrxhNi8bsYp qfBg== X-Gm-Message-State: AFqh2kq6OswTABr/P2Xz3NwuDzzaOCRVB1J9Mc7DZNR5Hl/sAMIs4VFE ntmHrHZnUTk4ZGrSz8zqVnild/l1qkOGsYU2 X-Google-Smtp-Source: AMrXdXsovgHkqfBSO+ED5mRXPXdvHSVA6VPfiNcOmS/gHMNYZXPtTXkrF9y1KvQhHCtWWDT0KBD5dQ== X-Received: by 2002:ac2:5699:0:b0:4cb:2b23:9965 with SMTP id 25-20020ac25699000000b004cb2b239965mr6108711lfr.63.1674515636218; Mon, 23 Jan 2023 15:13:56 -0800 (PST) Received: from [192.168.219.3] ([78.8.192.131]) by smtp.gmail.com with ESMTPSA id c6-20020ac25306000000b004cc5f44747dsm18690lfh.220.2023.01.23.15.13.53 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Jan 2023 15:13:55 -0800 (PST) Date: Mon, 23 Jan 2023 23:13:51 +0000 (GMT) From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Andrew Burgess , Tom Tromey , Richard Bunt Subject: [PATCH v3 2/5] GDB: Fix the mess with value byte/bit range types In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Consistently use the LONGEST and ULONGEST types for value byte/bit offsets and lengths respectively, avoiding slient truncation for ranges exceeding the 32-bit span, which may cause incorrect matching. Also report a conversion overflow on byte ranges that cannot be expressed in terms of bits with these data types, e.g.: (gdb) print one_hundred[1LL << 58] Integer overflow in data location calculation (gdb) print one_hundred[(-1LL << 58) - 1] Integer overflow in data location calculation (gdb) Previously such accesses would be let through with unpredictable results produced. --- No change from v2. New change in v2. --- gdb/value.c | 43 ++++++++++++++++++++++++++----------------- gdb/value.h | 8 ++++---- 2 files changed, 30 insertions(+), 21 deletions(-) gdb-value-range-types.diff Index: src/gdb/value.c =================================================================== --- src.orig/gdb/value.c +++ src/gdb/value.c @@ -74,7 +74,7 @@ struct range LONGEST offset; /* Length of the range. */ - LONGEST length; + ULONGEST length; /* Returns true if THIS is strictly less than OTHER, useful for searching. We keep ranges sorted by offset and coalesce @@ -97,10 +97,10 @@ struct range [offset2, offset2+len2) overlap. */ static int -ranges_overlap (LONGEST offset1, LONGEST len1, - LONGEST offset2, LONGEST len2) +ranges_overlap (LONGEST offset1, ULONGEST len1, + LONGEST offset2, ULONGEST len2) { - ULONGEST h, l; + LONGEST h, l; l = std::max (offset1, offset2); h = std::min (offset1 + len1, offset2 + len2); @@ -112,7 +112,7 @@ ranges_overlap (LONGEST offset1, LONGEST static int ranges_contain (const std::vector &ranges, LONGEST offset, - LONGEST length) + ULONGEST length) { range what; @@ -380,7 +380,8 @@ get_value_arch (const struct value *valu } int -value_bits_available (const struct value *value, LONGEST offset, LONGEST length) +value_bits_available (const struct value *value, + LONGEST offset, ULONGEST length) { gdb_assert (!value->lazy); @@ -389,8 +390,16 @@ value_bits_available (const struct value int value_bytes_available (const struct value *value, - LONGEST offset, LONGEST length) + LONGEST offset, ULONGEST length) { + ULONGEST sign = (1ULL << (sizeof (ULONGEST) * 8 - 1)) / TARGET_CHAR_BIT; + ULONGEST mask = (sign << 1) - 1; + + if (offset != ((offset & mask) ^ sign) - sign + || length != ((length & mask) ^ sign) - sign + || (length > 0 && (~offset & (offset + length - 1) & sign) != 0)) + error (_("Integer overflow in data location calculation")); + return value_bits_available (value, offset * TARGET_CHAR_BIT, length * TARGET_CHAR_BIT); @@ -460,7 +469,7 @@ value_entirely_optimized_out (struct val static void insert_into_bit_range_vector (std::vector *vectorp, - LONGEST offset, LONGEST length) + LONGEST offset, ULONGEST length) { range newr; @@ -558,8 +567,8 @@ insert_into_bit_range_vector (std::vecto if (ranges_overlap (bef.offset, bef.length, offset, length)) { /* #1 */ - ULONGEST l = std::min (bef.offset, offset); - ULONGEST h = std::max (bef.offset + bef.length, offset + length); + LONGEST l = std::min (bef.offset, offset); + LONGEST h = std::max (bef.offset + bef.length, offset + length); bef.offset = l; bef.length = h - l; @@ -600,7 +609,7 @@ insert_into_bit_range_vector (std::vecto struct range &r = *i; if (r.offset <= t.offset + t.length) { - ULONGEST l, h; + LONGEST l, h; l = std::min (t.offset, r.offset); h = std::max (t.offset + t.length, r.offset + r.length); @@ -626,14 +635,14 @@ insert_into_bit_range_vector (std::vecto void mark_value_bits_unavailable (struct value *value, - LONGEST offset, LONGEST length) + LONGEST offset, ULONGEST length) { insert_into_bit_range_vector (&value->unavailable, offset, length); } void mark_value_bytes_unavailable (struct value *value, - LONGEST offset, LONGEST length) + LONGEST offset, ULONGEST length) { mark_value_bits_unavailable (value, offset * TARGET_CHAR_BIT, @@ -786,7 +795,7 @@ static int find_first_range_overlap_and_match (struct ranges_and_idx *rp1, struct ranges_and_idx *rp2, LONGEST offset1, LONGEST offset2, - LONGEST length, ULONGEST *l, ULONGEST *h) + ULONGEST length, ULONGEST *l, ULONGEST *h) { rp1->idx = find_first_range_overlap (rp1->ranges, rp1->idx, offset1, length); @@ -1306,14 +1315,14 @@ value_contents_all (struct value *value) static void ranges_copy_adjusted (std::vector *dst_range, int dst_bit_offset, const std::vector &src_range, int src_bit_offset, - int bit_length) + unsigned int bit_length) { for (const range &r : src_range) { - ULONGEST h, l; + LONGEST h, l; l = std::max (r.offset, (LONGEST) src_bit_offset); - h = std::min (r.offset + r.length, + h = std::min ((LONGEST) (r.offset + r.length), (LONGEST) src_bit_offset + bit_length); if (l < h) Index: src/gdb/value.h =================================================================== --- src.orig/gdb/value.h +++ src/gdb/value.h @@ -512,7 +512,7 @@ extern int value_bits_synthetic_pointer byte is unavailable. */ extern int value_bytes_available (const struct value *value, - LONGEST offset, LONGEST length); + LONGEST offset, ULONGEST length); /* Given a value, determine whether the contents bits starting at OFFSET and extending for LENGTH bits are available. This returns @@ -520,7 +520,7 @@ extern int value_bytes_available (const bit is unavailable. */ extern int value_bits_available (const struct value *value, - LONGEST offset, LONGEST length); + LONGEST offset, ULONGEST length); /* Like value_bytes_available, but return false if any byte in the whole object is unavailable. */ @@ -534,13 +534,13 @@ extern int value_entirely_unavailable (s LENGTH bytes as unavailable. */ extern void mark_value_bytes_unavailable (struct value *value, - LONGEST offset, LONGEST length); + LONGEST offset, ULONGEST length); /* Mark VALUE's content bits starting at OFFSET and extending for LENGTH bits as unavailable. */ extern void mark_value_bits_unavailable (struct value *value, - LONGEST offset, LONGEST length); + LONGEST offset, ULONGEST length); /* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with LENGTH bytes of VAL2's contents starting at OFFSET2.