From patchwork Mon Oct 16 02:28:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 23584 Received: (qmail 21530 invoked by alias); 16 Oct 2017 02:29:47 -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 21521 invoked by uid 89); 16 Oct 2017 02:29:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: sesbmg23.ericsson.net Received: from sesbmg23.ericsson.net (HELO sesbmg23.ericsson.net) (193.180.251.37) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 16 Oct 2017 02:29:44 +0000 Received: from ESESSHC011.ericsson.se (Unknown_Domain [153.88.183.51]) by sesbmg23.ericsson.net (Symantec Mail Security) with SMTP id 30.33.03220.59914E95; Mon, 16 Oct 2017 04:29:41 +0200 (CEST) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.51) with Microsoft SMTP Server (TLS) id 14.3.352.0; Mon, 16 Oct 2017 04:28:51 +0200 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from elxacz23q12.lan (192.222.251.162) by DBXPR07MB318.eurprd07.prod.outlook.com (2a01:111:e400:941d::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.156.3; Mon, 16 Oct 2017 02:28:48 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH] Get rid of VEC(mem_range_s) Date: Sun, 15 Oct 2017 22:28:38 -0400 Message-ID: <1508120918-14039-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 X-ClientProxiedBy: BN6PR14CA0027.namprd14.prod.outlook.com (2603:10b6:404:13f::13) To DBXPR07MB318.eurprd07.prod.outlook.com (2a01:111:e400:941d::12) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 01c475d8-5df1-41f8-ff1d-08d5143da27e X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:DBXPR07MB318; X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB318; 3:BbxL48EqvZxbAdRiUMpKYBVqBVhaW/tkHFrvsNsFyhtcV2LmexzmNAxp3bzZf0r6cri4FJ6V8INdlcbOoXh3yToe8JrrEVR4RDA+IyvZYngMPdGk70BctDy4balXj3TIyMf2rVKAbUVoUbKH//x2Z1HNPa8kY0P4cfOPilZlDH+TntlV2OJTX2ysra7tKrVJUHi+32hSwkgdkA4s0D47C55nguW3OnDWN5epRcpTGyJ8Mu+ScBLrEHGeq0/QAcKz; 25:4elupIx6dxKMN12rpPUUYXbVsdY4n4CQu2qT6PB6nXGznnObDqZGwanUaGK29MSrS28hvf9tQG/k34nOhhNfzhygmWT4wdQq0ton2xL9HMV16OSxgFRVLq4+y+RINlzsdyvgYqdQhmBedSaI+lFW82YX6nm+BGtlHaH6vwe84h02zLFWKfuKzuqos6iRZUJxnMkpqDYRHW2J5bkJbK4WZDEZ7azvbwna7LKSiyq9DAmUdMe3xVD9D2JOfpH0LSn0lz8kHr9S/JwM+rc8uxParxgUTN3d+iudWXs/kOwklMeeg1d2S3BPplEXVwEqN62K+43V+A6H5leoq1Hmcz7W3uVdOiW9Z6vGG5Y3G71zqlo=; 31:5TWBd5yhL+G0XJADH1e4Y0KrRbrY7Ks0sBijnVEJqF7ZDTigVO2wqR7Dllq1UflaU0Shapj4icZE2dq7P+Yfdk44XxUoMRL6FI0vJBjKCeTRRNBIjEWj7/lvaDtv8Ndd/Vmyna8kHoz1xvNNSY5Sb6ZURD4DZd4GYEHmhwR108zFlFxSRtttBq+FeRksj5NTymPMhI35zkM0mDM+KnSQG4HNA3M/PLQ8Kw7y6QcsRq4= X-MS-TrafficTypeDiagnostic: DBXPR07MB318: X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB318; 20:Gf01wgsayQDsdJL6GzCVe8h1w3lRbD7/hc/OgwQEBtnw9jP6hJ5K2PZfaCz/zRqPL7RLBzRKy17IgJQYHCm2vHpl9ZN26kIRexeGoogV/pdNkBJ4ndjb26uRz11/bMKzwy7lt3s7KbDE7rJTgc4kz00v5bbTepS3k0wZfkMq3RJkiEb5WiD/KRz1Z6btg8BJoWksBhDEyEJtOBf2Dr1MnOumS7+pwdsu3W/gXwphew29X3Y/lJtYRhf0tF2jMbgDDMe99OKSNvieFF+Ndam0UnTkYuHK3RzVVZFtjlr5gOSWIWYUEuDe4BXVFPBlGrb2Topn1p2trX5jXgnZXQgviFJqClTDElnF8tbyVTKNEWltUqAs2dGLn+r0CbvKrclFWn2dCMOz2OP5xnZ3YBwkWAsasmkM0k6tbqrz+HNDvkIDkq173IL5cRaL3OGr0hmi4+D6BoabnO9tkF9HG9vzEATtMU62bZh3bVnCbcBIqp4m72XBenvn+WzrShuFnflq; 4:OsFgU5to//ATZO1m47EAlQvUqA/tLun91dk1dj1Jg5uhkhVaYNV9CHxd5BDdtVdHD0qg1J5I+nAPTNmVJePxJqpbtGkfEQwAa+5OYpqyF1VnVpCJYQLePXBIspnHKQyXEsafeGaJ7ewYClOexNL/bl55RJwtw1QS8ka7hWsaihORtb+gciWsuwLQ8Z5Sf55MO7n+Wc0mcACViu8G11D7BzHPcn8fqs70aO2VFlrHWLy1UhvTmIVEQJO28C0e2+p/Z2XyoMmefc7gjCDpCAabgfkp8j50k/v2mxzs8vAtiQjHukX6EnMXOELGOKTJdex6tpb2cd0FbpH1Ruq22hGgFY5HDyykz+a/4P2rt+vJQeUGv8eNoFDfOUCpQp+kVbwi X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030)(17755550239193); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(93006095)(93001095)(100000703101)(100105400095)(3002001)(10201501046)(6041248)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123564025)(20161123562025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:DBXPR07MB318; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:DBXPR07MB318; X-Forefront-PRVS: 0462918D61 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(376002)(346002)(199003)(54534003)(189002)(69596002)(3846002)(48376002)(86362001)(50466002)(2361001)(2351001)(105586002)(106356001)(33646002)(25786009)(8676002)(316002)(478600001)(16586007)(50226002)(7736002)(81156014)(81166006)(97736004)(5003940100001)(305945005)(189998001)(8936002)(21086003)(6512007)(6306002)(36756003)(6116002)(6486002)(6506006)(4326008)(2906002)(5660300001)(68736007)(16526018)(6666003)(6916009)(47776003)(107886003)(53936002)(66066001)(101416001)(50986999)(26583001)(2004002); DIR:OUT; SFP:1101; SCL:1; SRVR:DBXPR07MB318; H:elxacz23q12.lan; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DBXPR07MB318; 23:DpyRDmY+fbXTp2LdoHi9g4eDvFLZFFQzLKHKJyv3YD?= =?us-ascii?Q?ADaAVzkLbpM5kKqtZLEGfMs8Kd5FmYjZsBgRz8hyRz8btGmENl61xVI7DEz/?= =?us-ascii?Q?JYD+xbf47XrDcpVXZw4ub0i75yHBsFiP0G7aQ4T+ZIPODfy7dUO5siVPtgMk?= =?us-ascii?Q?JnqwMx0NEZKmcmGHK/J2VjueQ1PaoHiW5Uveo0L75FqlQ6SORqUgQdiQ40eT?= =?us-ascii?Q?xXX4P5CM6YThRLMyG0ZvbpUb3XD64WEBOXOS8eDmr/B8gSnorVcJg5C154Hh?= =?us-ascii?Q?2xKLnfWshe106gX8taeg2rdsF4uZu7pOnteroukdxdv4aeXSmvHi03nZGe77?= =?us-ascii?Q?YvfwBWQcHxjpNG4TU83yWBitXRbsEXuMtJpmMwcfvXBfZwrnsLrxvuQhFbTJ?= =?us-ascii?Q?DvAdr+CT6FyKAzCN1VoqvdE26ih9grf2rJXpHKfNUFIQyqhAhl3I+k+1R8Yq?= =?us-ascii?Q?bPBBTGaSCy4R1boTYc2m46N2Jak1HVpmyIV9mQSFifAVDIJbybupoMnZbvbb?= =?us-ascii?Q?gWqsuCvEDkXv87Hx3H4tTRw+jA6C3m9yLvUlBGxwcT0SaP1/jlA/WkL6Vl/h?= =?us-ascii?Q?LdJwntFmbt2Lk5kAvsmlU+5WUU6YFgEKDgzCGHG+XA5/yaY8DucyD/rYEdTo?= =?us-ascii?Q?+45i6Dw5wMO1fz8hSOL4Yyji6T0EtHOGiFDM0LIcUT8q0v5Me6XSvWVwzUql?= =?us-ascii?Q?fsOBP5WOCxpDqnOyqu+g+ctTFVTDw7EYBWwA58l1X5/oHCyMoLLnU6Hu3MFD?= =?us-ascii?Q?wXaVbKCpfO2XpAVPtRdXCkJXBTZQEVCYWVN7bsYaUEJ3srEYclnFnA5t8fCl?= =?us-ascii?Q?tK8YlyqiSCd4i52wZLxEBTG10J3mXYyovv1bMBStQg1ENo4BlH/7o/6G1/ok?= =?us-ascii?Q?vThdqx5HFfqFFxZixA9aZAKuXUXD9ob6PiKB/1r81X7+Y3HIDXfGz95yQuFn?= =?us-ascii?Q?IWKiPNp4XJRgTEFsZWn+lm1UvD6w1XfV5hFlUe1rPc/TUMWBrmTQKnEjyqO8?= =?us-ascii?Q?12trtZce/IvXE5WuZGNqsLtRmlEpCurgNrqDLz5IaEVxq5ftb4yG+1qrNldy?= =?us-ascii?Q?Zx852vxxqu3TgAXWqYRzOWwALppyX6eVWcitu1vh8YuudGvYkFU5sRx8Utus?= =?us-ascii?Q?qdfMQ8sOjrGj9MQZWSxSF/Dr0AkI1l8bdLH1mI4OR+hyAuRlgpU51FD6c5Sa?= =?us-ascii?Q?ouUdXoT1x0MQWUZx6uQMIF+pgh8ohOPwgm?= X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB318; 6:BBRGiKdtma0sITkaXp1yHgxnQi69hEcaFK5Z4FtMESnh5N0H9sJ5KiG9niGj2eGVG/x7qw+WRIYEjGqb+HdPkeg7pDpe3JmzaEKkM71iH4YS2HN3GAuPzhzWMvVObyxcMh+trIi0b1zzIBPtbfClcXa2LIrtGso8kfEZhmO1d2HkfJmJ4EVlDn4WYWjS7hXb7yUee01GZd/XcJFvA+tGwdMDwxrG/ADbJNQre9K7hzgAAlBbBInJl7r1/u6vY/2b2qaionHUiSE37hpXSDa/8GQqGELTTrz2tOgVfJPnxmi44myu5UaBstYrOoVqNbQz022i8DLo0G2wJo5NHdLPdA==; 5:8ivYdjm93zUIyF79+T/bsUymKFVpECNItBKGPZUxuIRBmfswTSjzyve1Dc+cKJ60bxm3SC4td71UXdAN8sktUiqG821sndeykdwfTdHcy3kfey7LCK1njgNKXObeJtVFzUEopR6e4tTSOD+oJKslVw==; 24:+PsmmfgNhDtBCGxzdV68eeGziNrDaKLmJV+37T1HtNZprZ1+bUjsDwQAvkTDABuEKkc/y++OggC5TYHArBBFfsCZV/wC08MzjzDzVEF97GM=; 7:bqJbozOjluYZ5E+gBmJo7u3jaVVkkrWLYC2cicl837E6NnpQ1ue1xkxhiGR3vXC6kZJgKXsyDjLKjn9k4tK7DsZ9Siu7VIqsqMv2rZMYeJUZxJOWwmmmCvHJp9/dSqogg+S0l7gZdEa3dNBU0SRzPGfgYu4a0NFjBhkQ6boofu+ilbcgVlwQj2utxlaD8vs9r5OwjGnQqodCbKN8POi2O4azBHcZGVG+ldLxMTWDxe8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2017 02:28:48.9585 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 01c475d8-5df1-41f8-ff1d-08d5143da27e X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBXPR07MB318 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes This patch replaces the last usages of VEC(mem_range_s) with std::vector. This allows getting rid of a few cleanups and of the DEF_VEC_O(mem_range_s). I added a test for normalize_mem_ranges to make sure I didn't break anything there. Regtested on the buildbot. gdb/ChangeLog: * memrange.h (struct mem_range): Define operator< and operator==. (mem_range_s): Remove. (DEF_VEC_O (mem_range_s)): Remove. (normalize_mem_ranges): Change parameter type to std::vector. * memrange.c (compare_mem_ranges): Remove. (normalize_mem_ranges): Change parameter type to std::vector, adjust to vector change. * exec.c (section_table_available_memory): Return vector, remove parameter. (section_table_read_available_memory): Adjust to std::vector change. * remote.c (remote_read_bytes): Adjust to std::vector change. * tracepoint.h (traceframe_available_memory): Change parameter type to std::vector. * tracepoint.c (traceframe_available_memory): Change parameter type to std::vector, adjust. * gdb/mi/mi-main.c (mi_cmd_trace_frame_collected): Adjust to std::vector change. * gdb/Makefile.in (SUBDIR_UNITTESTS_SRCS): Add unittests/memrange-selftests.c. (SUBDIR_UNITTESTS_OBS): Add memrange-selftests.o. * gdb/unittests/memrange-selftests.c: New file. --- gdb/Makefile.in | 2 + gdb/exec.c | 55 ++++++------------ gdb/memrange.c | 46 ++++----------- gdb/memrange.h | 17 ++++-- gdb/mi/mi-main.c | 20 +++---- gdb/remote.c | 19 ++---- gdb/tracepoint.c | 13 ++--- gdb/tracepoint.h | 2 +- gdb/unittests/memrange-selftests.c | 115 +++++++++++++++++++++++++++++++++++++ 9 files changed, 179 insertions(+), 110 deletions(-) create mode 100644 gdb/unittests/memrange-selftests.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0f1ba54..e21ea55 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -530,6 +530,7 @@ SUBDIR_UNITTESTS_SRCS = \ unittests/common-utils-selftests.c \ unittests/environ-selftests.c \ unittests/function-view-selftests.c \ + unittests/memrange-selftests.c \ unittests/offset-type-selftests.c \ unittests/optional-selftests.c \ unittests/ptid-selftests.c \ @@ -541,6 +542,7 @@ SUBDIR_UNITTESTS_OBS = \ common-utils-selftests.o \ environ-selftests.o \ function-view-selftests.o \ + memrange-selftests.o \ offset-type-selftests.o \ optional-selftests.o \ ptid-selftests.o \ diff --git a/gdb/exec.c b/gdb/exec.c index 6eda9b2..2fa543b 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -698,20 +698,18 @@ exec_read_partial_read_only (gdb_byte *readbuf, ULONGEST offset, return TARGET_XFER_E_IO; } -/* Appends all read-only memory ranges found in the target section +/* Return all read-only memory ranges found in the target section table defined by SECTIONS and SECTIONS_END, starting at (and - intersected with) MEMADDR for LEN bytes. Returns the augmented - VEC. */ + intersected with) MEMADDR for LEN bytes. */ -static VEC(mem_range_s) * -section_table_available_memory (VEC(mem_range_s) *memory, - CORE_ADDR memaddr, ULONGEST len, +static std::vector +section_table_available_memory (CORE_ADDR memaddr, ULONGEST len, struct target_section *sections, struct target_section *sections_end) { - struct target_section *p; + std::vector memory; - for (p = sections; p < sections_end; p++) + for (target_section *p = sections; p < sections_end; p++) { if ((bfd_get_section_flags (p->the_bfd_section->owner, p->the_bfd_section) @@ -722,7 +720,6 @@ section_table_available_memory (VEC(mem_range_s) *memory, if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len)) { ULONGEST lo1, hi1, lo2, hi2; - struct mem_range *r; lo1 = memaddr; hi1 = memaddr + len; @@ -730,10 +727,10 @@ section_table_available_memory (VEC(mem_range_s) *memory, lo2 = p->addr; hi2 = p->endaddr; - r = VEC_safe_push (mem_range_s, memory, NULL); + CORE_ADDR start = std::max (lo1, lo2); + int length = std::min (hi1, hi2) - start; - r->start = std::max (lo1, lo2); - r->length = std::min (hi1, hi2) - r->start; + memory.emplace_back (start, length); } } @@ -744,51 +741,37 @@ enum target_xfer_status section_table_read_available_memory (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { - VEC(mem_range_s) *available_memory = NULL; - struct target_section_table *table; - struct cleanup *old_chain; - mem_range_s *r; - int i; + target_section_table *table = target_get_section_table (&exec_ops); + std::vector available_memory + = section_table_available_memory (offset, len, + table->sections, table->sections_end); - table = target_get_section_table (&exec_ops); - available_memory = section_table_available_memory (available_memory, - offset, len, - table->sections, - table->sections_end); + normalize_mem_ranges (&available_memory); - old_chain = make_cleanup (VEC_cleanup(mem_range_s), - &available_memory); - - normalize_mem_ranges (available_memory); - - for (i = 0; - VEC_iterate (mem_range_s, available_memory, i, r); - i++) + for (const mem_range &r : available_memory) { - if (mem_ranges_overlap (r->start, r->length, offset, len)) + if (mem_ranges_overlap (r.start, r.length, offset, len)) { CORE_ADDR end; enum target_xfer_status status; /* Get the intersection window. */ - end = std::min (offset + len, r->start + r->length); + end = std::min (offset + len, r.start + r.length); gdb_assert (end - offset <= len); - if (offset >= r->start) + if (offset >= r.start) status = exec_read_partial_read_only (readbuf, offset, end - offset, xfered_len); else { - *xfered_len = r->start - offset; + *xfered_len = r.start - offset; status = TARGET_XFER_UNAVAILABLE; } - do_cleanups (old_chain); return status; } } - do_cleanups (old_chain); *xfered_len = len; return TARGET_XFER_UNAVAILABLE; diff --git a/gdb/memrange.c b/gdb/memrange.c index 74da19d..34feac5 100644 --- a/gdb/memrange.c +++ b/gdb/memrange.c @@ -41,58 +41,36 @@ address_in_mem_range (CORE_ADDR address, const struct mem_range *r) && (address - r->start) < r->length); } -/* qsort comparison function, that compares mem_ranges. Ranges are - sorted in ascending START order. */ - -static int -compare_mem_ranges (const void *ap, const void *bp) -{ - const struct mem_range *r1 = (const struct mem_range *) ap; - const struct mem_range *r2 = (const struct mem_range *) bp; - - if (r1->start > r2->start) - return 1; - else if (r1->start < r2->start) - return -1; - else - return 0; -} - void -normalize_mem_ranges (VEC(mem_range_s) *ranges) +normalize_mem_ranges (std::vector *memory) { /* This function must not use any VEC operation on RANGES that reallocates the memory block as that invalidates the RANGES pointer, which callers expect to remain valid. */ - if (!VEC_empty (mem_range_s, ranges)) + if (!memory->empty ()) { - struct mem_range *ra, *rb; - int a, b; + std::vector &m = *memory; - qsort (VEC_address (mem_range_s, ranges), - VEC_length (mem_range_s, ranges), - sizeof (mem_range_s), - compare_mem_ranges); + std::sort (m.begin (), m.end ()); - a = 0; - ra = VEC_index (mem_range_s, ranges, a); - for (b = 1; VEC_iterate (mem_range_s, ranges, b, rb); b++) + int a = 0; + for (int b = 1; b < m.size (); b++) { /* If mem_range B overlaps or is adjacent to mem_range A, merge them. */ - if (rb->start <= ra->start + ra->length) + if (m[b].start <= m[a].start + m[a].length) { - ra->length = std::max ((CORE_ADDR) ra->length, - (rb->start - ra->start) + rb->length); + m[a].length = std::max ((CORE_ADDR) m[a].length, + (m[b].start - m[a].start) + m[b].length); continue; /* next b, same a */ } a++; /* next a */ - ra = VEC_index (mem_range_s, ranges, a); if (a != b) - *ra = *rb; + m[a] = m[b]; } - VEC_truncate (mem_range_s, ranges, a + 1); + + m.resize (a + 1); } } diff --git a/gdb/memrange.h b/gdb/memrange.h index 029ec71..fb10cda 100644 --- a/gdb/memrange.h +++ b/gdb/memrange.h @@ -32,6 +32,17 @@ struct mem_range : start (start_), length (length_) {} + bool operator< (const mem_range &other) const + { + return this->start < other.start; + } + + bool operator== (const mem_range &other) const + { + return (this->start == other.start + && this->length == other.length); + } + /* Lowest address in the range. */ CORE_ADDR start; @@ -39,10 +50,6 @@ struct mem_range int length; }; -typedef struct mem_range mem_range_s; - -DEF_VEC_O(mem_range_s); - /* Returns true if the ranges defined by [start1, start1+len1) and [start2, start2+len2) overlap. */ @@ -57,6 +64,6 @@ extern int address_in_mem_range (CORE_ADDR addr, /* Sort ranges by start address, then coalesce contiguous or overlapping ranges. */ -extern void normalize_mem_ranges (VEC(mem_range_s) *memory); +extern void normalize_mem_ranges (std::vector *memory); #endif diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index a94e329..8dc955d 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -2752,40 +2752,34 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) /* Memory. */ { - struct cleanup *cleanups; - VEC(mem_range_s) *available_memory = NULL; - struct mem_range *r; - int i; + std::vector available_memory; traceframe_available_memory (&available_memory, 0, ULONGEST_MAX); - cleanups = make_cleanup (VEC_cleanup(mem_range_s), &available_memory); ui_out_emit_list list_emitter (uiout, "memory"); - for (i = 0; VEC_iterate (mem_range_s, available_memory, i, r); i++) + for (const mem_range &r : available_memory) { struct gdbarch *gdbarch = target_gdbarch (); ui_out_emit_tuple tuple_emitter (uiout, NULL); - uiout->field_core_addr ("address", gdbarch, r->start); - uiout->field_int ("length", r->length); + uiout->field_core_addr ("address", gdbarch, r.start); + uiout->field_int ("length", r.length); - gdb::byte_vector data (r->length); + gdb::byte_vector data (r.length); if (memory_contents) { - if (target_read_memory (r->start, data.data (), r->length) == 0) + if (target_read_memory (r.start, data.data (), r.length) == 0) { - std::string data_str = bin2hex (data.data (), r->length); + std::string data_str = bin2hex (data.data (), r.length); uiout->field_string ("contents", data_str.c_str ()); } else uiout->field_skip ("contents"); } } - - do_cleanups (cleanups); } } diff --git a/gdb/remote.c b/gdb/remote.c index e2bdd11..b38ace9 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -8465,7 +8465,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, if (get_traceframe_number () != -1) { - VEC(mem_range_s) *available; + std::vector available; /* If we fail to get the set of available memory, then the target does not support querying traceframe info, and so we @@ -8473,27 +8473,20 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, target implements the old QTro packet then). */ if (traceframe_available_memory (&available, memaddr, len)) { - struct cleanup *old_chain; - - old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); - - if (VEC_empty (mem_range_s, available) - || VEC_index (mem_range_s, available, 0)->start != memaddr) + if (available.empty () || available[0].start != memaddr) { enum target_xfer_status res; /* Don't read into the traceframe's available memory. */ - if (!VEC_empty (mem_range_s, available)) + if (!available.empty ()) { LONGEST oldlen = len; - len = VEC_index (mem_range_s, available, 0)->start - memaddr; + len = available[0].start - memaddr; gdb_assert (len <= oldlen); } - do_cleanups (old_chain); - /* This goes through the topmost target again. */ res = remote_xfer_live_readonly_partial (ops, myaddr, memaddr, len, unit_size, xfered_len); @@ -8512,9 +8505,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, case the target implements the deprecated QTro packet to cater for older GDBs (the target's knowledge of read-only sections may be outdated by now). */ - len = VEC_index (mem_range_s, available, 0)->length; - - do_cleanups (old_chain); + len = available[0].length; } } diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 9c07315..fdc3b38 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -4077,20 +4077,19 @@ get_traceframe_info (void) undefined. */ int -traceframe_available_memory (VEC(mem_range_s) **result, +traceframe_available_memory (std::vector *result, CORE_ADDR memaddr, ULONGEST len) { struct traceframe_info *info = get_traceframe_info (); if (info != NULL) { - *result = NULL; + result->clear (); for (mem_range &r : info->memory) if (mem_ranges_overlap (r.start, r.length, memaddr, len)) { ULONGEST lo1, hi1, lo2, hi2; - struct mem_range *nr; lo1 = memaddr; hi1 = memaddr + len; @@ -4098,13 +4097,13 @@ traceframe_available_memory (VEC(mem_range_s) **result, lo2 = r.start; hi2 = r.start + r.length; - nr = VEC_safe_push (mem_range_s, *result, NULL); + CORE_ADDR start = std::max (lo1, lo2); + int length = std::min (hi1, hi2) - start; - nr->start = std::max (lo1, lo2); - nr->length = std::min (hi1, hi2) - nr->start; + result->emplace_back (start, length); } - normalize_mem_ranges (*result); + normalize_mem_ranges (result); return 1; } diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index 88c18c3..8364d38 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -400,7 +400,7 @@ extern void trace_save_ctf (const char *dirname, extern traceframe_info_up parse_traceframe_info (const char *tframe_info); -extern int traceframe_available_memory (VEC(mem_range_s) **result, +extern int traceframe_available_memory (std::vector *result, CORE_ADDR memaddr, ULONGEST len); extern struct traceframe_info *get_traceframe_info (void); diff --git a/gdb/unittests/memrange-selftests.c b/gdb/unittests/memrange-selftests.c new file mode 100644 index 0000000..6487578 --- /dev/null +++ b/gdb/unittests/memrange-selftests.c @@ -0,0 +1,115 @@ +/* Self tests for mem ranges for GDB, the GNU debugger. + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "selftest.h" +#include "memrange.h" + +namespace selftests { +namespace memrange_tests { + +static void +normalize_mem_ranges_tests (void) +{ + /* Empty vector. */ + { + std::vector ranges; + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 0); + } + + /* With one range. */ + { + std::vector ranges; + + ranges.emplace_back (10, 20); + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 1); + SELF_CHECK (ranges[0] == mem_range (10, 20)); + } + + /* Completely disjoint ranges. */ + { + std::vector ranges; + + ranges.emplace_back (20, 1); + ranges.emplace_back (10, 1); + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 2); + SELF_CHECK (ranges[0] == mem_range (10, 1)); + SELF_CHECK (ranges[1] == mem_range (20, 1)); + } + + /* Overlapping and contiguous ranges. */ + { + std::vector ranges; + + ranges.emplace_back (5, 10); + ranges.emplace_back (10, 10); + ranges.emplace_back (15, 10); + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 1); + SELF_CHECK (ranges[0] == mem_range (5, 20)); + } + + /* Duplicate ranges. */ + { + std::vector ranges; + + ranges.emplace_back (10, 10); + ranges.emplace_back (10, 10); + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 1); + SELF_CHECK (ranges[0] == mem_range (10, 10)); + } + + /* Range completely inside another. */ + { + std::vector ranges; + + ranges.emplace_back (14, 2); + ranges.emplace_back (10, 10); + + normalize_mem_ranges (&ranges); + + SELF_CHECK (ranges.size () == 1); + SELF_CHECK (ranges[0] == mem_range (10, 10)); + } +} + +} /* namespace memrange_tests */ +} /* namespace selftests */ + +void +_initialize_memrange_selftests () +{ + selftests::register_test + ("normalize_mem_ranges", + selftests::memrange_tests::normalize_mem_ranges_tests); +}