From patchwork Tue Mar 9 22:57:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 42410 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 62C3F389244C; Tue, 9 Mar 2021 22:59:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 62C3F389244C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1615330774; bh=3M/HV3gAxTN8xCzdbL2eS9uWNCWGt8eiIKICtjz8RNI=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:Cc:From; b=UwWFtFx8/rYzDueC/+yh4uNqogycIVA2tTK0lkcPGGP5KHcVmLAIS2bYAvFMX3oBX FAHPc1AOHCN01JRVG0C+BJ4/9k0zo8J67rGhNnnhrDMz6XDhEOvGEpzzYK20KXSk9X ajDdKtJZAEvmUB0fSlUDQ06JE3TPoHBqiFnnO9sU= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by sourceware.org (Postfix) with ESMTPS id 33D2D3892448 for ; Tue, 9 Mar 2021 22:58:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 33D2D3892448 Received: by mail-qk1-x749.google.com with SMTP id 130so11352069qkm.0 for ; Tue, 09 Mar 2021 14:58:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=3M/HV3gAxTN8xCzdbL2eS9uWNCWGt8eiIKICtjz8RNI=; b=GsRk7OBkJ3vmwWnzyUGFlbUwx7deBsEYUasI0o13YXFLUjRv7i6kDlSssTfxVOT5E7 PEDOP07M4rI6FcxF9bHvcAl+AkgaU/WjWIM2/aWv3ptSOtHGLwUNsaC0RpcJ5HBaldyA wcAvP0/3SOCEQBeQSG5TdQqvMa9XQwOLHwRiI9KV/3wER+WgXcAvLHamvOiXY9E2lnw/ z9ZvtRxa0b78JSXFiKOxRiTld6Vbwe8wlvNmB8ci416H0g4TaruqUe1lkZULMau+C0Mk 1IegzxnRJvNPBNiNCCfTkijgLjLeg3+3btve5RwM+PlH3ag44Qc4YPBgtZ5fbBKOO6+w 2xbw== X-Gm-Message-State: AOAM532mWzSMeC81iIKybgV5GJrJ+iquq14hdDQbDZeuuqL8Q66W0DPR M0/zVNgPmf1Msg7POdKTN0kWWrtD/LMYRdRa+YwwYngDellQgWxXwReF3FJ2dlw6g0tA9ruym67 U4lyWou9VJkM/GPsyECaq74wPPtHgsqvrRy4Ne3hP2QhgwXaQApdCu8YsRlPBSY+DginsmFw= X-Google-Smtp-Source: ABdhPJw5gjGGaq7Ky18IOGV92ynQQrtR8JgxRB4nvg+SyfsnYPTC0OesJ8QSimWwuJxTFmmTp0f/xww2hvxL1A== X-Received: from tef.lon.corp.google.com ([2a00:79e0:d:110:2993:37af:9ac:ccfc]) (user=gprocida job=sendgmr) by 2002:a05:6214:1624:: with SMTP id e4mr402074qvw.58.1615330685144; Tue, 09 Mar 2021 14:58:05 -0800 (PST) Date: Tue, 9 Mar 2021 22:57:54 +0000 Message-Id: <20210309225754.2759649-1-gprocida@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH] DWARF reader: Interpret ARM32 ELF addresses correctly To: libabigail@sourceware.org X-Spam-Status: No, score=-20.8 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SCC_10_SHORT_WORD_LINES, SCC_20_SHORT_WORD_LINES, SCC_35_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org 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, mark@klomp.org Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" Bug 27552 - libabigail needs to interpret ARM32 symbol addresses specially The ARM32 ELF specification specifies that bit 0 of an ELF function address is a flag specifying whether the instructions are Thumb or ARM. So clear this bit before using the addresses for symbol mapping. * src/abg-dwarf-reader.cc (read_context::load_symbol_maps_from_symtab_section): Clear bit zero of ARM32 function addresses. * src/abg-elf-helpers.cc (architecture_is_arm32): Add new function. * src/abg-elf-helpers.h (architecture_is_arm32): Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Update. Signed-off-by: Giuliano Procida Reviewed-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 3 + src/abg-elf-helpers.cc | 13 + src/abg-elf-helpers.h | 3 + .../test-read-dwarf/test-libandroid.so.abi | 10851 +++++++++------- 4 files changed, 6381 insertions(+), 4489 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 9cfd50b3..9a8e7b34 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -6207,6 +6207,7 @@ public: ABG_ASSERT(gelf_getehdr(elf_handle(), &elf_header)); bool is_ppc64 = architecture_is_ppc64(elf_handle()); + bool is_arm32 = architecture_is_arm32(elf_handle()); for (size_t i = 0; i < nb_syms; ++i) { @@ -6236,6 +6237,8 @@ public: maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle(), sym); + if (is_arm32) + symbol_value = symbol_value & ~1; addr_elf_symbol_sptr_map_type::const_iterator it = fun_addr_sym_map_->find(symbol_value); if (it == fun_addr_sym_map_->end()) diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc index 5130e5b6..213c5d60 100644 --- a/src/abg-elf-helpers.cc +++ b/src/abg-elf-helpers.cc @@ -827,6 +827,19 @@ architecture_is_ppc64(Elf* elf_handle) return (elf_header && elf_header->e_machine == EM_PPC64); } +/// Test if the architecture of the current binary is arm32. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return true iff the architecture of the current binary is arm32. +bool +architecture_is_arm32(Elf* elf_handle) +{ + GElf_Ehdr eh_mem; + GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem); + return (elf_header && elf_header->e_machine == EM_ARM); +} + /// Test if the endianness of the current binary is Big Endian. /// /// https://en.wikipedia.org/wiki/Endianness. diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h index b4f3293d..7ce4df95 100644 --- a/src/abg-elf-helpers.h +++ b/src/abg-elf-helpers.h @@ -130,6 +130,9 @@ get_version_for_symbol(Elf* elf_handle, bool architecture_is_ppc64(Elf* elf_handle); +bool +architecture_is_arm32(Elf* elf_handle); + bool architecture_is_big_endian(Elf* elf_handle); diff --git a/tests/data/test-read-dwarf/test-libandroid.so.abi b/tests/data/test-read-dwarf/test-libandroid.so.abi index 34d22e9c..9d09d6c3 100644 --- a/tests/data/test-read-dwarf/test-libandroid.so.abi +++ b/tests/data/test-read-dwarf/test-libandroid.so.abi @@ -2665,7 +2665,6 @@ - @@ -2684,12 +2683,12 @@ + - @@ -3451,12 +3450,14 @@ + + @@ -3498,6 +3499,7 @@ + @@ -3523,6 +3525,7 @@ + @@ -3541,8 +3544,13 @@ + + + + + @@ -4598,6 +4606,8 @@ + + @@ -5369,317 +5379,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5756,6 +5455,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6673,6 +6683,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -6705,41 +6739,85 @@ - + - + + + - + + + + + + + + + + + + - + - + + + + + + + + - + - + - - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7320,176 +7398,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7622,6 +7530,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -9027,30 +9105,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -9565,30 +9619,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -10293,26 +10323,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -12016,15 +12026,6 @@ - - - - - - - - - @@ -12972,6 +12973,15 @@ + + + + + + + + + @@ -15012,6 +15022,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -17014,6 +17110,8 @@ + + @@ -17784,11 +17882,6 @@ - - - - - @@ -17846,6 +17939,11 @@ + + + + + @@ -18083,6 +18181,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18095,13 +18223,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18118,6 +18492,7 @@ + @@ -18133,11 +18508,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18278,6 +19012,7 @@ + @@ -18407,6 +19142,16 @@ + + + + + + + + + + @@ -18452,8 +19197,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18461,6 +19291,13 @@ + + + + + + + @@ -18468,6 +19305,10 @@ + + + + @@ -18477,18 +19318,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18533,6 +19693,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18609,6 +19920,7 @@ + @@ -18731,22 +20043,40 @@ - + + + + + + + + + + + + + + - - + + + + + + + @@ -19897,6 +21227,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -19919,7 +21282,28 @@ - + + + + + + + + + + + + + + + + + + + + + + @@ -19934,6 +21318,7 @@ + @@ -19975,14 +21360,6 @@ - - - - - - - - @@ -19998,22 +21375,60 @@ - - - + + + + + + + + + + + - + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -20163,6 +21578,9 @@ + + + @@ -22063,7 +23481,6 @@ - @@ -22076,6 +23493,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -22242,6 +23779,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -22525,62 +24118,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -22758,126 +24295,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -24129,7 +25546,7 @@ - + @@ -24168,7 +25585,7 @@ - + @@ -24258,6 +25675,7 @@ + @@ -24365,7 +25783,6 @@ - @@ -24377,465 +25794,474 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - - + + + + - - - - - + + + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - - - - - + + + + + - - - - - - + + + + + + - - - + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - + - + - - + + - - - + + + - - - - + + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - + - + - + - + - - + + - - + + - - + + - - - + + + - - - + + + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - - + + - - + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + @@ -24856,5699 +26282,5690 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + - - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + - - - - + + + + + + - - - - + + - - - - - - - - - - - + + + - - - + + + + + + + + - - - - + + - - - + + + - - - - + + + + + + + + + + - - - + + + + + + + + + + + + + + - - - - + + - - - - - - - - - - - - - - + - + - + - + - - - - - - - - + + - - - + + + - - - - + + + + + - - - - + + + + - - - + + + + + + + + - - - - - - - - - - - - - + + - + - - - + + + + + + + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - + - + + + + + + + + - + - + + + + - + - + - + - + - - - + + + + - - + - + + + + + + + - + + + + + + + - - + + - - - - - - - - - - - - - + + + + - - + + + + + + + + + + - + - + - + - + - + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + - - - + + - - - - + + + + + + + + + + + - - - + + + + + + + + + + + + - - - - + + + + + - - - + + - - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + - + - + - + + + - + - + + + + + + + + + + - + - + - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - + + + + - - + + + + + + + + + - - - - - - - - - + + + + + - + - + + + + - - + + + + + + + + + - - + + + + + - + - - - - - + + + + + + + + + + + - + - + - + - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + - + - + - + - + - + - + + + - + - + + + + - + - + - + - + - + - + - - - + + + + - + - + + + - + + + + + + + + + + + + + + + - - - - - + + - - - - + + + - - + + + + + + + + - - + + + + + + + + + - - + + + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - - - + + + - - - + + + - - - - + + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - - - - - - - - - + - + - + - - - + + - - - + + + + + + - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - + + + - - - - + + + + - - - + + + - - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + + - - - - + + - - + + - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - - - - - + + - - + + - + + + + + + + + + + - - + + - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - + + + - - - - - + + + - - - + + + + - - - - - - - + + + - - - - - - - - - - - + + + + - - - - - - + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + - + - + + + + + + + + + + + + - + - + + + + + + + + + + + + - + - + + - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - + - - - + - + - + - + - + - - - + + + - - - - + + + + + + + + + + + + + + + + + - - - + - + + + - + - + - + - + - + - - - - - - - + + + - - + + + + - - + + + + + + + + + - - + + - - + + - - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + + + - - - + + + - - - - + + + + - - - + + + + - - - - + + + + + - - - - + + + - - - - - - + + + - - - - - - - + + + + - - - - + + + - - - - - + + + + - - - - - + + + - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - + - + - + - + - - - - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - + + + + - - - - - + + + + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + - - - + + + + + + + + + + + + + + + + - - - + + - - - - + + - + - - + + + + + - - - - - - - + - + - + - + - + - + - + - - + - + - - - - - - - + - + + + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + - - - + + - - - - - - - + + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - + + - - - - - + + + - - - - - - + + + - - - + + + + - - - + + + + - - - - + + + + + - - - - + + + - - - - + + + - - - + + + + - - - - - - + + + - - - - - - - + + + + - - - - - + + + - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - + - + - + - + - - - - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - + + + + - - - - - + + + + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + - - - - - - - - - - - - + + - - - + + + + - + - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + + - + - + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - + - + - + - - + + - - - + + + - - + + - + - + + + + + + + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - + - + - + - + - + - - + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - + - - - - - + + + + + + + + + + + + + + + - - + - + + + + + + + + - - + + - + - + - + - - + + + + + + + + + + + + + + + - - + + + + + - + - - - - - + - + - + - + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - + + + + + + + + + - - - - + + + + + + + + + + + + + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - - + + - - - - - + + + + + - - - - + + + + + + - - - - - + + + - - - - - - + + + - - - + + + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + + + - - - + + + + + + + - - - - - - + + + + - - - - - - - + + + + + - - - - - + + + + + - - - - - - + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - + + + - - - - + + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - + - + - + - + - - + + - - + + + + + + + + - - - + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - - - - - - - - - - - - - - - - - - + - - + + - + - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + + - - - - - - - - - - - + + + - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - + - + - + - + - - + + - - - - + + + + + - - - + + + + - - - - - - - + + + + + - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - + + + - - - + + + + - - - - - - - + + + - - - - - - - - - - - + + + + + + - - - - - + + + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + - - + + - - - + + + + - - - + + + + + - - - - + + + - - - - + + + - - - - - + + + + - - - + + + + - - - + + + + - - - - - + + + + + + + + + + + + + + - - - + + + - - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + - - - - + + - - - - - - - - - - - - - - + - + - + - + - - - - - - - - + + - - - - - - - - - - + + + - - - - + + + + + - - - + + + + - - - - - - - - - - - - - + + + + + + - + - - - + + + + + + + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - + - + + + - + + + + + + - + + + + - + - + - + - + - - - + + + + - + - + + + + + + + + + + - + - + - + - - + + - + - + - + - - - - - + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + + + + - - - - + + + + - - + + - + - + - + - + - + - + + + + + + + - + - + - + - + - + + + + - - + + - - - + + + + + - - - + + + + - - - - + + + + + - - - - + + + + + + - - - - - - - - - - - + + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - + + + + + + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - - + + - - - - - + + + + - - - - - - + + + + + - - - + + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + - - - - + + - - - - - + + + + - - - - - + + + + + + + + + + + + + + + + - - - - - - + + - + - + - + - + - + - + - - + + + + + + + + + + - - + + - - + + - - + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + - - + + - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + - + - + - + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + - - - + + + + + + + + + + + + - - - + + - + + + + + + - + - + - - - - - + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - + - + - - + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + + + + + - + - + - - + + - + - + - + - + - + - - + + - - - + + + - - + + - + - + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - + - + - + - + - + - - + + - + - + - + - - - - + - + - + - + - + - - - - - + - + - + - + - - + + - + - + - + - - + + - + - - + + - - - - - + - + - - + + - - + + - + - + - + - - + + - + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - + - + - + - - - + - + - + - + - + - - - - - - - - - - - - - - - + + + - - - - - - - + - + - + - - + + + + + + + + - + + - + - - - + + + + + + + - - - + + + + + - - - - - - - + + - - - + + - - - + + + - - - - + + + + + + + + + + + + + + + + - + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - - - - + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - + - + - - + + + + + + + + + + + + + + + + + - - + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + - + - + - - - + - + - + - + - + - - - - + + + - + - + - - - + + + + + + + + + + - - - - - - - - - + + + + - - + + - - + + - + - + - + - + + + + - + - - + + - - - - + + + + - + + + + + + + + + + + @@ -32385,6 +33802,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -32465,31 +33907,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -32755,6 +34172,19 @@ + + + + + + + + + + + + + @@ -32825,8 +34255,6 @@ - - @@ -32872,17 +34300,6 @@ - - - - - - - - - - - @@ -32906,6 +34323,7 @@ + @@ -32914,10 +34332,154 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33096,6 +34658,8 @@ + + @@ -33192,6 +34756,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33400,6 +34999,8 @@ + + @@ -33415,6 +35016,10 @@ + + + + @@ -34380,16 +35985,6 @@ - - - - - - - - - - @@ -34640,6 +36235,11 @@ + + + + + @@ -34663,6 +36263,11 @@ + + + + + @@ -36938,6 +38543,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36945,23 +38630,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36969,9 +38679,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36996,6 +38736,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -37005,6 +38769,8 @@ + + @@ -37103,7 +38869,6 @@ - @@ -37471,7 +39236,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +