From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by sourceware.org (Postfix) with ESMTPS id EACFC3854382 for ; Thu, 12 Jan 2023 09:01:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EACFC3854382 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-x12a.google.com with SMTP id bq39so27518478lfb.0 for ; Thu, 12 Jan 2023 01:01:52 -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=xqluHNCIpW3vTSrMSsrnehW9x3dLuXNPvFBSc3T71Cg=; b=c8zanxEQw0aGri8Sd40+jOI459kAKadGl6fXyHvn50PEYe1EEiaC2rfACc/QWtEiil 5ERpVwn2ZKR5L76mYIcXGQ0X/IWnayhIoKN8a/qvnap5DgsRG2xgrzAETSHR9BKGVEsh Pbvu4RM36IDnP9NdbiDlDaCeOoVVTI7Rl1o3nsO64tzVtucPrN4HvxgHHgHtykLc051F u+1qNrU7WWL8+gv/b+bdOQlK6zPH2I71W8AEnhIsJVSRbJ61s29mX7EYn34wD7/4iJoS WE0MDINDjVmIpEDSwQzKVzT8Ab4SsKKzj+iB8rxQ9qY5NI9nS6Bc9B55DCJNGtrZRvGI qFkA== 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=xqluHNCIpW3vTSrMSsrnehW9x3dLuXNPvFBSc3T71Cg=; b=C2Ngzv5pBQRh1FSzb5zuwfvjld9skkSqRfY0EahQqAihNBn3xoPenzQAPbDDdB9uVh XTsflL9vPtfCCuHApoSGnnkygXR2/YTdKHUNOGfkwslYngIsrzYh0IGMZWtl5BZw6QSU Ck79uT17SrXRxPrkzX+8jV7ceiDT3VzWfm0G0iF0jZNu8Af+NZoR5OL37bjnqIaFVVUS ChSXwxnt0h8klifilXMZtkg2ujs4LQPcOvJbk1g9lSaJbOQxZjmwhJoHCwebyEXALY2P EYdTk5BuIMcae9ypPG1lZ5CRSTjdO8B7VUew7JlgFknARCEIMq6qcuMyrMSXrLMwpqX5 SZUg== X-Gm-Message-State: AFqh2krfzre9o6aJFTVPNQ0EHzZPcnY6qqP/7FDK2bV6TZv9Pg3oM/gq kxGMrfbfuP40n7kKHBg229HhCI1K0sBDCIcO X-Google-Smtp-Source: AMrXdXsJW5JeWP+60qusUBY8fWObK8W6wFQ3PXKvz6q1ZfOTxAAukhQBOnPOEm035Uu4O5p5YEy5jg== X-Received: by 2002:ac2:5f6a:0:b0:4cb:d16:3f09 with SMTP id c10-20020ac25f6a000000b004cb0d163f09mr14886909lfc.25.1673514112458; Thu, 12 Jan 2023 01:01:52 -0800 (PST) Received: from [192.168.219.3] ([78.8.192.131]) by smtp.gmail.com with ESMTPSA id y4-20020a0565123f0400b004cc590975f7sm3177420lfa.183.2023.01.12.01.01.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Jan 2023 01:01:52 -0800 (PST) Date: Thu, 12 Jan 2023 09:01:49 +0000 (GMT) From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Andrew Burgess , Tom Tromey , Richard Bunt Subject: [PATCH v2 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. --- 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.