From patchwork Tue Aug 4 18:39:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 40204 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 29E96384640F; Wed, 5 Aug 2020 05:20:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 29E96384640F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1596604827; bh=3QTUx2YLQ9POipX4tJMm9wABZENqCVmIZsC60YUVQv0=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=V+/ETUQLuw0dL5Oa50Am5tMM2D3MB0OewmXS6AzoD+2L4Cs1cELEhtiW1Sa2StxT6 AL/8bUc+WFPtauoHxYEWYQT77zN10YuHsVr5EmfHBRIDqB90Sp6Q1uZIx/Q3yBjJ3O hgJ+9xlwCnG4PMPn26JGpA8hZpEDbG+nb6sZcFMU= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wm1-x34a.google.com (mail-wm1-x34a.google.com [IPv6:2a00:1450:4864:20::34a]) by sourceware.org (Postfix) with ESMTPS id 62CE83851C2A for ; Tue, 4 Aug 2020 18:39:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 62CE83851C2A Received: by mail-wm1-x34a.google.com with SMTP id a207so1360581wme.9 for ; Tue, 04 Aug 2020 11:39:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=3QTUx2YLQ9POipX4tJMm9wABZENqCVmIZsC60YUVQv0=; b=V9vNvSyE/sna/UMTlsLgwH5TQQnfEroDSmeA0MK7lMbNsF/nqB1QJjWU8zkjAAXDcM sSXd6vuc3wZXMOfYmGEQEQhKussPpMfUWjr20y78vqj7pl4dZQInrMXPMOqUsWHp7lFY gv7dSO+xJHmWZtD8V0/ErbBFEbdc8b8Ai7qTwoOF8pZbMvfy1NcOJrvbRSO9pGxWNZ9m NwZf8NriJ/7/ZDTpr6ePl0va6vwaETct0Xoy86ZaNa3G5fKP4C1b+GeoummF5Cwz8jfQ Zh1WM/hsJphPNZGMRRQxYHvYhI5Kh9vyqgsLNghJQDwtI/NRY57hSlYUqzeuSfHdbXOr Xjtg== X-Gm-Message-State: AOAM53101nYxospC3CZD8T9Fzejy0BAtVcTpaR1sqCSFY/ZzuJrI0/gC AV3QpVH+4xGFCsnkhEMi5kupijvvTbXs0Q/kph5WsoodP78xioFGNqh3xt8ilVoAxdt0U4c2XKW lb+3tOGe4LgEbbIrLUQ0EqBj4bPa500LSGO/bGeFWSUxJxIS8v4b70Me4QYwb6bPjhbS1aC0= X-Google-Smtp-Source: ABdhPJxE9qkGeKvgrUvXSV35YG1ptnISN2on0dmarxQySoXeMS3IY+W5KR40YEXOyg8wcgvzCjRVsvTVA5RWzw== X-Received: by 2002:adf:a34f:: with SMTP id d15mr19376055wrb.281.1596566382651; Tue, 04 Aug 2020 11:39:42 -0700 (PDT) Date: Tue, 4 Aug 2020 19:39:35 +0100 In-Reply-To: <20200804183935.3076857-1-gprocida@google.com> Message-Id: <20200804183935.3076857-2-gprocida@google.com> Mime-Version: 1.0 References: <20200804183935.3076857-1-gprocida@google.com> X-Mailer: git-send-email 2.28.0.163.g6104cc2f0b6-goog Subject: [PATCH 1/1] abg-writer.cc: Track types by plain address To: libabigail@sourceware.org X-Mailman-Approved-At: Wed, 05 Aug 2020 05:20:14 +0000 X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Giuliano Procida via Libabigail From: Giuliano Procida Reply-To: Giuliano Procida Cc: maennich@google.com, kernel-team@android.com Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" The XML writer tracks the state of referenced and emitted types so it can emit the right types with no repetitions or omissions. The sets and maps are keyed using type_hasher and deep_ptr_eq_functor, effectively resulting in structural equality checks in some cases. The helper function type_is_emitted looks up types in a set but the corresponding record_type_as_emitted stores the canonical pointer where possible. Any discrepancy between structural and canonical equality may result in types being treated as emitted when there are not or vice versa, resulting in duplicate or omitted type ids. Together, the result is that some types are unexpectedly conflated. Also, depending on the toolchain and libraries, some types are not emitted even when referred to elsewhere in the XML. * src/abg-writer.cc (writer_context): Change type_ptr_map, type_ptr_set_type and fn_type_ptr_set_type to use plain pointer equality and hashing. (type_is_emitted): Look up canonical type if it exists, to match record_type_as_emitted, get_id_for_type etc. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Refresh. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Refresh. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Refresh. * tests/data/test-read-write/test25.xml: Refresh. Signed-off-by: Giuliano Procida --- src/abg-writer.cc | 20 +- .../test-read-dwarf/PR22122-libftdc.so.abi | 6026 ++-- .../test-read-dwarf/test12-pr18844.so.abi | 27857 ++++++++-------- .../test9-pr18818-clang.so.abi | 4103 +-- tests/data/test-read-write/test25.xml | 8 +- 5 files changed, 19011 insertions(+), 19003 deletions(-) diff --git a/src/abg-writer.cc b/src/abg-writer.cc index 4c751c26..8b82b46b 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -140,21 +140,14 @@ struct type_hasher }; // end struct type_hasher /// A convenience typedef for a map that associates a pointer to type -/// to a string. The pointer to type is hashed as fast as possible. -typedef unordered_map type_ptr_map; +/// to a string. +typedef unordered_map type_ptr_map; // A convenience typedef for a set of type_base*. -typedef unordered_set -type_ptr_set_type; +typedef unordered_set type_ptr_set_type; /// A convenience typedef for a set of function type*. -typedef unordered_set -fn_type_ptr_set_type; +typedef unordered_set fn_type_ptr_set_type; typedef unordered_map, string, @@ -732,7 +725,10 @@ public: bool type_is_emitted(const type_base *t) { - return m_emitted_type_set.find(t) != m_emitted_type_set.end(); + type_base *c = t->get_naked_canonical_type(); + if (c == 0) + c = const_cast(t); + return m_emitted_type_set.find(c) != m_emitted_type_set.end(); } /// Test if a given type has been written out to the XML output. diff --git a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi index 4901fc5c..cd69b032 100644 --- a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi +++ b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi @@ -273,196 +273,196 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + - + - + - - - + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - + + - - + + - + - + - + - + - - + + - - - + + + - + - + - + - - + + - + - + - + - - + + @@ -470,676 +470,676 @@ - + - + - - + + - + - + - + - + - + - + - + - - - + + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - - + + - - + + - + - - - + + + - - - + + + - - + + - - + + - + - - + + - - + + - - + + - - - - + + + + - - - - + + + + - - - + + + - - + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + - - + + - - - - + + + + - - - - + + + + - - - - - - + + + + + + - - - - + + + + - + - - - + + + - + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - + - + - - - + + + - - - + + + - + - + - + - + - - - + + + - - - + + + - - + + - + - - + + - - - - + + + + - - - + + + - + - - + + - + - - + + - + - + - + - + - - - - + + + + - + - - - - + + + + - - + + - + - - + + - + - + - - + + - + - + - + - + - - + + - - + + - + - + - + - + - - + + - - - + + + - + - - + + - + - - - - + + + + - - - - + + + + - + - + - + - + - - + + - - + + - + @@ -1147,239 +1147,239 @@ - + - + - + - + - - + + - + - + - + - - + + - - - + + + - - - + + + - - + + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - + + + - - - + + + - + - + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - - - + + + - - + + - + - + - - + + @@ -1390,238 +1390,238 @@ - + - + - + - + - + - - - - + + + + - - - + + + - + - + - + - + - + - + - - + + - - + + - + - - + + - + - + - + - - - + + + - - + + - - + + - - - + + + - - + + - + - + - - + + - + - - + + - - + + - + - - + + - - - + + + - - + + - + - + - - - + + + - + - + - - - + + + - + - + - - + + - + - - + + - + - - + + - - + + - + - + - + - - + + - + - + - - + + - + - + @@ -1629,161 +1629,161 @@ - + - + - - + + - + - - - + + + - - - + + + - + - - + + - - - + + + - - + + - - + + - + - + - - - + + + - - + + - - + + - - - + + + - - + + - + - - + + - + - - + + - + - - + + - - + + - + - - + + - + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + @@ -1792,89 +1792,89 @@ - - + + - - + + - + - - + + - + - + - + - + - + - + - + - - - + + + - + - + - - - + + + - + - + - - + + - - + + - - + + - - + + - + @@ -1940,54 +1940,54 @@ - + - + - + - + - + - - + + - - + + - + - + - + - - + + @@ -1996,34 +1996,34 @@ - + - + - + - - + + - - + + - + - + @@ -2034,43 +2034,43 @@ - + - + - - + + - - + + - - + + - + - - + + - + @@ -2088,147 +2088,147 @@ - + - - + + - - + + - - + + - - + + - + - + - + - + - + - + - - + + - + - - + + - - - + + + - - + + - + - - + + - + - + - - - - + + + + - - + + - + - - + + - + - + - + - + - + - + - + @@ -2236,109 +2236,109 @@ - + - + - - + + - + - + - - + + - - + + - - + + - - + + - + - - + + - + - - - + + + - - + + - - - + + + - + - + - - - + + + - - + + - + - - + + - - - + + + @@ -2389,7 +2389,7 @@ - + @@ -2407,7 +2407,7 @@ - + @@ -2733,15 +2733,15 @@ - + - + - + @@ -2804,19 +2804,19 @@ - + - + - + @@ -2915,7 +2915,7 @@ - + @@ -2952,7 +2952,7 @@ - + @@ -2964,767 +2964,776 @@ - - + + - - + + - - + + - - - + + + - - + + - + - - + + - + - - + + - + - - + + - + - + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - + - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + - - - + + + - + - + - + - + - + - + - + - - + + - - + + - + - - + + - - + + - - + + - + - + - + - - + + - - + + - - + + - - + + - + - + - + - + - - + + - + - - - + + + - - + + - - + + - + - - - + + + - + - - + + - + - - - + + + - + - - - + + + - - - + + + - - + + - + - + - + - + - - + + - - + + - + - - + + - - + + - + - - - + + + - - - + + + - + - - + + - + - - - - + + + + - - - + + + - - + + - + - - - - + + + + - + - - + + - + - - + + - - + + - - + + - - - + + + - + - + - - + + - - + + - - + + - + - + - - - + + + - - + + - - + + - - + + - + - - + + - - + + - + - + - - + + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - - + + - + - - + + - + - + - - - + + + - - + + - + - - - + + + - - + + - + - + - - + + - - + + - - + + - - + + - + - - - + + + - + - - - + + + - + - - - + + + - - - + + + - + - - - + + + @@ -3732,102 +3741,102 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - + - - - - + + + + - - - - + + + + - + - - + + - + - - - + + + - + - + - + @@ -3835,650 +3844,651 @@ - - + + - - + + - - + + - + - + - + - - - + + + - - + + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + - + - - + + - + - + - + - + - - + + - - - - - - - + + + + + + + - + - - + + - - + + - + - - + + - - + + - - - + + + - - - + + + - - - - + + + + - - + + - + - + - - + + - - - + + + - + - + - + - - + + - + - + - + - - + + - - - + + + - - + + - - + + - + - - - + + + - + - - - - + + + + - + - - + + - + - - + + - + - + - + - - + + - - - + + + - - - + + + - - - + + + - - + + - + - + - + - - - - + + + + - + - - - - + + + + - + - + - - + + - + - - + + - - - + + + - - + + - + - + - - + + - + - + - + - + - + - - + + - - + + - - - + + + - - - - + + + + - + - - - + + + - - - - + + + + - - - + + + - - + + - + - - + + - - + + - + - + - - + + - + - - + + - + - + - + - + - + - + - - - + + + - + - - - + + + - - - + + + - - + + - - - + + + - + - - + + - - - + + + - - - - + + + + - + - + - - + + @@ -4486,947 +4496,947 @@ - - + + - - + + - - + + - + - - - + + + - - + + - - - + + + - - + + - + - - + + - + - - - - + + + + - + - - - - + + + + - + - - + + - - + + - + - + - + - + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - + + + - - + + - - + + - + - - + + - - + + - + - + - + - + - + - + - - - - - + + + + + - - + + - - + + - + - - + + - + - + - + - + - + - + - + - - - + + + - - + + - + - + - - + + - - + + - - - + + + - - + + - + - + - - + + - - - - + + + + - + - + - + - + - + - + - + - + - + - + - - + + - + - - - + + + - + - - - - - + + + + + - + - - + + - - + + - + - + - + - - + + - - - + + + - - + + - - - + + + - + - - - - + + + + - - + + - + - - + + - + - - + + - + - + - + - + - + - + - + - + - + - - - - + + + + - - - - + + + + - + - - + + - + - + - - + + - - + + - + - - - + + + - - + + - + - - + + - + - - + + - + - - - - + + + + - + - + - - - + + + - - + + - - - + + + - + - + - - + + - - + + - - + + - - + + - + - - + + - + - - - + + + - - + + - + - + - + - + - - - + + + - + - + - + - + - - + + - - + + - - + + - - - + + + - - - + + + - - - + + + - + - + - - + + - + - - + + - - - + + + - + - + - - + + - - + + - + - + - + - + - - - - - - + + + + + + - + - + - + - - + + - - + + - - + + - + - + - - - + + + - - + + - - + + - - + + - + - + - + - - - - + + + + - - + + - + - - - + + + - - - + + + - - - + + + - - + + @@ -5434,26 +5444,26 @@ - + - - - + + + - - - + + + - - - + + + @@ -5461,163 +5471,163 @@ - - - - + + + + - + - + - - - - - - - - + + + + + + + + - + - - + + - - + + - - + + - - + + - - - - - + + + + + - - + + - + - - + + - - + + - - + + - - + + - - + + - + - - + + - - - - - + + + + + - - + + - - + + - - + + - + - + - + - + - + @@ -5625,571 +5635,571 @@ - + - - + + - - - + + + - - + + - + - + - + - - - + + + - - - + + + - - - - + + + + - + - - - + + + - - - - - + + + + + - - - + + + - - + + - - + + - - - - + + + + - - - - + + + + - + - - + + - + - - - + + + - - + + - - + + - - + + - - - + + + - - - + + + - - + + - + - + - - + + - - - + + + - - - + + + - + - - + + - - - + + + - + - + - + - + - + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - + - + - - + + - - - + + + - - + + - - - + + + - + - + - - - + + + - - - + + + - + - - - - - - + + + + + + - + - + - + - - - - - - + + + + + + - - - + + + - + - + - + - + - + - + - - + + - + - - + + - - - + + + - - - + + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - + + - + - - + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + - + - - + + - - + + - + - + - - + + - + - + - - + + - + - + - - + + @@ -6197,51 +6207,51 @@ - + - + - - + + - - + + - + - - + + - + - - - + + + - - + + - + @@ -6252,865 +6262,865 @@ - - - + + + - + - + - - + + - - + + - + - + - + - + - + - + - + - + - - + + - - - + + + - - + + - + - + - + - + - - + + - - + + - + - - - - - - + + + + + + - - + + - - - + + + - + - + - - - - + + + + - + - - + + - - + + - + - + - + - - + + - + - - - + + + - + - - + + - - - - - + + + + + - - - + + + - - + + - + - + - - + + - + - - + + - - - - + + + + - - + + - + - - + + - - + + - + - + - + - + - - - + + + - - + + - - - - + + + + - + - + - - + + - - + + - - + + - - + + - + - + - + - - - + + + - - + + - + - + - - - + + + - + - - - - + + + + - - + + - - + + - - - - + + + + - - + + - + - - - + + + - + - - - + + + - + - + - + - - - - + + + + - + - - + + - - - - + + + + - - + + - - + + - - - + + + - + - - - - - - + + + + + + - + - - - - + + + + - + - - - - + + + + - - - - + + + + - - - - + + + + - - + + - - - - + + + + - + - + - - - + + + - + - - - + + + - + - - - + + + - + - + - - + + - - - + + + - - - + + + - - + + - + - + - - - + + + - + - + - + - + - - - + + + - + - - - + + + - + - + - - + + - + - - + + - + - + - - + + - + - + - + - + - + - + - - - - + + + + - - + + - + - - - - - + + + + + - - + + - - + + - - - - + + + + - - - - - + + + + + - - + + - - - + + + - - - - - + + + + + - - - - - + + + + + - - + + - + - - + + - - + + - + - + - - - + + + - - + + - - + + - - + + - + - - - - - - + + + + + + - + - - + + - + - + - + - - + + - - - + + + - + - - - + + + @@ -7118,444 +7128,444 @@ - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - + - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + - + - - - + + + - + - + - + - - - + + + - + - + - + - + - + - + - + - - - + + + - - + + - - + + - - - - - + + + + + - - - + + + - - - - + + + + - - + + - - - - - + + + + + - + - - + + - - - - + + + + - + - - - - + + + + - - - - + + + + - - - + + + - - - + + + - + - - - - + + + + - + - - - - + + + + - + - - + + - - - + + + - + - + - + - - - - + + + + - + - - - - + + + + - + - + - + - - - + + + - - + + - + - + - - + + - + - + - + - + - - - - - - + + + + + + - + - - + + - - + + - - + + - - - + + + - + - + - + - + - - + + - - + + - - - - - - - - + + + + + + + + - + - + - + - + - - + + - - + + - + - - - + + + - - - - + + + + - + - - - + + + - - - + + + - - - + + + @@ -7563,235 +7573,235 @@ - - + + - + - + - + - - + + - - + + - - + + - + - + - - - - - + + + + + - + - + - + - - + + - - + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - + - + - + - + - - + + - + - - - + + + - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - + - - - + + + - + - - - - - - + + + + + + - + - - + + - + - - - + + + - + - + - - + + - - + + - + - - + + - + - - + + - + - + - + - - - + + + @@ -7799,819 +7809,819 @@ - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - + - - + + - + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - + + + + + + - + - + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - + - - - + + + - - - + + + - - - + + + - - - - - + + + + + - + - - - - - - + + + + + + - - + + - - - + + + - + - + - + - - - - - - - - - + + + + + + + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - + + - - - + + + - - - - - - - - + + + + + + + + - - + + - - + + - - - + + + - - + + - - + + - + - + - - + + - + - + - + - + - + - - - + + + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - + - - + + - + - - - + + + - - + + - + - - - + + + - - + + - + - - - + + + - + - + - - + + - + - - + + - - + + - + - - + + - + - + - - + + - + - - + + - - + + - - + + - - - + + + - + - + - + - + - - + + - + - - - + + + - + - - + + - + - - - + + + - + - + - + - + - - + + - + - + - - - + + + - - - - + + + + - - + + - + - - - + + + - + - - + + - - - + + + - - + + - + - - + + - + - - - + + + - - - + + + - - + + - + - + - + - - - - + + + + - + - - + + - + - + - + - - - + + + - - + + - + - + - + - + - + - + - + - + - - - + + + - - - + + + - - - + + + - - - + + + @@ -8619,26 +8629,26 @@ - + - - - + + + - - - + + + - - - + + + @@ -8647,28 +8657,28 @@ - - + + - + - - + + - - - + + + - + - - + + diff --git a/tests/data/test-read-dwarf/test12-pr18844.so.abi b/tests/data/test-read-dwarf/test12-pr18844.so.abi index 5b6d24b8..cee104fa 100644 --- a/tests/data/test-read-dwarf/test12-pr18844.so.abi +++ b/tests/data/test-read-dwarf/test12-pr18844.so.abi @@ -1988,3170 +1988,3170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +