From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by sourceware.org (Postfix) with ESMTPS id 0C143385B800 for ; Fri, 10 Feb 2023 14:19:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0C143385B800 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-wr1-x429.google.com with SMTP id r2so5206786wrv.7 for ; Fri, 10 Feb 2023 06:19:26 -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=UFp0E1+HD+E2PF2x3yrZ8MxJWWTb17vjO0oJ+ZPvwuI=; b=aVHwaQTSTbpC0ukTDcukdzuykV/iGJ1IzGuXTFUg5h4zccuOPvsL0PwFa85m0s5m7h lW6KNYkV3K5EFiHAIf0ArCD/wESm56CX/uzvy8AMzSb9uHSzPxQYYRR7J/iXFJWjQP4w q8bHrnbnHC15IGe57SdnaT7JX4//pT3eVDCCXJpBwg+R2f1KpzNDQN1rRx8oQOHdfuG6 eYe+QRrrlOzqN6SkF5u8qnkprf/tDSH5FhIU/d2C2LhqNq01C2LPugGdkNMsXUocz/At OiDzj1REQJ982oqTKAcnbz4q9IPEexXfH6S7Ga4UmUx/diuyTyKpFOy4SoCh1jtLmaUk onPg== 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=UFp0E1+HD+E2PF2x3yrZ8MxJWWTb17vjO0oJ+ZPvwuI=; b=DQs2RFYPkrt9znI3zsmU3NP1ONYwCngTaifCLU0Iquhge0H56rKdXrvkGyFutcaIBv Nyx7S7PhoFU9aLuXisS7t2FPBl1qxVkesXBJysSb4tjW8ZbrKpCpoCoLlAb9BM81+1ta sg2QLO9WmI0fx1Y6Ev3/cZ6NBz7UrCk5VH1D+RR3kgqLYdjZOuMjg0RP81ixogfTmepg AER9Lk4YiUaQt5r3vmVBdebLbeVwinO+p8229fCprUTe8sLeUZzqbf7RL58RY3KhCA5T 8qLYJKaOI4U1vkoZUmXuclu216c/yfz3QnzdPWCQTmAUd7F5LbS+rRUPnE9CyJXE6KG9 AdJA== X-Gm-Message-State: AO0yUKXvmfqCdkR8/nOAQT5qI6VNci9xIABrf6llbl3TcAonrW+fZYis X1AWujJGCcsm6YVfmiRIv69w+yjeQ/YSZLFE X-Google-Smtp-Source: AK7set+Mg3GOuZpVRI+eFhNkIYv8xEXzWe8XvgCKUoeDSAB/uSj4oy4a+t+edgzyNUE4NJepUm4o2g== X-Received: by 2002:adf:e5cb:0:b0:2c4:626:acd4 with SMTP id a11-20020adfe5cb000000b002c40626acd4mr8016051wrn.13.1676038764841; Fri, 10 Feb 2023 06:19:24 -0800 (PST) Received: from tpp.orcam.me.uk (tpp.orcam.me.uk. [2001:8b0:154:0:ea6a:64ff:fe24:f2fc]) by smtp.gmail.com with ESMTPSA id g16-20020adfe410000000b002bfae1398bbsm3678180wrm.42.2023.02.10.06.19.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Feb 2023 06:19:24 -0800 (PST) Date: Fri, 10 Feb 2023 14:19:23 +0000 (GMT) From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Andrew Burgess , Tom Tromey , Richard Bunt Subject: [PATCH v4 3/6] 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 silent 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. --- Changes from v3: - s/slient/silent/ in change description. 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 @@ -505,7 +505,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 @@ -513,7 +513,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. */ @@ -527,13 +527,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.