diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/libunwind | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/libunwind')
31 files changed, 7865 insertions, 7865 deletions
diff --git a/contrib/libs/libunwind/LICENSE.TXT b/contrib/libs/libunwind/LICENSE.TXT index 1e3120621c..772ff14ecd 100644 --- a/contrib/libs/libunwind/LICENSE.TXT +++ b/contrib/libs/libunwind/LICENSE.TXT @@ -1,311 +1,311 @@ -============================================================================== -The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: -============================================================================== - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - -============================================================================== -Software from third parties included in the LLVM Project: -============================================================================== -The LLVM Project contains third party software which is under different license -terms. All such code will be identified clearly using at least one of two -mechanisms: -1) It will be in a separate directory tree with its own `LICENSE.txt` or - `LICENSE` file at the top containing the specific license and restrictions - which apply to that software, or -2) It will contain specific license and restriction terms at the top of every - file. - -============================================================================== -Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): -============================================================================== - -The libunwind library is dual licensed under both the University of Illinois -"BSD-Like" license and the MIT license. As a user of this code you may choose -to use it under either license. As a contributor, you agree to allow your code -to be used under both. - -Full text of the relevant licenses is included below. - -============================================================================== - -University of Illinois/NCSA -Open Source License - -Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT - -All rights reserved. - -Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLVM Team, University of Illinois at - Urbana-Champaign, nor the names of its contributors may be used to - endorse or promote products derived from this Software without specific - prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - -============================================================================== - -Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +============================================================================== +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): +============================================================================== + +The libunwind library is dual licensed under both the University of Illinois +"BSD-Like" license and the MIT license. As a user of this code you may choose +to use it under either license. As a contributor, you agree to allow your code +to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/contrib/libs/libunwind/include/__libunwind_config.h b/contrib/libs/libunwind/include/__libunwind_config.h index e87bcf4003..8d1866874a 100644 --- a/contrib/libs/libunwind/include/__libunwind_config.h +++ b/contrib/libs/libunwind/include/__libunwind_config.h @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -11,139 +11,139 @@ #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ !defined(__ARM_DWARF_EH__) -#define _LIBUNWIND_ARM_EHABI +#define _LIBUNWIND_ARM_EHABI #endif -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 32 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 116 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 32 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 116 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 31 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143 - -#if defined(_LIBUNWIND_IS_NATIVE_ONLY) + +#if defined(_LIBUNWIND_IS_NATIVE_ONLY) # if defined(__linux__) # define _LIBUNWIND_TARGET_LINUX 1 # endif # if defined(__i386__) -# define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_CONTEXT_SIZE 8 -# define _LIBUNWIND_CURSOR_SIZE 15 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 +# define _LIBUNWIND_TARGET_I386 +# define _LIBUNWIND_CONTEXT_SIZE 8 +# define _LIBUNWIND_CURSOR_SIZE 15 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) -# define _LIBUNWIND_TARGET_X86_64 1 -# if defined(_WIN64) -# define _LIBUNWIND_CONTEXT_SIZE 54 -# ifdef __SEH__ -# define _LIBUNWIND_CURSOR_SIZE 204 -# else -# define _LIBUNWIND_CURSOR_SIZE 66 -# endif -# else -# define _LIBUNWIND_CONTEXT_SIZE 21 -# define _LIBUNWIND_CURSOR_SIZE 33 -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 -# elif defined(__powerpc64__) -# define _LIBUNWIND_TARGET_PPC64 1 -# define _LIBUNWIND_CONTEXT_SIZE 167 -# define _LIBUNWIND_CURSOR_SIZE 179 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 +# define _LIBUNWIND_TARGET_X86_64 1 +# if defined(_WIN64) +# define _LIBUNWIND_CONTEXT_SIZE 54 +# ifdef __SEH__ +# define _LIBUNWIND_CURSOR_SIZE 204 +# else +# define _LIBUNWIND_CURSOR_SIZE 66 +# endif +# else +# define _LIBUNWIND_CONTEXT_SIZE 21 +# define _LIBUNWIND_CURSOR_SIZE 33 +# endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 +# elif defined(__powerpc64__) +# define _LIBUNWIND_TARGET_PPC64 1 +# define _LIBUNWIND_CONTEXT_SIZE 167 +# define _LIBUNWIND_CURSOR_SIZE 179 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 # elif defined(__powerpc__) -# define _LIBUNWIND_TARGET_PPC 1 -# define _LIBUNWIND_CONTEXT_SIZE 117 -# define _LIBUNWIND_CURSOR_SIZE 124 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC +# define _LIBUNWIND_TARGET_PPC 1 +# define _LIBUNWIND_CONTEXT_SIZE 117 +# define _LIBUNWIND_CURSOR_SIZE 124 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC # elif defined(__aarch64__) -# define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_CONTEXT_SIZE 66 -# if defined(__SEH__) -# define _LIBUNWIND_CURSOR_SIZE 164 -# else -# define _LIBUNWIND_CURSOR_SIZE 78 -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 +# define _LIBUNWIND_TARGET_AARCH64 1 +# define _LIBUNWIND_CONTEXT_SIZE 66 +# if defined(__SEH__) +# define _LIBUNWIND_CURSOR_SIZE 164 +# else +# define _LIBUNWIND_CURSOR_SIZE 78 +# endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) -# define _LIBUNWIND_TARGET_ARM 1 -# if defined(__SEH__) -# define _LIBUNWIND_CONTEXT_SIZE 42 -# define _LIBUNWIND_CURSOR_SIZE 80 -# elif defined(__ARM_WMMX) -# define _LIBUNWIND_CONTEXT_SIZE 61 -# define _LIBUNWIND_CURSOR_SIZE 68 -# else -# define _LIBUNWIND_CONTEXT_SIZE 42 -# define _LIBUNWIND_CURSOR_SIZE 49 -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM -# elif defined(__or1k__) -# define _LIBUNWIND_TARGET_OR1K 1 -# define _LIBUNWIND_CONTEXT_SIZE 16 -# define _LIBUNWIND_CURSOR_SIZE 24 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K -# elif defined(__hexagon__) -# define _LIBUNWIND_TARGET_HEXAGON 1 -// Values here change when : Registers.hpp - hexagon_thread_state_t change -# define _LIBUNWIND_CONTEXT_SIZE 18 -# define _LIBUNWIND_CURSOR_SIZE 24 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON -# elif defined(__mips__) -# if defined(_ABIO32) && _MIPS_SIM == _ABIO32 -# define _LIBUNWIND_TARGET_MIPS_O32 1 -# if defined(__mips_hard_float) -# define _LIBUNWIND_CONTEXT_SIZE 50 -# define _LIBUNWIND_CURSOR_SIZE 57 -# else -# define _LIBUNWIND_CONTEXT_SIZE 18 -# define _LIBUNWIND_CURSOR_SIZE 24 -# endif -# elif defined(_ABIN32) && _MIPS_SIM == _ABIN32 -# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 -# if defined(__mips_hard_float) -# define _LIBUNWIND_CONTEXT_SIZE 67 -# define _LIBUNWIND_CURSOR_SIZE 74 -# else -# define _LIBUNWIND_CONTEXT_SIZE 35 -# define _LIBUNWIND_CURSOR_SIZE 42 -# endif -# elif defined(_ABI64) && _MIPS_SIM == _ABI64 -# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 -# if defined(__mips_hard_float) -# define _LIBUNWIND_CONTEXT_SIZE 67 -# define _LIBUNWIND_CURSOR_SIZE 79 -# else -# define _LIBUNWIND_CONTEXT_SIZE 35 -# define _LIBUNWIND_CURSOR_SIZE 47 -# endif -# else -# error "Unsupported MIPS ABI and/or environment" -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS +# define _LIBUNWIND_TARGET_ARM 1 +# if defined(__SEH__) +# define _LIBUNWIND_CONTEXT_SIZE 42 +# define _LIBUNWIND_CURSOR_SIZE 80 +# elif defined(__ARM_WMMX) +# define _LIBUNWIND_CONTEXT_SIZE 61 +# define _LIBUNWIND_CURSOR_SIZE 68 +# else +# define _LIBUNWIND_CONTEXT_SIZE 42 +# define _LIBUNWIND_CURSOR_SIZE 49 +# endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM +# elif defined(__or1k__) +# define _LIBUNWIND_TARGET_OR1K 1 +# define _LIBUNWIND_CONTEXT_SIZE 16 +# define _LIBUNWIND_CURSOR_SIZE 24 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K +# elif defined(__hexagon__) +# define _LIBUNWIND_TARGET_HEXAGON 1 +// Values here change when : Registers.hpp - hexagon_thread_state_t change +# define _LIBUNWIND_CONTEXT_SIZE 18 +# define _LIBUNWIND_CURSOR_SIZE 24 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON +# elif defined(__mips__) +# if defined(_ABIO32) && _MIPS_SIM == _ABIO32 +# define _LIBUNWIND_TARGET_MIPS_O32 1 +# if defined(__mips_hard_float) +# define _LIBUNWIND_CONTEXT_SIZE 50 +# define _LIBUNWIND_CURSOR_SIZE 57 +# else +# define _LIBUNWIND_CONTEXT_SIZE 18 +# define _LIBUNWIND_CURSOR_SIZE 24 +# endif +# elif defined(_ABIN32) && _MIPS_SIM == _ABIN32 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +# if defined(__mips_hard_float) +# define _LIBUNWIND_CONTEXT_SIZE 67 +# define _LIBUNWIND_CURSOR_SIZE 74 +# else +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 42 +# endif +# elif defined(_ABI64) && _MIPS_SIM == _ABI64 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +# if defined(__mips_hard_float) +# define _LIBUNWIND_CONTEXT_SIZE 67 +# define _LIBUNWIND_CURSOR_SIZE 79 +# else +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 47 +# endif +# else +# error "Unsupported MIPS ABI and/or environment" +# endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS #elif defined(__sparc__) && defined(__arch64__) #define _LIBUNWIND_TARGET_SPARC64 1 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 #define _LIBUNWIND_CONTEXT_SIZE 33 #define _LIBUNWIND_CURSOR_SIZE 45 -# elif defined(__sparc__) - #define _LIBUNWIND_TARGET_SPARC 1 - #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC - #define _LIBUNWIND_CONTEXT_SIZE 16 - #define _LIBUNWIND_CURSOR_SIZE 23 -# elif defined(__riscv) +# elif defined(__sparc__) + #define _LIBUNWIND_TARGET_SPARC 1 + #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC + #define _LIBUNWIND_CONTEXT_SIZE 16 + #define _LIBUNWIND_CURSOR_SIZE 23 +# elif defined(__riscv) # define _LIBUNWIND_TARGET_RISCV 1 # if defined(__riscv_flen) # define RISCV_FLEN __riscv_flen -# else +# else # define RISCV_FLEN 0 -# endif +# endif # define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64) # if __riscv_xlen == 32 # define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7) @@ -152,33 +152,33 @@ # else # error "Unsupported RISC-V ABI" # endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV # elif defined(__ve__) # define _LIBUNWIND_TARGET_VE 1 # define _LIBUNWIND_CONTEXT_SIZE 67 # define _LIBUNWIND_CURSOR_SIZE 79 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE -# else -# error "Unsupported architecture." -# endif -#else // !_LIBUNWIND_IS_NATIVE_ONLY -# define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_TARGET_X86_64 1 -# define _LIBUNWIND_TARGET_PPC 1 -# define _LIBUNWIND_TARGET_PPC64 1 -# define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_TARGET_ARM 1 -# define _LIBUNWIND_TARGET_OR1K 1 -# define _LIBUNWIND_TARGET_MIPS_O32 1 -# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 -# define _LIBUNWIND_TARGET_SPARC 1 +# else +# error "Unsupported architecture." +# endif +#else // !_LIBUNWIND_IS_NATIVE_ONLY +# define _LIBUNWIND_TARGET_I386 +# define _LIBUNWIND_TARGET_X86_64 1 +# define _LIBUNWIND_TARGET_PPC 1 +# define _LIBUNWIND_TARGET_PPC64 1 +# define _LIBUNWIND_TARGET_AARCH64 1 +# define _LIBUNWIND_TARGET_ARM 1 +# define _LIBUNWIND_TARGET_OR1K 1 +# define _LIBUNWIND_TARGET_MIPS_O32 1 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +# define _LIBUNWIND_TARGET_SPARC 1 # define _LIBUNWIND_TARGET_SPARC64 1 -# define _LIBUNWIND_TARGET_HEXAGON 1 -# define _LIBUNWIND_TARGET_RISCV 1 +# define _LIBUNWIND_TARGET_HEXAGON 1 +# define _LIBUNWIND_TARGET_RISCV 1 # define _LIBUNWIND_TARGET_VE 1 -# define _LIBUNWIND_CONTEXT_SIZE 167 -# define _LIBUNWIND_CURSOR_SIZE 179 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 -#endif // _LIBUNWIND_IS_NATIVE_ONLY - +# define _LIBUNWIND_CONTEXT_SIZE 167 +# define _LIBUNWIND_CURSOR_SIZE 179 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 +#endif // _LIBUNWIND_IS_NATIVE_ONLY + #endif // ____LIBUNWIND_CONFIG_H__ diff --git a/contrib/libs/libunwind/include/libunwind.h b/contrib/libs/libunwind/include/libunwind.h index 8303c1a04c..ef88caf664 100644 --- a/contrib/libs/libunwind/include/libunwind.h +++ b/contrib/libs/libunwind/include/libunwind.h @@ -1,11 +1,11 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -// Compatible with libunwind API documented at: +// Compatible with libunwind API documented at: // http://www.nongnu.org/libunwind/man/libunwind(3).html // //===----------------------------------------------------------------------===// @@ -19,36 +19,36 @@ #include <stddef.h> #ifdef __APPLE__ - #if __clang__ - #if __has_include(<Availability.h>) - #include <Availability.h> - #endif - #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 - #include <Availability.h> - #endif - - #ifdef __arm__ - #define LIBUNWIND_AVAIL __attribute__((unavailable)) - #elif defined(__OSX_AVAILABLE_STARTING) - #define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0) - #else - #include <AvailabilityMacros.h> - #ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define LIBUNWIND_AVAIL AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + #if __clang__ + #if __has_include(<Availability.h>) + #include <Availability.h> + #endif + #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 + #include <Availability.h> + #endif + + #ifdef __arm__ + #define LIBUNWIND_AVAIL __attribute__((unavailable)) + #elif defined(__OSX_AVAILABLE_STARTING) + #define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0) + #else + #include <AvailabilityMacros.h> + #ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + #define LIBUNWIND_AVAIL AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER #else - #define LIBUNWIND_AVAIL __attribute__((unavailable)) + #define LIBUNWIND_AVAIL __attribute__((unavailable)) #endif - #endif + #endif #else #define LIBUNWIND_AVAIL #endif -#if defined(_WIN32) && defined(__SEH__) - #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR __attribute__((__aligned__(16))) -#else - #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR -#endif - +#if defined(_WIN32) && defined(__SEH__) + #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR __attribute__((__aligned__(16))) +#else + #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR +#endif + /* error codes */ enum { UNW_ESUCCESS = 0, /* no error */ @@ -62,26 +62,26 @@ enum { UNW_EINVAL = -6547, /* unsupported operation or bad value */ UNW_EBADVERSION = -6548, /* unwind info has unsupported version */ UNW_ENOINFO = -6549 /* no unwind info found */ -#if defined(_LIBUNWIND_TARGET_AARCH64) && !defined(_LIBUNWIND_IS_NATIVE_ONLY) - , UNW_ECROSSRASIGNING = -6550 /* cross unwind with return address signing */ -#endif +#if defined(_LIBUNWIND_TARGET_AARCH64) && !defined(_LIBUNWIND_IS_NATIVE_ONLY) + , UNW_ECROSSRASIGNING = -6550 /* cross unwind with return address signing */ +#endif }; struct unw_context_t { - uint64_t data[_LIBUNWIND_CONTEXT_SIZE]; + uint64_t data[_LIBUNWIND_CONTEXT_SIZE]; }; typedef struct unw_context_t unw_context_t; struct unw_cursor_t { - uint64_t data[_LIBUNWIND_CURSOR_SIZE]; -} LIBUNWIND_CURSOR_ALIGNMENT_ATTR; + uint64_t data[_LIBUNWIND_CURSOR_SIZE]; +} LIBUNWIND_CURSOR_ALIGNMENT_ATTR; typedef struct unw_cursor_t unw_cursor_t; typedef struct unw_addr_space *unw_addr_space_t; typedef int unw_regnum_t; -typedef uintptr_t unw_word_t; -#if defined(__arm__) && !defined(__ARM_DWARF_EH__) +typedef uintptr_t unw_word_t; +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) typedef uint64_t unw_fpreg_t; #else typedef double unw_fpreg_t; @@ -96,8 +96,8 @@ struct unw_proc_info_t { unw_word_t gp; /* not used */ unw_word_t flags; /* not used */ uint32_t format; /* compact unwind encoding, or zero if none */ - uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */ - unw_word_t unwind_info; /* address of DWARF unwind info, or zero */ + uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */ + unw_word_t unwind_info; /* address of DWARF unwind info, or zero */ unw_word_t extra; /* mach_header of mach-o image containing func */ }; typedef struct unw_proc_info_t unw_proc_info_t; @@ -169,24 +169,24 @@ enum { UNW_X86_64_R12 = 12, UNW_X86_64_R13 = 13, UNW_X86_64_R14 = 14, - UNW_X86_64_R15 = 15, - UNW_X86_64_RIP = 16, - UNW_X86_64_XMM0 = 17, - UNW_X86_64_XMM1 = 18, - UNW_X86_64_XMM2 = 19, - UNW_X86_64_XMM3 = 20, - UNW_X86_64_XMM4 = 21, - UNW_X86_64_XMM5 = 22, - UNW_X86_64_XMM6 = 23, - UNW_X86_64_XMM7 = 24, - UNW_X86_64_XMM8 = 25, - UNW_X86_64_XMM9 = 26, - UNW_X86_64_XMM10 = 27, - UNW_X86_64_XMM11 = 28, - UNW_X86_64_XMM12 = 29, - UNW_X86_64_XMM13 = 30, - UNW_X86_64_XMM14 = 31, - UNW_X86_64_XMM15 = 32, + UNW_X86_64_R15 = 15, + UNW_X86_64_RIP = 16, + UNW_X86_64_XMM0 = 17, + UNW_X86_64_XMM1 = 18, + UNW_X86_64_XMM2 = 19, + UNW_X86_64_XMM3 = 20, + UNW_X86_64_XMM4 = 21, + UNW_X86_64_XMM5 = 22, + UNW_X86_64_XMM6 = 23, + UNW_X86_64_XMM7 = 24, + UNW_X86_64_XMM8 = 25, + UNW_X86_64_XMM9 = 26, + UNW_X86_64_XMM10 = 27, + UNW_X86_64_XMM11 = 28, + UNW_X86_64_XMM12 = 29, + UNW_X86_64_XMM13 = 30, + UNW_X86_64_XMM14 = 31, + UNW_X86_64_XMM15 = 32, }; @@ -307,190 +307,190 @@ enum { UNW_PPC_SPEFSCR = 112 }; -// 64-bit ppc register numbers -enum { - UNW_PPC64_R0 = 0, - UNW_PPC64_R1 = 1, - UNW_PPC64_R2 = 2, - UNW_PPC64_R3 = 3, - UNW_PPC64_R4 = 4, - UNW_PPC64_R5 = 5, - UNW_PPC64_R6 = 6, - UNW_PPC64_R7 = 7, - UNW_PPC64_R8 = 8, - UNW_PPC64_R9 = 9, - UNW_PPC64_R10 = 10, - UNW_PPC64_R11 = 11, - UNW_PPC64_R12 = 12, - UNW_PPC64_R13 = 13, - UNW_PPC64_R14 = 14, - UNW_PPC64_R15 = 15, - UNW_PPC64_R16 = 16, - UNW_PPC64_R17 = 17, - UNW_PPC64_R18 = 18, - UNW_PPC64_R19 = 19, - UNW_PPC64_R20 = 20, - UNW_PPC64_R21 = 21, - UNW_PPC64_R22 = 22, - UNW_PPC64_R23 = 23, - UNW_PPC64_R24 = 24, - UNW_PPC64_R25 = 25, - UNW_PPC64_R26 = 26, - UNW_PPC64_R27 = 27, - UNW_PPC64_R28 = 28, - UNW_PPC64_R29 = 29, - UNW_PPC64_R30 = 30, - UNW_PPC64_R31 = 31, - UNW_PPC64_F0 = 32, - UNW_PPC64_F1 = 33, - UNW_PPC64_F2 = 34, - UNW_PPC64_F3 = 35, - UNW_PPC64_F4 = 36, - UNW_PPC64_F5 = 37, - UNW_PPC64_F6 = 38, - UNW_PPC64_F7 = 39, - UNW_PPC64_F8 = 40, - UNW_PPC64_F9 = 41, - UNW_PPC64_F10 = 42, - UNW_PPC64_F11 = 43, - UNW_PPC64_F12 = 44, - UNW_PPC64_F13 = 45, - UNW_PPC64_F14 = 46, - UNW_PPC64_F15 = 47, - UNW_PPC64_F16 = 48, - UNW_PPC64_F17 = 49, - UNW_PPC64_F18 = 50, - UNW_PPC64_F19 = 51, - UNW_PPC64_F20 = 52, - UNW_PPC64_F21 = 53, - UNW_PPC64_F22 = 54, - UNW_PPC64_F23 = 55, - UNW_PPC64_F24 = 56, - UNW_PPC64_F25 = 57, - UNW_PPC64_F26 = 58, - UNW_PPC64_F27 = 59, - UNW_PPC64_F28 = 60, - UNW_PPC64_F29 = 61, - UNW_PPC64_F30 = 62, - UNW_PPC64_F31 = 63, - // 64: reserved - UNW_PPC64_LR = 65, - UNW_PPC64_CTR = 66, - // 67: reserved - UNW_PPC64_CR0 = 68, - UNW_PPC64_CR1 = 69, - UNW_PPC64_CR2 = 70, - UNW_PPC64_CR3 = 71, - UNW_PPC64_CR4 = 72, - UNW_PPC64_CR5 = 73, - UNW_PPC64_CR6 = 74, - UNW_PPC64_CR7 = 75, - UNW_PPC64_XER = 76, - UNW_PPC64_V0 = 77, - UNW_PPC64_V1 = 78, - UNW_PPC64_V2 = 79, - UNW_PPC64_V3 = 80, - UNW_PPC64_V4 = 81, - UNW_PPC64_V5 = 82, - UNW_PPC64_V6 = 83, - UNW_PPC64_V7 = 84, - UNW_PPC64_V8 = 85, - UNW_PPC64_V9 = 86, - UNW_PPC64_V10 = 87, - UNW_PPC64_V11 = 88, - UNW_PPC64_V12 = 89, - UNW_PPC64_V13 = 90, - UNW_PPC64_V14 = 91, - UNW_PPC64_V15 = 92, - UNW_PPC64_V16 = 93, - UNW_PPC64_V17 = 94, - UNW_PPC64_V18 = 95, - UNW_PPC64_V19 = 96, - UNW_PPC64_V20 = 97, - UNW_PPC64_V21 = 98, - UNW_PPC64_V22 = 99, - UNW_PPC64_V23 = 100, - UNW_PPC64_V24 = 101, - UNW_PPC64_V25 = 102, - UNW_PPC64_V26 = 103, - UNW_PPC64_V27 = 104, - UNW_PPC64_V28 = 105, - UNW_PPC64_V29 = 106, - UNW_PPC64_V30 = 107, - UNW_PPC64_V31 = 108, - // 109, 111-113: OpenPOWER ELF V2 ABI: reserved - // Borrowing VRSAVE number from PPC32. - UNW_PPC64_VRSAVE = 109, - UNW_PPC64_VSCR = 110, - UNW_PPC64_TFHAR = 114, - UNW_PPC64_TFIAR = 115, - UNW_PPC64_TEXASR = 116, - UNW_PPC64_VS0 = UNW_PPC64_F0, - UNW_PPC64_VS1 = UNW_PPC64_F1, - UNW_PPC64_VS2 = UNW_PPC64_F2, - UNW_PPC64_VS3 = UNW_PPC64_F3, - UNW_PPC64_VS4 = UNW_PPC64_F4, - UNW_PPC64_VS5 = UNW_PPC64_F5, - UNW_PPC64_VS6 = UNW_PPC64_F6, - UNW_PPC64_VS7 = UNW_PPC64_F7, - UNW_PPC64_VS8 = UNW_PPC64_F8, - UNW_PPC64_VS9 = UNW_PPC64_F9, - UNW_PPC64_VS10 = UNW_PPC64_F10, - UNW_PPC64_VS11 = UNW_PPC64_F11, - UNW_PPC64_VS12 = UNW_PPC64_F12, - UNW_PPC64_VS13 = UNW_PPC64_F13, - UNW_PPC64_VS14 = UNW_PPC64_F14, - UNW_PPC64_VS15 = UNW_PPC64_F15, - UNW_PPC64_VS16 = UNW_PPC64_F16, - UNW_PPC64_VS17 = UNW_PPC64_F17, - UNW_PPC64_VS18 = UNW_PPC64_F18, - UNW_PPC64_VS19 = UNW_PPC64_F19, - UNW_PPC64_VS20 = UNW_PPC64_F20, - UNW_PPC64_VS21 = UNW_PPC64_F21, - UNW_PPC64_VS22 = UNW_PPC64_F22, - UNW_PPC64_VS23 = UNW_PPC64_F23, - UNW_PPC64_VS24 = UNW_PPC64_F24, - UNW_PPC64_VS25 = UNW_PPC64_F25, - UNW_PPC64_VS26 = UNW_PPC64_F26, - UNW_PPC64_VS27 = UNW_PPC64_F27, - UNW_PPC64_VS28 = UNW_PPC64_F28, - UNW_PPC64_VS29 = UNW_PPC64_F29, - UNW_PPC64_VS30 = UNW_PPC64_F30, - UNW_PPC64_VS31 = UNW_PPC64_F31, - UNW_PPC64_VS32 = UNW_PPC64_V0, - UNW_PPC64_VS33 = UNW_PPC64_V1, - UNW_PPC64_VS34 = UNW_PPC64_V2, - UNW_PPC64_VS35 = UNW_PPC64_V3, - UNW_PPC64_VS36 = UNW_PPC64_V4, - UNW_PPC64_VS37 = UNW_PPC64_V5, - UNW_PPC64_VS38 = UNW_PPC64_V6, - UNW_PPC64_VS39 = UNW_PPC64_V7, - UNW_PPC64_VS40 = UNW_PPC64_V8, - UNW_PPC64_VS41 = UNW_PPC64_V9, - UNW_PPC64_VS42 = UNW_PPC64_V10, - UNW_PPC64_VS43 = UNW_PPC64_V11, - UNW_PPC64_VS44 = UNW_PPC64_V12, - UNW_PPC64_VS45 = UNW_PPC64_V13, - UNW_PPC64_VS46 = UNW_PPC64_V14, - UNW_PPC64_VS47 = UNW_PPC64_V15, - UNW_PPC64_VS48 = UNW_PPC64_V16, - UNW_PPC64_VS49 = UNW_PPC64_V17, - UNW_PPC64_VS50 = UNW_PPC64_V18, - UNW_PPC64_VS51 = UNW_PPC64_V19, - UNW_PPC64_VS52 = UNW_PPC64_V20, - UNW_PPC64_VS53 = UNW_PPC64_V21, - UNW_PPC64_VS54 = UNW_PPC64_V22, - UNW_PPC64_VS55 = UNW_PPC64_V23, - UNW_PPC64_VS56 = UNW_PPC64_V24, - UNW_PPC64_VS57 = UNW_PPC64_V25, - UNW_PPC64_VS58 = UNW_PPC64_V26, - UNW_PPC64_VS59 = UNW_PPC64_V27, - UNW_PPC64_VS60 = UNW_PPC64_V28, - UNW_PPC64_VS61 = UNW_PPC64_V29, - UNW_PPC64_VS62 = UNW_PPC64_V30, - UNW_PPC64_VS63 = UNW_PPC64_V31 -}; - +// 64-bit ppc register numbers +enum { + UNW_PPC64_R0 = 0, + UNW_PPC64_R1 = 1, + UNW_PPC64_R2 = 2, + UNW_PPC64_R3 = 3, + UNW_PPC64_R4 = 4, + UNW_PPC64_R5 = 5, + UNW_PPC64_R6 = 6, + UNW_PPC64_R7 = 7, + UNW_PPC64_R8 = 8, + UNW_PPC64_R9 = 9, + UNW_PPC64_R10 = 10, + UNW_PPC64_R11 = 11, + UNW_PPC64_R12 = 12, + UNW_PPC64_R13 = 13, + UNW_PPC64_R14 = 14, + UNW_PPC64_R15 = 15, + UNW_PPC64_R16 = 16, + UNW_PPC64_R17 = 17, + UNW_PPC64_R18 = 18, + UNW_PPC64_R19 = 19, + UNW_PPC64_R20 = 20, + UNW_PPC64_R21 = 21, + UNW_PPC64_R22 = 22, + UNW_PPC64_R23 = 23, + UNW_PPC64_R24 = 24, + UNW_PPC64_R25 = 25, + UNW_PPC64_R26 = 26, + UNW_PPC64_R27 = 27, + UNW_PPC64_R28 = 28, + UNW_PPC64_R29 = 29, + UNW_PPC64_R30 = 30, + UNW_PPC64_R31 = 31, + UNW_PPC64_F0 = 32, + UNW_PPC64_F1 = 33, + UNW_PPC64_F2 = 34, + UNW_PPC64_F3 = 35, + UNW_PPC64_F4 = 36, + UNW_PPC64_F5 = 37, + UNW_PPC64_F6 = 38, + UNW_PPC64_F7 = 39, + UNW_PPC64_F8 = 40, + UNW_PPC64_F9 = 41, + UNW_PPC64_F10 = 42, + UNW_PPC64_F11 = 43, + UNW_PPC64_F12 = 44, + UNW_PPC64_F13 = 45, + UNW_PPC64_F14 = 46, + UNW_PPC64_F15 = 47, + UNW_PPC64_F16 = 48, + UNW_PPC64_F17 = 49, + UNW_PPC64_F18 = 50, + UNW_PPC64_F19 = 51, + UNW_PPC64_F20 = 52, + UNW_PPC64_F21 = 53, + UNW_PPC64_F22 = 54, + UNW_PPC64_F23 = 55, + UNW_PPC64_F24 = 56, + UNW_PPC64_F25 = 57, + UNW_PPC64_F26 = 58, + UNW_PPC64_F27 = 59, + UNW_PPC64_F28 = 60, + UNW_PPC64_F29 = 61, + UNW_PPC64_F30 = 62, + UNW_PPC64_F31 = 63, + // 64: reserved + UNW_PPC64_LR = 65, + UNW_PPC64_CTR = 66, + // 67: reserved + UNW_PPC64_CR0 = 68, + UNW_PPC64_CR1 = 69, + UNW_PPC64_CR2 = 70, + UNW_PPC64_CR3 = 71, + UNW_PPC64_CR4 = 72, + UNW_PPC64_CR5 = 73, + UNW_PPC64_CR6 = 74, + UNW_PPC64_CR7 = 75, + UNW_PPC64_XER = 76, + UNW_PPC64_V0 = 77, + UNW_PPC64_V1 = 78, + UNW_PPC64_V2 = 79, + UNW_PPC64_V3 = 80, + UNW_PPC64_V4 = 81, + UNW_PPC64_V5 = 82, + UNW_PPC64_V6 = 83, + UNW_PPC64_V7 = 84, + UNW_PPC64_V8 = 85, + UNW_PPC64_V9 = 86, + UNW_PPC64_V10 = 87, + UNW_PPC64_V11 = 88, + UNW_PPC64_V12 = 89, + UNW_PPC64_V13 = 90, + UNW_PPC64_V14 = 91, + UNW_PPC64_V15 = 92, + UNW_PPC64_V16 = 93, + UNW_PPC64_V17 = 94, + UNW_PPC64_V18 = 95, + UNW_PPC64_V19 = 96, + UNW_PPC64_V20 = 97, + UNW_PPC64_V21 = 98, + UNW_PPC64_V22 = 99, + UNW_PPC64_V23 = 100, + UNW_PPC64_V24 = 101, + UNW_PPC64_V25 = 102, + UNW_PPC64_V26 = 103, + UNW_PPC64_V27 = 104, + UNW_PPC64_V28 = 105, + UNW_PPC64_V29 = 106, + UNW_PPC64_V30 = 107, + UNW_PPC64_V31 = 108, + // 109, 111-113: OpenPOWER ELF V2 ABI: reserved + // Borrowing VRSAVE number from PPC32. + UNW_PPC64_VRSAVE = 109, + UNW_PPC64_VSCR = 110, + UNW_PPC64_TFHAR = 114, + UNW_PPC64_TFIAR = 115, + UNW_PPC64_TEXASR = 116, + UNW_PPC64_VS0 = UNW_PPC64_F0, + UNW_PPC64_VS1 = UNW_PPC64_F1, + UNW_PPC64_VS2 = UNW_PPC64_F2, + UNW_PPC64_VS3 = UNW_PPC64_F3, + UNW_PPC64_VS4 = UNW_PPC64_F4, + UNW_PPC64_VS5 = UNW_PPC64_F5, + UNW_PPC64_VS6 = UNW_PPC64_F6, + UNW_PPC64_VS7 = UNW_PPC64_F7, + UNW_PPC64_VS8 = UNW_PPC64_F8, + UNW_PPC64_VS9 = UNW_PPC64_F9, + UNW_PPC64_VS10 = UNW_PPC64_F10, + UNW_PPC64_VS11 = UNW_PPC64_F11, + UNW_PPC64_VS12 = UNW_PPC64_F12, + UNW_PPC64_VS13 = UNW_PPC64_F13, + UNW_PPC64_VS14 = UNW_PPC64_F14, + UNW_PPC64_VS15 = UNW_PPC64_F15, + UNW_PPC64_VS16 = UNW_PPC64_F16, + UNW_PPC64_VS17 = UNW_PPC64_F17, + UNW_PPC64_VS18 = UNW_PPC64_F18, + UNW_PPC64_VS19 = UNW_PPC64_F19, + UNW_PPC64_VS20 = UNW_PPC64_F20, + UNW_PPC64_VS21 = UNW_PPC64_F21, + UNW_PPC64_VS22 = UNW_PPC64_F22, + UNW_PPC64_VS23 = UNW_PPC64_F23, + UNW_PPC64_VS24 = UNW_PPC64_F24, + UNW_PPC64_VS25 = UNW_PPC64_F25, + UNW_PPC64_VS26 = UNW_PPC64_F26, + UNW_PPC64_VS27 = UNW_PPC64_F27, + UNW_PPC64_VS28 = UNW_PPC64_F28, + UNW_PPC64_VS29 = UNW_PPC64_F29, + UNW_PPC64_VS30 = UNW_PPC64_F30, + UNW_PPC64_VS31 = UNW_PPC64_F31, + UNW_PPC64_VS32 = UNW_PPC64_V0, + UNW_PPC64_VS33 = UNW_PPC64_V1, + UNW_PPC64_VS34 = UNW_PPC64_V2, + UNW_PPC64_VS35 = UNW_PPC64_V3, + UNW_PPC64_VS36 = UNW_PPC64_V4, + UNW_PPC64_VS37 = UNW_PPC64_V5, + UNW_PPC64_VS38 = UNW_PPC64_V6, + UNW_PPC64_VS39 = UNW_PPC64_V7, + UNW_PPC64_VS40 = UNW_PPC64_V8, + UNW_PPC64_VS41 = UNW_PPC64_V9, + UNW_PPC64_VS42 = UNW_PPC64_V10, + UNW_PPC64_VS43 = UNW_PPC64_V11, + UNW_PPC64_VS44 = UNW_PPC64_V12, + UNW_PPC64_VS45 = UNW_PPC64_V13, + UNW_PPC64_VS46 = UNW_PPC64_V14, + UNW_PPC64_VS47 = UNW_PPC64_V15, + UNW_PPC64_VS48 = UNW_PPC64_V16, + UNW_PPC64_VS49 = UNW_PPC64_V17, + UNW_PPC64_VS50 = UNW_PPC64_V18, + UNW_PPC64_VS51 = UNW_PPC64_V19, + UNW_PPC64_VS52 = UNW_PPC64_V20, + UNW_PPC64_VS53 = UNW_PPC64_V21, + UNW_PPC64_VS54 = UNW_PPC64_V22, + UNW_PPC64_VS55 = UNW_PPC64_V23, + UNW_PPC64_VS56 = UNW_PPC64_V24, + UNW_PPC64_VS57 = UNW_PPC64_V25, + UNW_PPC64_VS58 = UNW_PPC64_V26, + UNW_PPC64_VS59 = UNW_PPC64_V27, + UNW_PPC64_VS60 = UNW_PPC64_V28, + UNW_PPC64_VS61 = UNW_PPC64_V29, + UNW_PPC64_VS62 = UNW_PPC64_V30, + UNW_PPC64_VS63 = UNW_PPC64_V31 +}; + // 64-bit ARM64 registers enum { UNW_AARCH64_X0 = 0, @@ -804,224 +804,224 @@ enum { UNW_OR1K_R29 = 29, UNW_OR1K_R30 = 30, UNW_OR1K_R31 = 31, - UNW_OR1K_EPCR = 32, -}; - -// MIPS registers -enum { - UNW_MIPS_R0 = 0, - UNW_MIPS_R1 = 1, - UNW_MIPS_R2 = 2, - UNW_MIPS_R3 = 3, - UNW_MIPS_R4 = 4, - UNW_MIPS_R5 = 5, - UNW_MIPS_R6 = 6, - UNW_MIPS_R7 = 7, - UNW_MIPS_R8 = 8, - UNW_MIPS_R9 = 9, - UNW_MIPS_R10 = 10, - UNW_MIPS_R11 = 11, - UNW_MIPS_R12 = 12, - UNW_MIPS_R13 = 13, - UNW_MIPS_R14 = 14, - UNW_MIPS_R15 = 15, - UNW_MIPS_R16 = 16, - UNW_MIPS_R17 = 17, - UNW_MIPS_R18 = 18, - UNW_MIPS_R19 = 19, - UNW_MIPS_R20 = 20, - UNW_MIPS_R21 = 21, - UNW_MIPS_R22 = 22, - UNW_MIPS_R23 = 23, - UNW_MIPS_R24 = 24, - UNW_MIPS_R25 = 25, - UNW_MIPS_R26 = 26, - UNW_MIPS_R27 = 27, - UNW_MIPS_R28 = 28, - UNW_MIPS_R29 = 29, - UNW_MIPS_R30 = 30, - UNW_MIPS_R31 = 31, - UNW_MIPS_F0 = 32, - UNW_MIPS_F1 = 33, - UNW_MIPS_F2 = 34, - UNW_MIPS_F3 = 35, - UNW_MIPS_F4 = 36, - UNW_MIPS_F5 = 37, - UNW_MIPS_F6 = 38, - UNW_MIPS_F7 = 39, - UNW_MIPS_F8 = 40, - UNW_MIPS_F9 = 41, - UNW_MIPS_F10 = 42, - UNW_MIPS_F11 = 43, - UNW_MIPS_F12 = 44, - UNW_MIPS_F13 = 45, - UNW_MIPS_F14 = 46, - UNW_MIPS_F15 = 47, - UNW_MIPS_F16 = 48, - UNW_MIPS_F17 = 49, - UNW_MIPS_F18 = 50, - UNW_MIPS_F19 = 51, - UNW_MIPS_F20 = 52, - UNW_MIPS_F21 = 53, - UNW_MIPS_F22 = 54, - UNW_MIPS_F23 = 55, - UNW_MIPS_F24 = 56, - UNW_MIPS_F25 = 57, - UNW_MIPS_F26 = 58, - UNW_MIPS_F27 = 59, - UNW_MIPS_F28 = 60, - UNW_MIPS_F29 = 61, - UNW_MIPS_F30 = 62, - UNW_MIPS_F31 = 63, - UNW_MIPS_HI = 64, - UNW_MIPS_LO = 65, -}; - -// SPARC registers -enum { - UNW_SPARC_G0 = 0, - UNW_SPARC_G1 = 1, - UNW_SPARC_G2 = 2, - UNW_SPARC_G3 = 3, - UNW_SPARC_G4 = 4, - UNW_SPARC_G5 = 5, - UNW_SPARC_G6 = 6, - UNW_SPARC_G7 = 7, - UNW_SPARC_O0 = 8, - UNW_SPARC_O1 = 9, - UNW_SPARC_O2 = 10, - UNW_SPARC_O3 = 11, - UNW_SPARC_O4 = 12, - UNW_SPARC_O5 = 13, - UNW_SPARC_O6 = 14, - UNW_SPARC_O7 = 15, - UNW_SPARC_L0 = 16, - UNW_SPARC_L1 = 17, - UNW_SPARC_L2 = 18, - UNW_SPARC_L3 = 19, - UNW_SPARC_L4 = 20, - UNW_SPARC_L5 = 21, - UNW_SPARC_L6 = 22, - UNW_SPARC_L7 = 23, - UNW_SPARC_I0 = 24, - UNW_SPARC_I1 = 25, - UNW_SPARC_I2 = 26, - UNW_SPARC_I3 = 27, - UNW_SPARC_I4 = 28, - UNW_SPARC_I5 = 29, - UNW_SPARC_I6 = 30, - UNW_SPARC_I7 = 31, -}; - -// Hexagon register numbers -enum { - UNW_HEXAGON_R0, - UNW_HEXAGON_R1, - UNW_HEXAGON_R2, - UNW_HEXAGON_R3, - UNW_HEXAGON_R4, - UNW_HEXAGON_R5, - UNW_HEXAGON_R6, - UNW_HEXAGON_R7, - UNW_HEXAGON_R8, - UNW_HEXAGON_R9, - UNW_HEXAGON_R10, - UNW_HEXAGON_R11, - UNW_HEXAGON_R12, - UNW_HEXAGON_R13, - UNW_HEXAGON_R14, - UNW_HEXAGON_R15, - UNW_HEXAGON_R16, - UNW_HEXAGON_R17, - UNW_HEXAGON_R18, - UNW_HEXAGON_R19, - UNW_HEXAGON_R20, - UNW_HEXAGON_R21, - UNW_HEXAGON_R22, - UNW_HEXAGON_R23, - UNW_HEXAGON_R24, - UNW_HEXAGON_R25, - UNW_HEXAGON_R26, - UNW_HEXAGON_R27, - UNW_HEXAGON_R28, - UNW_HEXAGON_R29, - UNW_HEXAGON_R30, - UNW_HEXAGON_R31, - UNW_HEXAGON_P3_0, - UNW_HEXAGON_PC, -}; - -// RISC-V registers. These match the DWARF register numbers defined by section -// 4 of the RISC-V ELF psABI specification, which can be found at: -// -// https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md -enum { - UNW_RISCV_X0 = 0, - UNW_RISCV_X1 = 1, - UNW_RISCV_X2 = 2, - UNW_RISCV_X3 = 3, - UNW_RISCV_X4 = 4, - UNW_RISCV_X5 = 5, - UNW_RISCV_X6 = 6, - UNW_RISCV_X7 = 7, - UNW_RISCV_X8 = 8, - UNW_RISCV_X9 = 9, - UNW_RISCV_X10 = 10, - UNW_RISCV_X11 = 11, - UNW_RISCV_X12 = 12, - UNW_RISCV_X13 = 13, - UNW_RISCV_X14 = 14, - UNW_RISCV_X15 = 15, - UNW_RISCV_X16 = 16, - UNW_RISCV_X17 = 17, - UNW_RISCV_X18 = 18, - UNW_RISCV_X19 = 19, - UNW_RISCV_X20 = 20, - UNW_RISCV_X21 = 21, - UNW_RISCV_X22 = 22, - UNW_RISCV_X23 = 23, - UNW_RISCV_X24 = 24, - UNW_RISCV_X25 = 25, - UNW_RISCV_X26 = 26, - UNW_RISCV_X27 = 27, - UNW_RISCV_X28 = 28, - UNW_RISCV_X29 = 29, - UNW_RISCV_X30 = 30, - UNW_RISCV_X31 = 31, - UNW_RISCV_F0 = 32, - UNW_RISCV_F1 = 33, - UNW_RISCV_F2 = 34, - UNW_RISCV_F3 = 35, - UNW_RISCV_F4 = 36, - UNW_RISCV_F5 = 37, - UNW_RISCV_F6 = 38, - UNW_RISCV_F7 = 39, - UNW_RISCV_F8 = 40, - UNW_RISCV_F9 = 41, - UNW_RISCV_F10 = 42, - UNW_RISCV_F11 = 43, - UNW_RISCV_F12 = 44, - UNW_RISCV_F13 = 45, - UNW_RISCV_F14 = 46, - UNW_RISCV_F15 = 47, - UNW_RISCV_F16 = 48, - UNW_RISCV_F17 = 49, - UNW_RISCV_F18 = 50, - UNW_RISCV_F19 = 51, - UNW_RISCV_F20 = 52, - UNW_RISCV_F21 = 53, - UNW_RISCV_F22 = 54, - UNW_RISCV_F23 = 55, - UNW_RISCV_F24 = 56, - UNW_RISCV_F25 = 57, - UNW_RISCV_F26 = 58, - UNW_RISCV_F27 = 59, - UNW_RISCV_F28 = 60, - UNW_RISCV_F29 = 61, - UNW_RISCV_F30 = 62, - UNW_RISCV_F31 = 63, + UNW_OR1K_EPCR = 32, }; +// MIPS registers +enum { + UNW_MIPS_R0 = 0, + UNW_MIPS_R1 = 1, + UNW_MIPS_R2 = 2, + UNW_MIPS_R3 = 3, + UNW_MIPS_R4 = 4, + UNW_MIPS_R5 = 5, + UNW_MIPS_R6 = 6, + UNW_MIPS_R7 = 7, + UNW_MIPS_R8 = 8, + UNW_MIPS_R9 = 9, + UNW_MIPS_R10 = 10, + UNW_MIPS_R11 = 11, + UNW_MIPS_R12 = 12, + UNW_MIPS_R13 = 13, + UNW_MIPS_R14 = 14, + UNW_MIPS_R15 = 15, + UNW_MIPS_R16 = 16, + UNW_MIPS_R17 = 17, + UNW_MIPS_R18 = 18, + UNW_MIPS_R19 = 19, + UNW_MIPS_R20 = 20, + UNW_MIPS_R21 = 21, + UNW_MIPS_R22 = 22, + UNW_MIPS_R23 = 23, + UNW_MIPS_R24 = 24, + UNW_MIPS_R25 = 25, + UNW_MIPS_R26 = 26, + UNW_MIPS_R27 = 27, + UNW_MIPS_R28 = 28, + UNW_MIPS_R29 = 29, + UNW_MIPS_R30 = 30, + UNW_MIPS_R31 = 31, + UNW_MIPS_F0 = 32, + UNW_MIPS_F1 = 33, + UNW_MIPS_F2 = 34, + UNW_MIPS_F3 = 35, + UNW_MIPS_F4 = 36, + UNW_MIPS_F5 = 37, + UNW_MIPS_F6 = 38, + UNW_MIPS_F7 = 39, + UNW_MIPS_F8 = 40, + UNW_MIPS_F9 = 41, + UNW_MIPS_F10 = 42, + UNW_MIPS_F11 = 43, + UNW_MIPS_F12 = 44, + UNW_MIPS_F13 = 45, + UNW_MIPS_F14 = 46, + UNW_MIPS_F15 = 47, + UNW_MIPS_F16 = 48, + UNW_MIPS_F17 = 49, + UNW_MIPS_F18 = 50, + UNW_MIPS_F19 = 51, + UNW_MIPS_F20 = 52, + UNW_MIPS_F21 = 53, + UNW_MIPS_F22 = 54, + UNW_MIPS_F23 = 55, + UNW_MIPS_F24 = 56, + UNW_MIPS_F25 = 57, + UNW_MIPS_F26 = 58, + UNW_MIPS_F27 = 59, + UNW_MIPS_F28 = 60, + UNW_MIPS_F29 = 61, + UNW_MIPS_F30 = 62, + UNW_MIPS_F31 = 63, + UNW_MIPS_HI = 64, + UNW_MIPS_LO = 65, +}; + +// SPARC registers +enum { + UNW_SPARC_G0 = 0, + UNW_SPARC_G1 = 1, + UNW_SPARC_G2 = 2, + UNW_SPARC_G3 = 3, + UNW_SPARC_G4 = 4, + UNW_SPARC_G5 = 5, + UNW_SPARC_G6 = 6, + UNW_SPARC_G7 = 7, + UNW_SPARC_O0 = 8, + UNW_SPARC_O1 = 9, + UNW_SPARC_O2 = 10, + UNW_SPARC_O3 = 11, + UNW_SPARC_O4 = 12, + UNW_SPARC_O5 = 13, + UNW_SPARC_O6 = 14, + UNW_SPARC_O7 = 15, + UNW_SPARC_L0 = 16, + UNW_SPARC_L1 = 17, + UNW_SPARC_L2 = 18, + UNW_SPARC_L3 = 19, + UNW_SPARC_L4 = 20, + UNW_SPARC_L5 = 21, + UNW_SPARC_L6 = 22, + UNW_SPARC_L7 = 23, + UNW_SPARC_I0 = 24, + UNW_SPARC_I1 = 25, + UNW_SPARC_I2 = 26, + UNW_SPARC_I3 = 27, + UNW_SPARC_I4 = 28, + UNW_SPARC_I5 = 29, + UNW_SPARC_I6 = 30, + UNW_SPARC_I7 = 31, +}; + +// Hexagon register numbers +enum { + UNW_HEXAGON_R0, + UNW_HEXAGON_R1, + UNW_HEXAGON_R2, + UNW_HEXAGON_R3, + UNW_HEXAGON_R4, + UNW_HEXAGON_R5, + UNW_HEXAGON_R6, + UNW_HEXAGON_R7, + UNW_HEXAGON_R8, + UNW_HEXAGON_R9, + UNW_HEXAGON_R10, + UNW_HEXAGON_R11, + UNW_HEXAGON_R12, + UNW_HEXAGON_R13, + UNW_HEXAGON_R14, + UNW_HEXAGON_R15, + UNW_HEXAGON_R16, + UNW_HEXAGON_R17, + UNW_HEXAGON_R18, + UNW_HEXAGON_R19, + UNW_HEXAGON_R20, + UNW_HEXAGON_R21, + UNW_HEXAGON_R22, + UNW_HEXAGON_R23, + UNW_HEXAGON_R24, + UNW_HEXAGON_R25, + UNW_HEXAGON_R26, + UNW_HEXAGON_R27, + UNW_HEXAGON_R28, + UNW_HEXAGON_R29, + UNW_HEXAGON_R30, + UNW_HEXAGON_R31, + UNW_HEXAGON_P3_0, + UNW_HEXAGON_PC, +}; + +// RISC-V registers. These match the DWARF register numbers defined by section +// 4 of the RISC-V ELF psABI specification, which can be found at: +// +// https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md +enum { + UNW_RISCV_X0 = 0, + UNW_RISCV_X1 = 1, + UNW_RISCV_X2 = 2, + UNW_RISCV_X3 = 3, + UNW_RISCV_X4 = 4, + UNW_RISCV_X5 = 5, + UNW_RISCV_X6 = 6, + UNW_RISCV_X7 = 7, + UNW_RISCV_X8 = 8, + UNW_RISCV_X9 = 9, + UNW_RISCV_X10 = 10, + UNW_RISCV_X11 = 11, + UNW_RISCV_X12 = 12, + UNW_RISCV_X13 = 13, + UNW_RISCV_X14 = 14, + UNW_RISCV_X15 = 15, + UNW_RISCV_X16 = 16, + UNW_RISCV_X17 = 17, + UNW_RISCV_X18 = 18, + UNW_RISCV_X19 = 19, + UNW_RISCV_X20 = 20, + UNW_RISCV_X21 = 21, + UNW_RISCV_X22 = 22, + UNW_RISCV_X23 = 23, + UNW_RISCV_X24 = 24, + UNW_RISCV_X25 = 25, + UNW_RISCV_X26 = 26, + UNW_RISCV_X27 = 27, + UNW_RISCV_X28 = 28, + UNW_RISCV_X29 = 29, + UNW_RISCV_X30 = 30, + UNW_RISCV_X31 = 31, + UNW_RISCV_F0 = 32, + UNW_RISCV_F1 = 33, + UNW_RISCV_F2 = 34, + UNW_RISCV_F3 = 35, + UNW_RISCV_F4 = 36, + UNW_RISCV_F5 = 37, + UNW_RISCV_F6 = 38, + UNW_RISCV_F7 = 39, + UNW_RISCV_F8 = 40, + UNW_RISCV_F9 = 41, + UNW_RISCV_F10 = 42, + UNW_RISCV_F11 = 43, + UNW_RISCV_F12 = 44, + UNW_RISCV_F13 = 45, + UNW_RISCV_F14 = 46, + UNW_RISCV_F15 = 47, + UNW_RISCV_F16 = 48, + UNW_RISCV_F17 = 49, + UNW_RISCV_F18 = 50, + UNW_RISCV_F19 = 51, + UNW_RISCV_F20 = 52, + UNW_RISCV_F21 = 53, + UNW_RISCV_F22 = 54, + UNW_RISCV_F23 = 55, + UNW_RISCV_F24 = 56, + UNW_RISCV_F25 = 57, + UNW_RISCV_F26 = 58, + UNW_RISCV_F27 = 59, + UNW_RISCV_F28 = 60, + UNW_RISCV_F29 = 61, + UNW_RISCV_F30 = 62, + UNW_RISCV_F31 = 63, +}; + // VE register numbers enum { UNW_VE_S0 = 0, diff --git a/contrib/libs/libunwind/include/mach-o/compact_unwind_encoding.h b/contrib/libs/libunwind/include/mach-o/compact_unwind_encoding.h index 68d562eec4..b40514b4b1 100644 --- a/contrib/libs/libunwind/include/mach-o/compact_unwind_encoding.h +++ b/contrib/libs/libunwind/include/mach-o/compact_unwind_encoding.h @@ -1,11 +1,11 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -// Darwin's alternative to DWARF based unwind encodings. +// Darwin's alternative to DWARF based unwind encodings. // //===----------------------------------------------------------------------===// @@ -16,7 +16,7 @@ #include <stdint.h> // -// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section +// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section // of object files. Or compilers can emit compact unwind information in // the __LD,__compact_unwind section. // @@ -25,10 +25,10 @@ // runtime to access unwind info for any given function. If the compiler // emitted compact unwind info for the function, that compact unwind info will // be encoded in the __TEXT,__unwind_info section. If the compiler emitted -// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset +// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset // of the FDE in the __TEXT,__eh_frame section in the final linked image. // -// Note: Previously, the linker would transform some DWARF unwind infos into +// Note: Previously, the linker would transform some DWARF unwind infos into // compact unwind info. But that is fragile and no longer done. @@ -57,7 +57,7 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF +// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF // ebp based: // 15-bits (5*3-bits per reg) register permutation // 8-bits for stack offset @@ -127,9 +127,9 @@ enum { // UNWIND_X86_FRAMELESS_STACK_SIZE. // UNWIND_X86_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only DWARF unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // // The permutation encoding is a Lehmer code sequence encoded into a @@ -192,7 +192,7 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF +// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF // rbp based: // 15-bits (5*3-bits per reg) register permutation // 8-bits for stack offset @@ -261,9 +261,9 @@ enum { // UNWIND_X86_64_FRAMELESS_STACK_SIZE. // UNWIND_X86_64_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only DWARF unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // @@ -274,14 +274,14 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 4=frame-based, 3=DWARF, 2=frameless +// 4-bits: 4=frame-based, 3=DWARF, 2=frameless // frameless: // 12-bits of stack size // frame-based: // 4-bits D reg pairs saved // 5-bits X reg pairs saved -// DWARF: -// 24-bits offset of DWARF FDE in __eh_frame section +// DWARF: +// 24-bits offset of DWARF FDE in __eh_frame section // enum { UNWIND_ARM64_MODE_MASK = 0x0F000000, @@ -319,9 +319,9 @@ enum { // UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK. // UNWIND_ARM64_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only DWARF unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // @@ -384,7 +384,7 @@ enum { // saved at that range of the function. // // If a particular function is so wacky that there is no compact unwind way -// to encode it, then the compiler can emit traditional DWARF unwind info. +// to encode it, then the compiler can emit traditional DWARF unwind info. // The runtime will use which ever is available. // // Runtime support for compact unwind encodings are only available on 10.6 diff --git a/contrib/libs/libunwind/include/unwind.h b/contrib/libs/libunwind/include/unwind.h index 6949e063dd..b5d04b25b5 100644 --- a/contrib/libs/libunwind/include/unwind.h +++ b/contrib/libs/libunwind/include/unwind.h @@ -1,12 +1,12 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // C++ ABI Level 1 ABI documented at: -// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html +// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html // //===----------------------------------------------------------------------===// @@ -18,11 +18,11 @@ #include <stdint.h> #include <stddef.h> -#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) && defined(_WIN32) -#include <windows.h> -#include <ntverp.h> -#endif - +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) && defined(_WIN32) +#include <windows.h> +#include <ntverp.h> +#endif + #if defined(__APPLE__) #define LIBUNWIND_UNAVAIL __attribute__ (( deprecated )) #else @@ -40,7 +40,7 @@ typedef enum { _URC_HANDLER_FOUND = 6, _URC_INSTALL_CONTEXT = 7, _URC_CONTINUE_UNWIND = 8, -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) _URC_FAILURE = 9 #endif } _Unwind_Reason_Code; @@ -55,11 +55,11 @@ typedef enum { typedef struct _Unwind_Context _Unwind_Context; // opaque -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) #include "unwind_arm_ehabi.h" -#else +#else #include "unwind_itanium.h" -#endif +#endif typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int version, @@ -141,7 +141,7 @@ extern void __deregister_frame(const void *fde); // _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has // an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind -// info" which the runtime uses in preference to DWARF unwind info. This +// info" which the runtime uses in preference to DWARF unwind info. This // function will only work if the target function has an FDE but no compact // unwind info. struct dwarf_eh_bases { @@ -154,7 +154,7 @@ extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *); // This function attempts to find the start (address of first instruction) of // a function given an address inside the function. It only works if the -// function has an FDE (DWARF unwind info). +// function has an FDE (DWARF unwind info). // This function is unimplemented on Mac OS X 10.6 and later. Instead, use // _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result. extern void *_Unwind_FindEnclosingFunction(void *pc); @@ -185,21 +185,21 @@ extern void *__deregister_frame_info(const void *fde) extern void *__deregister_frame_info_bases(const void *fde) LIBUNWIND_UNAVAIL; -#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) -#ifndef _WIN32 -typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD; -typedef struct _CONTEXT CONTEXT; -typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; -#elif !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 -typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; -#endif -// This is the common wrapper for GCC-style personality functions with SEH. -extern EXCEPTION_DISPOSITION _GCC_specific_handler(EXCEPTION_RECORD *exc, - void *frame, CONTEXT *ctx, - DISPATCHER_CONTEXT *disp, - _Unwind_Personality_Fn pers); -#endif - +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#ifndef _WIN32 +typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD; +typedef struct _CONTEXT CONTEXT; +typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; +#elif !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 +typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; +#endif +// This is the common wrapper for GCC-style personality functions with SEH. +extern EXCEPTION_DISPOSITION _GCC_specific_handler(EXCEPTION_RECORD *exc, + void *frame, CONTEXT *ctx, + DISPATCHER_CONTEXT *disp, + _Unwind_Personality_Fn pers); +#endif + #ifdef _YNDX_LIBUNWIND_ENABLE_EXCEPTION_BACKTRACE #define _YNDX_LIBUNWIND_EXCEPTION_BACKTRACE_SIZE 128 diff --git a/contrib/libs/libunwind/include/unwind_arm_ehabi.h b/contrib/libs/libunwind/include/unwind_arm_ehabi.h index 6277a1457f..06740d68ee 100644 --- a/contrib/libs/libunwind/include/unwind_arm_ehabi.h +++ b/contrib/libs/libunwind/include/unwind_arm_ehabi.h @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // C++ ABI Level 1 ABI documented at: @@ -18,7 +18,7 @@ typedef uint32_t _Unwind_State; static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0; static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1; static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2; -static const _Unwind_State _US_ACTION_MASK = 3; +static const _Unwind_State _US_ACTION_MASK = 3; /* Undocumented flag for force unwinding. */ static const _Unwind_State _US_FORCE_UNWIND = 8; @@ -62,11 +62,11 @@ struct _Unwind_Control_Block { } pr_cache; long long int :0; /* Enforce the 8-byte alignment */ -} __attribute__((__aligned__(8))); +} __attribute__((__aligned__(8))); -typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( - _Unwind_State state, _Unwind_Exception *exceptionObject, - struct _Unwind_Context *context); +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( + _Unwind_State state, _Unwind_Exception *exceptionObject, + struct _Unwind_Context *context); #ifdef __cplusplus extern "C" { diff --git a/contrib/libs/libunwind/include/unwind_itanium.h b/contrib/libs/libunwind/include/unwind_itanium.h index d94a6183be..460772df57 100644 --- a/contrib/libs/libunwind/include/unwind_itanium.h +++ b/contrib/libs/libunwind/include/unwind_itanium.h @@ -1,12 +1,12 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // C++ ABI Level 1 ABI documented at: -// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html +// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html // //===----------------------------------------------------------------------===// @@ -22,27 +22,27 @@ struct _Unwind_Exception { _Unwind_Exception_Class exception_class; void (*exception_cleanup)(_Unwind_Reason_Code reason, _Unwind_Exception *exc); -#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) - uintptr_t private_[6]; -#else +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) + uintptr_t private_[6]; +#else uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use -#endif -#if __SIZEOF_POINTER__ == 4 - // The implementation of _Unwind_Exception uses an attribute mode on the - // above fields which has the side effect of causing this whole struct to - // round up to 32 bytes in size (48 with SEH). To be more explicit, we add - // pad fields added for binary compatibility. +#endif +#if __SIZEOF_POINTER__ == 4 + // The implementation of _Unwind_Exception uses an attribute mode on the + // above fields which has the side effect of causing this whole struct to + // round up to 32 bytes in size (48 with SEH). To be more explicit, we add + // pad fields added for binary compatibility. uint32_t reserved[3]; #endif - // The Itanium ABI requires that _Unwind_Exception objects are "double-word - // aligned". GCC has interpreted this to mean "use the maximum useful - // alignment for the target"; so do we. -} __attribute__((__aligned__)); + // The Itanium ABI requires that _Unwind_Exception objects are "double-word + // aligned". GCC has interpreted this to mean "use the maximum useful + // alignment for the target"; so do we. +} __attribute__((__aligned__)); -typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( - int version, _Unwind_Action actions, uint64_t exceptionClass, - _Unwind_Exception *exceptionObject, struct _Unwind_Context *context); +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( + int version, _Unwind_Action actions, uint64_t exceptionClass, + _Unwind_Exception *exceptionObject, struct _Unwind_Context *context); #ifdef __cplusplus extern "C" { diff --git a/contrib/libs/libunwind/src/AddressSpace.hpp b/contrib/libs/libunwind/src/AddressSpace.hpp index 0c4dfeb4e6..d15d5302a7 100644 --- a/contrib/libs/libunwind/src/AddressSpace.hpp +++ b/contrib/libs/libunwind/src/AddressSpace.hpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Abstracts accessing local vs remote address spaces. @@ -17,125 +17,125 @@ #include <stdlib.h> #include <string.h> -#include "libunwind.h" -#include "config.h" -#include "dwarf2.h" -#include "EHHeaderParser.hpp" -#include "Registers.hpp" - -#ifndef _LIBUNWIND_USE_DLADDR - #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) - #define _LIBUNWIND_USE_DLADDR 1 - #else - #define _LIBUNWIND_USE_DLADDR 0 - #endif -#endif - -#if _LIBUNWIND_USE_DLADDR +#include "libunwind.h" +#include "config.h" +#include "dwarf2.h" +#include "EHHeaderParser.hpp" +#include "Registers.hpp" + +#ifndef _LIBUNWIND_USE_DLADDR + #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) + #define _LIBUNWIND_USE_DLADDR 1 + #else + #define _LIBUNWIND_USE_DLADDR 0 + #endif +#endif + +#if _LIBUNWIND_USE_DLADDR #include <dlfcn.h> -#if defined(__ELF__) && defined(_LIBUNWIND_LINK_DL_LIB) -#pragma comment(lib, "dl") -#endif -#endif - -#if defined(_LIBUNWIND_ARM_EHABI) -struct EHABIIndexEntry { - uint32_t functionOffset; - uint32_t data; -}; +#if defined(__ELF__) && defined(_LIBUNWIND_LINK_DL_LIB) +#pragma comment(lib, "dl") #endif - +#endif + +#if defined(_LIBUNWIND_ARM_EHABI) +struct EHABIIndexEntry { + uint32_t functionOffset; + uint32_t data; +}; +#endif + #ifdef __APPLE__ - struct dyld_unwind_sections - { - const struct mach_header* mh; - const void* dwarf_section; - uintptr_t dwarf_section_length; - const void* compact_unwind_section; - uintptr_t compact_unwind_section_length; - }; - - // In 10.7.0 or later, libSystem.dylib implements this function. - extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); + struct dyld_unwind_sections + { + const struct mach_header* mh; + const void* dwarf_section; + uintptr_t dwarf_section_length; + const void* compact_unwind_section; + uintptr_t compact_unwind_section_length; + }; -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) + // In 10.7.0 or later, libSystem.dylib implements this function. + extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) + // When statically linked on bare-metal, the symbols for the EH table are looked // up without going through the dynamic loader. -// The following linker script may be used to produce the necessary sections and symbols. -// Unless the --eh-frame-hdr linker option is provided, the section is not generated -// and does not take space in the output file. -// -// .eh_frame : -// { -// __eh_frame_start = .; -// KEEP(*(.eh_frame)) -// __eh_frame_end = .; -// } -// -// .eh_frame_hdr : -// { -// KEEP(*(.eh_frame_hdr)) -// } -// -// __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; -// __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; - -extern char __eh_frame_start; -extern char __eh_frame_end; - -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) -extern char __eh_frame_hdr_start; -extern char __eh_frame_hdr_end; -#endif - -#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) - -// When statically linked on bare-metal, the symbols for the EH table are looked -// up without going through the dynamic loader. -extern char __exidx_start; -extern char __exidx_end; - -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) - -#include <windows.h> -#include <psapi.h> - -#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) || \ - defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX) - -#include <link.h> - +// The following linker script may be used to produce the necessary sections and symbols. +// Unless the --eh-frame-hdr linker option is provided, the section is not generated +// and does not take space in the output file. +// +// .eh_frame : +// { +// __eh_frame_start = .; +// KEEP(*(.eh_frame)) +// __eh_frame_end = .; +// } +// +// .eh_frame_hdr : +// { +// KEEP(*(.eh_frame_hdr)) +// } +// +// __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; +// __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; + +extern char __eh_frame_start; +extern char __eh_frame_end; + +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) +extern char __eh_frame_hdr_start; +extern char __eh_frame_hdr_end; +#endif + +#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) + +// When statically linked on bare-metal, the symbols for the EH table are looked +// up without going through the dynamic loader. +extern char __exidx_start; +extern char __exidx_end; + +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) + +#include <windows.h> +#include <psapi.h> + +#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) || \ + defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX) + +#include <link.h> + #endif namespace libunwind { /// Used by findUnwindSections() to return info about needed sections. struct UnwindInfoSections { -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || \ - defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \ - defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) - // No dso_base for SEH. +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || \ + defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \ + defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) + // No dso_base for SEH. uintptr_t dso_base; #endif -#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) +#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) size_t text_segment_length; -#endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) uintptr_t dwarf_section; size_t dwarf_section_length; #endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) uintptr_t dwarf_index_section; size_t dwarf_index_section_length; #endif -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) uintptr_t compact_unwind_section; size_t compact_unwind_section_length; #endif -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) uintptr_t arm_section; size_t arm_section_length; #endif @@ -145,10 +145,10 @@ struct UnwindInfoSections { /// LocalAddressSpace is used as a template parameter to UnwindCursor when /// unwinding a thread in the same process. The wrappers compile away, /// making local unwinds fast. -class _LIBUNWIND_HIDDEN LocalAddressSpace { +class _LIBUNWIND_HIDDEN LocalAddressSpace { public: - typedef uintptr_t pint_t; - typedef intptr_t sint_t; + typedef uintptr_t pint_t; + typedef intptr_t sint_t; uint8_t get8(pint_t addr) { uint8_t val; memcpy(&val, (void *)addr, sizeof(val)); @@ -180,7 +180,7 @@ public: return val; } uintptr_t getP(pint_t addr); - uint64_t getRegister(pint_t addr); + uint64_t getRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -195,21 +195,21 @@ public: }; inline uintptr_t LocalAddressSpace::getP(pint_t addr) { -#if __SIZEOF_POINTER__ == 8 - return get64(addr); -#else - return get32(addr); -#endif -} - -inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { -#if __SIZEOF_POINTER__ == 8 || defined(__mips64) +#if __SIZEOF_POINTER__ == 8 return get64(addr); #else return get32(addr); #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if __SIZEOF_POINTER__ == 8 || defined(__mips64) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -246,11 +246,11 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { if (p == pend) _LIBUNWIND_ABORT("truncated sleb128 expression"); byte = *p++; - result |= (uint64_t)(byte & 0x7f) << bit; + result |= (uint64_t)(byte & 0x7f) << bit; bit += 7; } while (byte & 0x80); // sign extend negative numbers - if ((byte & 0x40) != 0 && bit < 64) + if ((byte & 0x40) != 0 && bit < 64) result |= (-1ULL) << bit; addr = (pint_t) p; return result; @@ -348,163 +348,163 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, return result; } -#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) - -// The ElfW() macro for pointer-size independent ELF header traversal is not -// provided by <link.h> on some systems (e.g., FreeBSD). On these systems the -// data structures are just called Elf_XXX. Define ElfW() locally. -#if !defined(ElfW) - #define ElfW(type) Elf_##type -#endif -#if !defined(Elf_Half) - typedef ElfW(Half) Elf_Half; -#endif -#if !defined(Elf_Phdr) - typedef ElfW(Phdr) Elf_Phdr; -#endif -#if !defined(Elf_Addr) - typedef ElfW(Addr) Elf_Addr; -#endif - -static Elf_Addr calculateImageBase(struct dl_phdr_info *pinfo) { - Elf_Addr image_base = pinfo->dlpi_addr; -#if defined(__ANDROID__) && __ANDROID_API__ < 18 - if (image_base == 0) { - // Normally, an image base of 0 indicates a non-PIE executable. On - // versions of Android prior to API 18, the dynamic linker reported a - // dlpi_addr of 0 for PIE executables. Compute the true image base - // using the PT_PHDR segment. - // See https://github.com/android/ndk/issues/505. - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_PHDR) { - image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) - - phdr->p_vaddr; - break; - } - } - } -#endif - return image_base; -} - -struct _LIBUNWIND_HIDDEN dl_iterate_cb_data { - LocalAddressSpace *addressSpace; - UnwindInfoSections *sects; - uintptr_t targetAddr; -}; - -#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) -#include "FrameHeaderCache.hpp" - -// Typically there is one cache per process, but when libunwind is built as a -// hermetic static library, then each shared object may have its own cache. -static FrameHeaderCache TheFrameHeaderCache; -#endif - -static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base, - dl_iterate_cb_data *cbdata) { - if (phdr->p_type == PT_LOAD) { - uintptr_t begin = image_base + phdr->p_vaddr; - uintptr_t end = begin + phdr->p_memsz; - if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { - cbdata->sects->dso_base = begin; - cbdata->sects->text_segment_length = phdr->p_memsz; - return true; - } - } - return false; -} - -static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base, - dl_iterate_cb_data *cbdata) { -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - if (phdr->p_type == PT_GNU_EH_FRAME) { - EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo; - uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr; - cbdata->sects->dwarf_index_section = eh_frame_hdr_start; - cbdata->sects->dwarf_index_section_length = phdr->p_memsz; - if (EHHeaderParser<LocalAddressSpace>::decodeEHHdr( - *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, - hdrInfo)) { - // .eh_frame_hdr records the start of .eh_frame, but not its size. - // Rely on a zero terminator to find the end of the section. - cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; +#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) + +// The ElfW() macro for pointer-size independent ELF header traversal is not +// provided by <link.h> on some systems (e.g., FreeBSD). On these systems the +// data structures are just called Elf_XXX. Define ElfW() locally. +#if !defined(ElfW) + #define ElfW(type) Elf_##type +#endif +#if !defined(Elf_Half) + typedef ElfW(Half) Elf_Half; +#endif +#if !defined(Elf_Phdr) + typedef ElfW(Phdr) Elf_Phdr; +#endif +#if !defined(Elf_Addr) + typedef ElfW(Addr) Elf_Addr; +#endif + +static Elf_Addr calculateImageBase(struct dl_phdr_info *pinfo) { + Elf_Addr image_base = pinfo->dlpi_addr; +#if defined(__ANDROID__) && __ANDROID_API__ < 18 + if (image_base == 0) { + // Normally, an image base of 0 indicates a non-PIE executable. On + // versions of Android prior to API 18, the dynamic linker reported a + // dlpi_addr of 0 for PIE executables. Compute the true image base + // using the PT_PHDR segment. + // See https://github.com/android/ndk/issues/505. + for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { + const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; + if (phdr->p_type == PT_PHDR) { + image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) - + phdr->p_vaddr; + break; + } + } + } +#endif + return image_base; +} + +struct _LIBUNWIND_HIDDEN dl_iterate_cb_data { + LocalAddressSpace *addressSpace; + UnwindInfoSections *sects; + uintptr_t targetAddr; +}; + +#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) +#include "FrameHeaderCache.hpp" + +// Typically there is one cache per process, but when libunwind is built as a +// hermetic static library, then each shared object may have its own cache. +static FrameHeaderCache TheFrameHeaderCache; +#endif + +static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base, + dl_iterate_cb_data *cbdata) { + if (phdr->p_type == PT_LOAD) { + uintptr_t begin = image_base + phdr->p_vaddr; + uintptr_t end = begin + phdr->p_memsz; + if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { + cbdata->sects->dso_base = begin; + cbdata->sects->text_segment_length = phdr->p_memsz; + return true; + } + } + return false; +} + +static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base, + dl_iterate_cb_data *cbdata) { +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + if (phdr->p_type == PT_GNU_EH_FRAME) { + EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo; + uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr; + cbdata->sects->dwarf_index_section = eh_frame_hdr_start; + cbdata->sects->dwarf_index_section_length = phdr->p_memsz; + if (EHHeaderParser<LocalAddressSpace>::decodeEHHdr( + *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, + hdrInfo)) { + // .eh_frame_hdr records the start of .eh_frame, but not its size. + // Rely on a zero terminator to find the end of the section. + cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; cbdata->sects->dwarf_section_length = SIZE_MAX; - return true; - } - } - return false; -#elif defined(_LIBUNWIND_ARM_EHABI) - if (phdr->p_type == PT_ARM_EXIDX) { - uintptr_t exidx_start = image_base + phdr->p_vaddr; - cbdata->sects->arm_section = exidx_start; - cbdata->sects->arm_section_length = phdr->p_memsz; - return true; - } - return false; -#else -#error Need one of _LIBUNWIND_SUPPORT_DWARF_INDEX or _LIBUNWIND_ARM_EHABI -#endif -} - -static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, - size_t pinfo_size, void *data) { - auto cbdata = static_cast<dl_iterate_cb_data *>(data); - if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr) - return 0; -#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) - if (TheFrameHeaderCache.find(pinfo, pinfo_size, data)) - return 1; -#else - // Avoid warning about unused variable. - (void)pinfo_size; -#endif - - Elf_Addr image_base = calculateImageBase(pinfo); - - // Most shared objects seen in this callback function likely don't contain the - // target address, so optimize for that. Scan for a matching PT_LOAD segment - // first and bail when it isn't found. - bool found_text = false; - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; ++i) { - if (checkAddrInSegment(&pinfo->dlpi_phdr[i], image_base, cbdata)) { - found_text = true; - break; - } - } - if (!found_text) - return 0; - - // PT_GNU_EH_FRAME and PT_ARM_EXIDX are usually near the end. Iterate - // backward. - bool found_unwind = false; - for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1]; - if (checkForUnwindInfoSegment(phdr, image_base, cbdata)) { - found_unwind = true; - break; - } - } - if (!found_unwind) - return 0; - -#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) - TheFrameHeaderCache.add(cbdata->sects); -#endif - return 1; -} - -#endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) - - + return true; + } + } + return false; +#elif defined(_LIBUNWIND_ARM_EHABI) + if (phdr->p_type == PT_ARM_EXIDX) { + uintptr_t exidx_start = image_base + phdr->p_vaddr; + cbdata->sects->arm_section = exidx_start; + cbdata->sects->arm_section_length = phdr->p_memsz; + return true; + } + return false; +#else +#error Need one of _LIBUNWIND_SUPPORT_DWARF_INDEX or _LIBUNWIND_ARM_EHABI +#endif +} + +static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, + size_t pinfo_size, void *data) { + auto cbdata = static_cast<dl_iterate_cb_data *>(data); + if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr) + return 0; +#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) + if (TheFrameHeaderCache.find(pinfo, pinfo_size, data)) + return 1; +#else + // Avoid warning about unused variable. + (void)pinfo_size; +#endif + + Elf_Addr image_base = calculateImageBase(pinfo); + + // Most shared objects seen in this callback function likely don't contain the + // target address, so optimize for that. Scan for a matching PT_LOAD segment + // first and bail when it isn't found. + bool found_text = false; + for (Elf_Half i = 0; i < pinfo->dlpi_phnum; ++i) { + if (checkAddrInSegment(&pinfo->dlpi_phdr[i], image_base, cbdata)) { + found_text = true; + break; + } + } + if (!found_text) + return 0; + + // PT_GNU_EH_FRAME and PT_ARM_EXIDX are usually near the end. Iterate + // backward. + bool found_unwind = false; + for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) { + const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1]; + if (checkForUnwindInfoSegment(phdr, image_base, cbdata)) { + found_unwind = true; + break; + } + } + if (!found_unwind) + return 0; + +#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE) + TheFrameHeaderCache.add(cbdata->sects); +#endif + return 1; +} + +#endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) + + inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, UnwindInfoSections &info) { #ifdef __APPLE__ dyld_unwind_sections dyldInfo; if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { info.dso_base = (uintptr_t)dyldInfo.mh; - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; info.dwarf_section_length = (size_t)dyldInfo.dwarf_section_length; #endif @@ -512,84 +512,84 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; return true; } -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) - info.dso_base = 0; +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) + info.dso_base = 0; // Bare metal is statically linked, so no need to ask the dynamic loader info.dwarf_section_length = (size_t)(&__eh_frame_end - &__eh_frame_start); - info.dwarf_section = (uintptr_t)(&__eh_frame_start); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", - (void *)info.dwarf_section, (void *)info.dwarf_section_length); -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - info.dwarf_index_section = (uintptr_t)(&__eh_frame_hdr_start); + info.dwarf_section = (uintptr_t)(&__eh_frame_start); + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", + (void *)info.dwarf_section, (void *)info.dwarf_section_length); +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + info.dwarf_index_section = (uintptr_t)(&__eh_frame_hdr_start); info.dwarf_index_section_length = (size_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p", - (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length); -#endif - if (info.dwarf_section_length) - return true; -#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) - // Bare metal is statically linked, so no need to ask the dynamic loader + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p", + (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length); +#endif + if (info.dwarf_section_length) + return true; +#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) + // Bare metal is statically linked, so no need to ask the dynamic loader info.arm_section = (uintptr_t)(&__exidx_start); info.arm_section_length = (size_t)(&__exidx_end - &__exidx_start); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", - (void *)info.arm_section, (void *)info.arm_section_length); - if (info.arm_section && info.arm_section_length) - return true; -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) - HMODULE mods[1024]; - HANDLE process = GetCurrentProcess(); - DWORD needed; - - if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) { - DWORD err = GetLastError(); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, " - "returned error %d", (int)err); - return false; - } - - for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) { - PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i]; - PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((BYTE *)pidh + pidh->e_lfanew); - PIMAGE_FILE_HEADER pifh = (PIMAGE_FILE_HEADER)&pinh->FileHeader; - PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(pinh); - bool found_obj = false; - bool found_hdr = false; - - info.dso_base = (uintptr_t)mods[i]; - for (unsigned j = 0; j < pifh->NumberOfSections; j++, pish++) { - uintptr_t begin = pish->VirtualAddress + (uintptr_t)mods[i]; - uintptr_t end = begin + pish->Misc.VirtualSize; - if (!strncmp((const char *)pish->Name, ".text", - IMAGE_SIZEOF_SHORT_NAME)) { - if (targetAddr >= begin && targetAddr < end) - found_obj = true; - } else if (!strncmp((const char *)pish->Name, ".eh_frame", - IMAGE_SIZEOF_SHORT_NAME)) { - info.dwarf_section = begin; - info.dwarf_section_length = pish->Misc.VirtualSize; - found_hdr = true; - } - if (found_obj && found_hdr) - return true; - } - } - return false; -#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32) - // Don't even bother, since Windows has functions that do all this stuff - // for us. - (void)targetAddr; - (void)info; - return true; -#elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX) + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", + (void *)info.arm_section, (void *)info.arm_section_length); + if (info.arm_section && info.arm_section_length) + return true; +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) + HMODULE mods[1024]; + HANDLE process = GetCurrentProcess(); + DWORD needed; + + if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) { + DWORD err = GetLastError(); + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, " + "returned error %d", (int)err); + return false; + } + + for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) { + PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i]; + PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((BYTE *)pidh + pidh->e_lfanew); + PIMAGE_FILE_HEADER pifh = (PIMAGE_FILE_HEADER)&pinh->FileHeader; + PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(pinh); + bool found_obj = false; + bool found_hdr = false; + + info.dso_base = (uintptr_t)mods[i]; + for (unsigned j = 0; j < pifh->NumberOfSections; j++, pish++) { + uintptr_t begin = pish->VirtualAddress + (uintptr_t)mods[i]; + uintptr_t end = begin + pish->Misc.VirtualSize; + if (!strncmp((const char *)pish->Name, ".text", + IMAGE_SIZEOF_SHORT_NAME)) { + if (targetAddr >= begin && targetAddr < end) + found_obj = true; + } else if (!strncmp((const char *)pish->Name, ".eh_frame", + IMAGE_SIZEOF_SHORT_NAME)) { + info.dwarf_section = begin; + info.dwarf_section_length = pish->Misc.VirtualSize; + found_hdr = true; + } + if (found_obj && found_hdr) + return true; + } + } + return false; +#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32) + // Don't even bother, since Windows has functions that do all this stuff + // for us. + (void)targetAddr; + (void)info; + return true; +#elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX) int length = 0; - info.arm_section = - (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length); + info.arm_section = + (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length); info.arm_section_length = (size_t)length * sizeof(EHABIIndexEntry); if (info.arm_section && info.arm_section_length) return true; -#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) +#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) dl_iterate_cb_data cb_data = {this, &info, targetAddr}; - int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data); + int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data); return static_cast<bool>(found); #endif @@ -607,7 +607,7 @@ inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, size_t bufLen, unw_word_t *offset) { -#if _LIBUNWIND_USE_DLADDR +#if _LIBUNWIND_USE_DLADDR Dl_info dyldInfo; if (dladdr((void *)addr, &dyldInfo)) { if (dyldInfo.dli_sname != NULL) { @@ -616,11 +616,11 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, return true; } } -#else - (void)addr; - (void)buf; - (void)bufLen; - (void)offset; +#else + (void)addr; + (void)buf; + (void)bufLen; + (void)offset; #endif return false; } diff --git a/contrib/libs/libunwind/src/CompactUnwinder.hpp b/contrib/libs/libunwind/src/CompactUnwinder.hpp index 0b2b5e111b..d387f81a51 100644 --- a/contrib/libs/libunwind/src/CompactUnwinder.hpp +++ b/contrib/libs/libunwind/src/CompactUnwinder.hpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Does runtime stack unwinding using compact unwind encodings. @@ -25,7 +25,7 @@ namespace libunwind { -#if defined(_LIBUNWIND_TARGET_I386) +#if defined(_LIBUNWIND_TARGET_I386) /// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_x86 register set template <typename A> @@ -103,7 +103,7 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingEBPFrame( default: (void)functionStart; _LIBUNWIND_DEBUG_LOG("bad register for EBP frame, encoding=%08X for " - "function starting at 0x%X", + "function starting at 0x%X", compactEncoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -222,7 +222,7 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingFrameless( break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%X", + "function starting at 0x%X", encoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -254,10 +254,10 @@ void CompactUnwinder_x86<A>::framelessUnwind( // old esp is before return address registers.setSP((uint32_t)returnAddressLocation + 4); } -#endif // _LIBUNWIND_TARGET_I386 +#endif // _LIBUNWIND_TARGET_I386 -#if defined(_LIBUNWIND_TARGET_X86_64) +#if defined(_LIBUNWIND_TARGET_X86_64) /// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_x86_64 register set template <typename A> @@ -334,7 +334,7 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame( default: (void)functionStart; _LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for " - "function starting at 0x%llX", + "function starting at 0x%llX", compactEncoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -453,7 +453,7 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless( break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%llX", + "function starting at 0x%llX", encoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -485,11 +485,11 @@ void CompactUnwinder_x86_64<A>::framelessUnwind(A &addressSpace, // old esp is before return address registers.setSP(returnAddressLocation + 8); } -#endif // _LIBUNWIND_TARGET_X86_64 +#endif // _LIBUNWIND_TARGET_X86_64 -#if defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_TARGET_AARCH64) /// CompactUnwinder_arm64 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_arm64 register set template <typename A> @@ -689,7 +689,7 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame( return UNW_STEP_SUCCESS; } -#endif // _LIBUNWIND_TARGET_AARCH64 +#endif // _LIBUNWIND_TARGET_AARCH64 } // namespace libunwind diff --git a/contrib/libs/libunwind/src/DwarfInstructions.hpp b/contrib/libs/libunwind/src/DwarfInstructions.hpp index c1a241c55c..6b3c93a849 100644 --- a/contrib/libs/libunwind/src/DwarfInstructions.hpp +++ b/contrib/libs/libunwind/src/DwarfInstructions.hpp @@ -1,11 +1,11 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -// Processor specific interpretation of DWARF unwind info. +// Processor specific interpretation of DWARF unwind info. // //===----------------------------------------------------------------------===// @@ -25,7 +25,7 @@ namespace libunwind { -/// DwarfInstructions maps abtract DWARF unwind instructions to a particular +/// DwarfInstructions maps abtract DWARF unwind instructions to a particular /// architecture template <typename A, typename R> class DwarfInstructions { @@ -34,7 +34,7 @@ public: typedef typename A::sint_t sint_t; static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart, - R ®isters, bool &isSignalFrame); + R ®isters, bool &isSignalFrame); private: @@ -63,8 +63,8 @@ private: static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, const R ®isters) { - if (prolog.cfaRegister != 0) - return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + + if (prolog.cfaRegister != 0) + return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + prolog.cfaRegisterOffset); if (prolog.cfaExpression != 0) return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, @@ -88,15 +88,15 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser<A>::kRegisterInCFA: - return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); + return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser<A>::kRegisterInCFADecrypt: // sparc64 specific return addressSpace.getP(cfa + (pint_t)savedReg.value) ^ getSparcWCookie(registers, 0); case CFI_Parser<A>::kRegisterAtExpression: - return (pint_t)addressSpace.getRegister(evaluateExpression( - (pint_t)savedReg.value, addressSpace, registers, cfa)); + return (pint_t)addressSpace.getRegister(evaluateExpression( + (pint_t)savedReg.value, addressSpace, registers, cfa)); case CFI_Parser<A>::kRegisterIsExpression: return evaluateExpression((pint_t)savedReg.value, addressSpace, @@ -104,8 +104,8 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( case CFI_Parser<A>::kRegisterInRegister: return registers.getRegister((int)savedReg.value); - case CFI_Parser<A>::kRegisterUndefined: - return 0; + case CFI_Parser<A>::kRegisterUndefined: + return 0; case CFI_Parser<A>::kRegisterUnused: case CFI_Parser<A>::kRegisterOffsetFromCFA: // FIX ME @@ -157,7 +157,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister( case CFI_Parser<A>::kRegisterIsExpression: case CFI_Parser<A>::kRegisterUnused: - case CFI_Parser<A>::kRegisterUndefined: + case CFI_Parser<A>::kRegisterUndefined: case CFI_Parser<A>::kRegisterOffsetFromCFA: case CFI_Parser<A>::kRegisterInRegister: case CFI_Parser<A>::kRegisterInCFADecrypt: @@ -169,19 +169,19 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister( template <typename A, typename R> int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, - pint_t fdeStart, R ®isters, - bool &isSignalFrame) { + pint_t fdeStart, R ®isters, + bool &isSignalFrame) { FDE_Info fdeInfo; CIE_Info cieInfo; if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo) == NULL) { PrologInfo prolog; if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, - R::getArch(), &prolog)) { + R::getArch(), &prolog)) { // get pointer to cfa (architecture specific) pint_t cfa = getCFA(addressSpace, prolog, registers); - // restore registers that DWARF says were saved + // restore registers that DWARF says were saved R newRegisters = registers; // Typically, the CFA is the stack pointer at the call site in @@ -195,7 +195,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, pint_t returnAddress = 0; const int lastReg = R::lastDwarfRegNum(); - assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && + assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && "register range too large"); assert(lastReg >= (int)cieInfo.returnAddressRegister && "register range does not contain return address register"); @@ -219,42 +219,42 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, prolog.savedRegisters[i])); else return UNW_EBADREG; - } else if (i == (int)cieInfo.returnAddressRegister) { - // Leaf function keeps the return address in register and there is no - // explicit intructions how to restore it. - returnAddress = registers.getRegister(cieInfo.returnAddressRegister); + } else if (i == (int)cieInfo.returnAddressRegister) { + // Leaf function keeps the return address in register and there is no + // explicit intructions how to restore it. + returnAddress = registers.getRegister(cieInfo.returnAddressRegister); } } - isSignalFrame = cieInfo.isSignalFrame; - -#if defined(_LIBUNWIND_TARGET_AARCH64) - // If the target is aarch64 then the return address may have been signed - // using the v8.3 pointer authentication extensions. The original - // return address needs to be authenticated before the return address is - // restored. autia1716 is used instead of autia as autia1716 assembles - // to a NOP on pre-v8.3a architectures. - if ((R::getArch() == REGISTERS_ARM64) && + isSignalFrame = cieInfo.isSignalFrame; + +#if defined(_LIBUNWIND_TARGET_AARCH64) + // If the target is aarch64 then the return address may have been signed + // using the v8.3 pointer authentication extensions. The original + // return address needs to be authenticated before the return address is + // restored. autia1716 is used instead of autia as autia1716 assembles + // to a NOP on pre-v8.3a architectures. + if ((R::getArch() == REGISTERS_ARM64) && prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value && returnAddress != 0) { -#if !defined(_LIBUNWIND_IS_NATIVE_ONLY) - return UNW_ECROSSRASIGNING; -#else - register unsigned long long x17 __asm("x17") = returnAddress; - register unsigned long long x16 __asm("x16") = cfa; - - // These are the autia1716/autib1716 instructions. The hint instructions - // are used here as gcc does not assemble autia1716/autib1716 for pre - // armv8.3a targets. - if (cieInfo.addressesSignedWithBKey) - asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716 - else - asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716 - returnAddress = x17; -#endif - } -#endif - +#if !defined(_LIBUNWIND_IS_NATIVE_ONLY) + return UNW_ECROSSRASIGNING; +#else + register unsigned long long x17 __asm("x17") = returnAddress; + register unsigned long long x16 __asm("x16") = cfa; + + // These are the autia1716/autib1716 instructions. The hint instructions + // are used here as gcc does not assemble autia1716/autib1716 for pre + // armv8.3a targets. + if (cieInfo.addressesSignedWithBKey) + asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716 + else + asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716 + returnAddress = x17; +#endif + } +#endif + #if defined(_LIBUNWIND_IS_NATIVE_ONLY) && defined(_LIBUNWIND_TARGET_ARM) && \ defined(__ARM_FEATURE_PAUTH) if ((R::getArch() == REGISTERS_ARM) && @@ -269,47 +269,47 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, } #endif -#if defined(_LIBUNWIND_TARGET_SPARC) - if (R::getArch() == REGISTERS_SPARC) { - // Skip call site instruction and delay slot - returnAddress += 8; - // Skip unimp instruction if function returns a struct - if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0) - returnAddress += 4; - } -#endif - +#if defined(_LIBUNWIND_TARGET_SPARC) + if (R::getArch() == REGISTERS_SPARC) { + // Skip call site instruction and delay slot + returnAddress += 8; + // Skip unimp instruction if function returns a struct + if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0) + returnAddress += 4; + } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC64) // Skip call site instruction and delay slot. if (R::getArch() == REGISTERS_SPARC64) returnAddress += 8; #endif -#if defined(_LIBUNWIND_TARGET_PPC64) -#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) -#define PPC64_ELFV1_R2_OFFSET 40 -#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) -#define PPC64_ELFV2_R2_OFFSET 24 - // If the instruction at return address is a TOC (r2) restore, - // then r2 was saved and needs to be restored. - // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, - // while in ELFv1 ABI it is saved at SP + 40. - if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { - pint_t sp = newRegisters.getRegister(UNW_REG_SP); - pint_t r2 = 0; - switch (addressSpace.get32(returnAddress)) { - case PPC64_ELFV1_R2_LOAD_INST_ENCODING: - r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); - break; - case PPC64_ELFV2_R2_LOAD_INST_ENCODING: - r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); - break; - } - if (r2) - newRegisters.setRegister(UNW_PPC64_R2, r2); - } -#endif - +#if defined(_LIBUNWIND_TARGET_PPC64) +#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) +#define PPC64_ELFV1_R2_OFFSET 40 +#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) +#define PPC64_ELFV2_R2_OFFSET 24 + // If the instruction at return address is a TOC (r2) restore, + // then r2 was saved and needs to be restored. + // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, + // while in ELFv1 ABI it is saved at SP + 40. + if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { + pint_t sp = newRegisters.getRegister(UNW_REG_SP); + pint_t r2 = 0; + switch (addressSpace.get32(returnAddress)) { + case PPC64_ELFV1_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); + break; + case PPC64_ELFV2_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); + break; + } + if (r2) + newRegisters.setRegister(UNW_PPC64_R2, r2); + } +#endif + // Return address is address after call site instruction, so setting IP to // that does simualates a return. newRegisters.setIP(returnAddress); @@ -483,7 +483,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, // pick from reg = addressSpace.get8(p); p += 1; - value = sp[-(int)reg]; + value = sp[-(int)reg]; *(++sp) = value; if (log) fprintf(stderr, "duplicate %d in stack\n", reg); @@ -591,7 +591,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, case DW_OP_plus_uconst: // pop stack, add uelb128 constant, push result - *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd)); + *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd)); if (log) fprintf(stderr, "add constant\n"); break; @@ -855,7 +855,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, case DW_OP_call4: case DW_OP_call_ref: default: - _LIBUNWIND_ABORT("DWARF opcode not implemented"); + _LIBUNWIND_ABORT("DWARF opcode not implemented"); } } diff --git a/contrib/libs/libunwind/src/DwarfParser.hpp b/contrib/libs/libunwind/src/DwarfParser.hpp index b5a53166fc..932297eea6 100644 --- a/contrib/libs/libunwind/src/DwarfParser.hpp +++ b/contrib/libs/libunwind/src/DwarfParser.hpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Parses DWARF CFIs (FDEs and CIEs). @@ -19,14 +19,14 @@ #include "libunwind.h" #include "dwarf2.h" -#include "Registers.hpp" +#include "Registers.hpp" -#include "config.h" +#include "config.h" namespace libunwind { - + /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. -/// See DWARF Spec for details: +/// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html /// template <typename A> @@ -49,9 +49,9 @@ public: bool isSignalFrame; bool fdesHaveAugmentationData; uint8_t returnAddressRegister; -#if defined(_LIBUNWIND_TARGET_AARCH64) - bool addressesSignedWithBKey; -#endif +#if defined(_LIBUNWIND_TARGET_AARCH64) + bool addressesSignedWithBKey; +#endif }; /// Information about an FDE (Frame Description Entry) @@ -65,11 +65,11 @@ public: }; enum { - kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER + kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER }; enum RegisterSavedWhere { kRegisterUnused, - kRegisterUndefined, + kRegisterUndefined, kRegisterInCFA, kRegisterInCFADecrypt, // sparc64 specific kRegisterOffsetFromCFA, @@ -79,51 +79,51 @@ public: }; struct RegisterLocation { RegisterSavedWhere location; - bool initialStateSaved; + bool initialStateSaved; int64_t value; }; /// Information about a frame layout and registers saved determined - /// by "running" the DWARF FDE "instructions" + /// by "running" the DWARF FDE "instructions" struct PrologInfo { uint32_t cfaRegister; int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset int64_t cfaExpression; // CFA = expression uint32_t spExtraArgSize; - RegisterLocation savedRegisters[kMaxRegisterNumber + 1]; - enum class InitializeTime { kLazy, kNormal }; - - // When saving registers, this data structure is lazily initialized. - PrologInfo(InitializeTime IT = InitializeTime::kNormal) { - if (IT == InitializeTime::kNormal) - memset(this, 0, sizeof(*this)); - } - void checkSaveRegister(uint64_t reg, PrologInfo &initialState) { - if (!savedRegisters[reg].initialStateSaved) { - initialState.savedRegisters[reg] = savedRegisters[reg]; - savedRegisters[reg].initialStateSaved = true; - } - } - void setRegister(uint64_t reg, RegisterSavedWhere newLocation, - int64_t newValue, PrologInfo &initialState) { - checkSaveRegister(reg, initialState); - savedRegisters[reg].location = newLocation; - savedRegisters[reg].value = newValue; - } - void setRegisterLocation(uint64_t reg, RegisterSavedWhere newLocation, - PrologInfo &initialState) { - checkSaveRegister(reg, initialState); - savedRegisters[reg].location = newLocation; - } - void setRegisterValue(uint64_t reg, int64_t newValue, - PrologInfo &initialState) { - checkSaveRegister(reg, initialState); - savedRegisters[reg].value = newValue; - } - void restoreRegisterToInitialState(uint64_t reg, PrologInfo &initialState) { - if (savedRegisters[reg].initialStateSaved) - savedRegisters[reg] = initialState.savedRegisters[reg]; - // else the register still holds its initial state - } + RegisterLocation savedRegisters[kMaxRegisterNumber + 1]; + enum class InitializeTime { kLazy, kNormal }; + + // When saving registers, this data structure is lazily initialized. + PrologInfo(InitializeTime IT = InitializeTime::kNormal) { + if (IT == InitializeTime::kNormal) + memset(this, 0, sizeof(*this)); + } + void checkSaveRegister(uint64_t reg, PrologInfo &initialState) { + if (!savedRegisters[reg].initialStateSaved) { + initialState.savedRegisters[reg] = savedRegisters[reg]; + savedRegisters[reg].initialStateSaved = true; + } + } + void setRegister(uint64_t reg, RegisterSavedWhere newLocation, + int64_t newValue, PrologInfo &initialState) { + checkSaveRegister(reg, initialState); + savedRegisters[reg].location = newLocation; + savedRegisters[reg].value = newValue; + } + void setRegisterLocation(uint64_t reg, RegisterSavedWhere newLocation, + PrologInfo &initialState) { + checkSaveRegister(reg, initialState); + savedRegisters[reg].location = newLocation; + } + void setRegisterValue(uint64_t reg, int64_t newValue, + PrologInfo &initialState) { + checkSaveRegister(reg, initialState); + savedRegisters[reg].value = newValue; + } + void restoreRegisterToInitialState(uint64_t reg, PrologInfo &initialState) { + if (savedRegisters[reg].initialStateSaved) + savedRegisters[reg] = initialState.savedRegisters[reg]; + // else the register still holds its initial state + } }; struct PrologInfoStackEntry { @@ -133,24 +133,24 @@ public: PrologInfo info; }; - struct RememberStack { - PrologInfoStackEntry *entry; - RememberStack() : entry(nullptr) {} - ~RememberStack() { -#if defined(_LIBUNWIND_REMEMBER_CLEANUP_NEEDED) - // Clean up rememberStack. Even in the case where every - // DW_CFA_remember_state is paired with a DW_CFA_restore_state, - // parseInstructions can skip restore opcodes if it reaches the target PC - // and stops interpreting, so we have to make sure we don't leak memory. - while (entry) { - PrologInfoStackEntry *next = entry->next; - _LIBUNWIND_REMEMBER_FREE(entry); - entry = next; - } -#endif - } - }; - + struct RememberStack { + PrologInfoStackEntry *entry; + RememberStack() : entry(nullptr) {} + ~RememberStack() { +#if defined(_LIBUNWIND_REMEMBER_CLEANUP_NEEDED) + // Clean up rememberStack. Even in the case where every + // DW_CFA_remember_state is paired with a DW_CFA_restore_state, + // parseInstructions can skip restore opcodes if it reaches the target PC + // and stops interpreting, so we have to make sure we don't leak memory. + while (entry) { + PrologInfoStackEntry *next = entry->next; + _LIBUNWIND_REMEMBER_FREE(entry); + entry = next; + } +#endif + } + }; + static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo); @@ -159,7 +159,7 @@ public: bool useCIEInfo = false); static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo, const CIE_Info &cieInfo, pint_t upToPC, - int arch, PrologInfo *results); + int arch, PrologInfo *results); static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo); }; @@ -181,10 +181,10 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart, p += 8; } if (cfiLength == 0) - return "FDE has zero length"; // zero terminator + return "FDE has zero length"; // zero terminator uint32_t ciePointer = addressSpace.get32(p); - if (ciePointer == 0) - return "FDE is really a CIE"; // this is a CIE not an FDE + if (ciePointer == 0) + return "FDE is really a CIE"; // this is a CIE not an FDE pint_t nextCFI = p + cfiLength; pint_t cieStart = p - ciePointer; if (useCIEInfo) { @@ -196,23 +196,23 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart, return err; } p += 4; - // Parse pc begin and range. + // Parse pc begin and range. pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding); pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F); - // Parse rest of info. + // Parse rest of info. fdeInfo->lsda = 0; - // Check for augmentation length. + // Check for augmentation length. if (cieInfo->fdesHaveAugmentationData) { pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI); pint_t endOfAug = p + augLen; if (cieInfo->lsdaEncoding != DW_EH_PE_omit) { - // Peek at value (without indirection). Zero means no LSDA. + // Peek at value (without indirection). Zero means no LSDA. pint_t lsdaStart = p; if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0) { - // Reset pointer and re-parse LSDA address. + // Reset pointer and re-parse LSDA address. p = lsdaStart; fdeInfo->lsda = addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding); @@ -236,8 +236,8 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc); pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart; const pint_t ehSectionEnd = (sectionLength == SIZE_MAX) - ? static_cast<pint_t>(-1) - : (ehSectionStart + sectionLength); + ? static_cast<pint_t>(-1) + : (ehSectionStart + sectionLength); while (p < ehSectionEnd) { pint_t currentCFI = p; //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p); @@ -249,26 +249,26 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, p += 8; } if (cfiLength == 0) - return false; // zero terminator + return false; // zero terminator uint32_t id = addressSpace.get32(p); if (id == 0) { - // Skip over CIEs. + // Skip over CIEs. p += cfiLength; } else { - // Process FDE to see if it covers pc. + // Process FDE to see if it covers pc. pint_t nextCFI = p + cfiLength; uint32_t ciePointer = addressSpace.get32(p); pint_t cieStart = p - ciePointer; - // Validate pointer to CIE is within section. + // Validate pointer to CIE is within section. if ((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)) { if (parseCIE(addressSpace, cieStart, cieInfo) == NULL) { p += 4; - // Parse pc begin and range. + // Parse pc begin and range. pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding); pint_t pcRange = addressSpace.getEncodedP( p, nextCFI, cieInfo->pointerEncoding & 0x0F); - // Test if pc is within the function this FDE covers. + // Test if pc is within the function this FDE covers. if ((pcStart < pc) && (pc <= pcStart + pcRange)) { // parse rest of info fdeInfo->lsda = 0; @@ -277,11 +277,11 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI); pint_t endOfAug = p + augLen; if (cieInfo->lsdaEncoding != DW_EH_PE_omit) { - // Peek at value (without indirection). Zero means no LSDA. + // Peek at value (without indirection). Zero means no LSDA. pint_t lsdaStart = p; if (addressSpace.getEncodedP( p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0) { - // Reset pointer and re-parse LSDA address. + // Reset pointer and re-parse LSDA address. p = lsdaStart; fdeInfo->lsda = addressSpace .getEncodedP(p, nextCFI, cieInfo->lsdaEncoding); @@ -299,7 +299,7 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, // pc is not in begin/range, skip this FDE } } else { - // Malformed CIE, now augmentation describing pc range encoding. + // Malformed CIE, now augmentation describing pc range encoding. } } else { // malformed FDE. CIE is bad @@ -323,9 +323,9 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, cieInfo->dataAlignFactor = 0; cieInfo->isSignalFrame = false; cieInfo->fdesHaveAugmentationData = false; -#if defined(_LIBUNWIND_TARGET_AARCH64) - cieInfo->addressesSignedWithBKey = false; -#endif +#if defined(_LIBUNWIND_TARGET_AARCH64) + cieInfo->addressesSignedWithBKey = false; +#endif cieInfo->cieStart = cie; pint_t p = cie; pint_t cieLength = (pint_t)addressSpace.get32(p); @@ -358,8 +358,8 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, // parse data alignment factor cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd); // parse return address register - uint64_t raReg = (version == 1) ? addressSpace.get8(p++) - : addressSpace.getULEB128(p, cieContentEnd); + uint64_t raReg = (version == 1) ? addressSpace.get8(p++) + : addressSpace.getULEB128(p, cieContentEnd); assert(raReg < 255 && "return address register too large"); cieInfo->returnAddressRegister = (uint8_t)raReg; // parse augmentation data based on augmentation string @@ -390,11 +390,11 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, case 'S': cieInfo->isSignalFrame = true; break; -#if defined(_LIBUNWIND_TARGET_AARCH64) - case 'B': - cieInfo->addressesSignedWithBKey = true; - break; -#endif +#if defined(_LIBUNWIND_TARGET_AARCH64) + case 'B': + cieInfo->addressesSignedWithBKey = true; + break; +#endif default: // ignore unknown letters break; @@ -407,368 +407,368 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, } -/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE +/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE template <typename A> bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo, const CIE_Info &cieInfo, pint_t upToPC, - int arch, PrologInfo *results) { - // Alloca is used for the allocation of the rememberStack entries. It removes - // the dependency on new/malloc but the below for loop can not be refactored - // into functions. Entry could be saved during the processing of a CIE and - // restored by an FDE. - RememberStack rememberStack; - - struct ParseInfo { - pint_t instructions; - pint_t instructionsEnd; - pint_t pcoffset; - }; - - ParseInfo parseInfoArray[] = { - {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength, - (pint_t)(-1)}, - {fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength, - upToPC - fdeInfo.pcStart}}; - - for (const auto &info : parseInfoArray) { - pint_t p = info.instructions; - pint_t instructionsEnd = info.instructionsEnd; - pint_t pcoffset = info.pcoffset; - pint_t codeOffset = 0; - - // initialState initialized as registers in results are modified. Use - // PrologInfo accessor functions to avoid reading uninitialized data. - PrologInfo initialState(PrologInfo::InitializeTime::kLazy); - - _LIBUNWIND_TRACE_DWARF("parseFDEInstructions(instructions=0x%0" PRIx64 - ")\n", - static_cast<uint64_t>(instructionsEnd)); - - // see DWARF Spec, section 6.4.2 for details on unwind opcodes - while ((p < instructionsEnd) && (codeOffset < pcoffset)) { - uint64_t reg; - uint64_t reg2; - int64_t offset; - uint64_t length; - uint8_t opcode = addressSpace.get8(p); - uint8_t operand; - - ++p; - switch (opcode) { - case DW_CFA_nop: - _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n"); - break; - case DW_CFA_set_loc: - codeOffset = addressSpace.getEncodedP(p, instructionsEnd, - cieInfo.pointerEncoding); - _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n"); - break; - case DW_CFA_advance_loc1: - codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor); - p += 1; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_advance_loc2: - codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor); - p += 2; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_advance_loc4: - codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor); - p += 4; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_offset_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_offset_extended DWARF unwind, reg too big"); - return false; - } - results->setRegister(reg, kRegisterInCFA, offset, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_restore_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_restore_extended DWARF unwind, reg too big"); - return false; - } - results->restoreRegisterToInitialState(reg, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", - reg); - break; - case DW_CFA_undefined: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_undefined DWARF unwind, reg too big"); - return false; - } - results->setRegisterLocation(reg, kRegisterUndefined, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg); - break; - case DW_CFA_same_value: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_same_value DWARF unwind, reg too big"); - return false; - } - // <rdar://problem/8456377> DW_CFA_same_value unsupported - // "same value" means register was stored in frame, but its current - // value has not changed, so no need to restore from frame. - // We model this as if the register was never saved. - results->setRegisterLocation(reg, kRegisterUnused, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg); - break; - case DW_CFA_register: - reg = addressSpace.getULEB128(p, instructionsEnd); - reg2 = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_register DWARF unwind, reg too big"); - return false; - } - if (reg2 > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_register DWARF unwind, reg2 too big"); - return false; - } - results->setRegister(reg, kRegisterInRegister, (int64_t)reg2, - initialState); - _LIBUNWIND_TRACE_DWARF( - "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2); - break; - case DW_CFA_remember_state: { - // Avoid operator new because that would be an upward dependency. - // Avoid malloc because it needs heap allocation. - PrologInfoStackEntry *entry = - (PrologInfoStackEntry *)_LIBUNWIND_REMEMBER_ALLOC( - sizeof(PrologInfoStackEntry)); - if (entry != NULL) { - entry->next = rememberStack.entry; - entry->info = *results; - rememberStack.entry = entry; - } else { - return false; - } - _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n"); - break; - } - case DW_CFA_restore_state: - if (rememberStack.entry != NULL) { - PrologInfoStackEntry *top = rememberStack.entry; - *results = top->info; - rememberStack.entry = top->next; - _LIBUNWIND_REMEMBER_FREE(top); - } else { - return false; - } - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n"); - break; - case DW_CFA_def_cfa: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big"); - return false; - } - results->cfaRegister = (uint32_t)reg; - results->cfaRegisterOffset = (int32_t)offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 - ")\n", - reg, offset); - break; - case DW_CFA_def_cfa_register: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big"); - return false; - } - results->cfaRegister = (uint32_t)reg; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg); - break; - case DW_CFA_def_cfa_offset: - results->cfaRegisterOffset = - (int32_t)addressSpace.getULEB128(p, instructionsEnd); - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n", - results->cfaRegisterOffset); - break; - case DW_CFA_def_cfa_expression: - results->cfaRegister = 0; - results->cfaExpression = (int64_t)p; - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < static_cast<pint_t>(~0) && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 - ", length=%" PRIu64 ")\n", - results->cfaExpression, length); - break; - case DW_CFA_expression: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_expression DWARF unwind, reg too big"); - return false; - } - results->setRegister(reg, kRegisterAtExpression, (int64_t)p, - initialState); - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < static_cast<pint_t>(~0) && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " - "expression=0x%" PRIx64 ", " - "length=%" PRIu64 ")\n", - reg, results->savedRegisters[reg].value, length); - break; - case DW_CFA_offset_extended_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big"); - return false; - } - offset = addressSpace.getSLEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - results->setRegister(reg, kRegisterInCFA, offset, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_def_cfa_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = addressSpace.getSLEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big"); - return false; - } - results->cfaRegister = (uint32_t)reg; - results->cfaRegisterOffset = (int32_t)offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_def_cfa_offset_sf: - results->cfaRegisterOffset = - (int32_t)(addressSpace.getSLEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor); - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n", - results->cfaRegisterOffset); - break; - case DW_CFA_val_offset: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG( - "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64 - ") out of range\n", - reg); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", " - "offset=%" PRId64 "\n", - reg, offset); - break; - case DW_CFA_val_offset_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big"); - return false; - } - offset = addressSpace.getSLEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 "\n", - reg, offset); - break; - case DW_CFA_val_expression: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0( - "malformed DW_CFA_val_expression DWARF unwind, reg too big"); - return false; - } - results->setRegister(reg, kRegisterIsExpression, (int64_t)p, - initialState); - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < static_cast<pint_t>(~0) && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " - "expression=0x%" PRIx64 ", length=%" PRIu64 - ")\n", - reg, results->savedRegisters[reg].value, length); - break; - case DW_CFA_GNU_args_size: - length = addressSpace.getULEB128(p, instructionsEnd); - results->spExtraArgSize = (uint32_t)length; - _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length); - break; - case DW_CFA_GNU_negative_offset_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF " - "unwind, reg too big"); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - results->setRegister(reg, kRegisterInCFA, -offset, initialState); - _LIBUNWIND_TRACE_DWARF( - "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset); - break; - + int arch, PrologInfo *results) { + // Alloca is used for the allocation of the rememberStack entries. It removes + // the dependency on new/malloc but the below for loop can not be refactored + // into functions. Entry could be saved during the processing of a CIE and + // restored by an FDE. + RememberStack rememberStack; + + struct ParseInfo { + pint_t instructions; + pint_t instructionsEnd; + pint_t pcoffset; + }; + + ParseInfo parseInfoArray[] = { + {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength, + (pint_t)(-1)}, + {fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength, + upToPC - fdeInfo.pcStart}}; + + for (const auto &info : parseInfoArray) { + pint_t p = info.instructions; + pint_t instructionsEnd = info.instructionsEnd; + pint_t pcoffset = info.pcoffset; + pint_t codeOffset = 0; + + // initialState initialized as registers in results are modified. Use + // PrologInfo accessor functions to avoid reading uninitialized data. + PrologInfo initialState(PrologInfo::InitializeTime::kLazy); + + _LIBUNWIND_TRACE_DWARF("parseFDEInstructions(instructions=0x%0" PRIx64 + ")\n", + static_cast<uint64_t>(instructionsEnd)); + + // see DWARF Spec, section 6.4.2 for details on unwind opcodes + while ((p < instructionsEnd) && (codeOffset < pcoffset)) { + uint64_t reg; + uint64_t reg2; + int64_t offset; + uint64_t length; + uint8_t opcode = addressSpace.get8(p); + uint8_t operand; + + ++p; + switch (opcode) { + case DW_CFA_nop: + _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n"); + break; + case DW_CFA_set_loc: + codeOffset = addressSpace.getEncodedP(p, instructionsEnd, + cieInfo.pointerEncoding); + _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n"); + break; + case DW_CFA_advance_loc1: + codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor); + p += 1; + _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n", + static_cast<uint64_t>(codeOffset)); + break; + case DW_CFA_advance_loc2: + codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor); + p += 2; + _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n", + static_cast<uint64_t>(codeOffset)); + break; + case DW_CFA_advance_loc4: + codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor); + p += 4; + _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n", + static_cast<uint64_t>(codeOffset)); + break; + case DW_CFA_offset_extended: + reg = addressSpace.getULEB128(p, instructionsEnd); + offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_offset_extended DWARF unwind, reg too big"); + return false; + } + results->setRegister(reg, kRegisterInCFA, offset, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", " + "offset=%" PRId64 ")\n", + reg, offset); + break; + case DW_CFA_restore_extended: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_restore_extended DWARF unwind, reg too big"); + return false; + } + results->restoreRegisterToInitialState(reg, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", + reg); + break; + case DW_CFA_undefined: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_undefined DWARF unwind, reg too big"); + return false; + } + results->setRegisterLocation(reg, kRegisterUndefined, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg); + break; + case DW_CFA_same_value: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_same_value DWARF unwind, reg too big"); + return false; + } + // <rdar://problem/8456377> DW_CFA_same_value unsupported + // "same value" means register was stored in frame, but its current + // value has not changed, so no need to restore from frame. + // We model this as if the register was never saved. + results->setRegisterLocation(reg, kRegisterUnused, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg); + break; + case DW_CFA_register: + reg = addressSpace.getULEB128(p, instructionsEnd); + reg2 = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_register DWARF unwind, reg too big"); + return false; + } + if (reg2 > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_register DWARF unwind, reg2 too big"); + return false; + } + results->setRegister(reg, kRegisterInRegister, (int64_t)reg2, + initialState); + _LIBUNWIND_TRACE_DWARF( + "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2); + break; + case DW_CFA_remember_state: { + // Avoid operator new because that would be an upward dependency. + // Avoid malloc because it needs heap allocation. + PrologInfoStackEntry *entry = + (PrologInfoStackEntry *)_LIBUNWIND_REMEMBER_ALLOC( + sizeof(PrologInfoStackEntry)); + if (entry != NULL) { + entry->next = rememberStack.entry; + entry->info = *results; + rememberStack.entry = entry; + } else { + return false; + } + _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n"); + break; + } + case DW_CFA_restore_state: + if (rememberStack.entry != NULL) { + PrologInfoStackEntry *top = rememberStack.entry; + *results = top->info; + rememberStack.entry = top->next; + _LIBUNWIND_REMEMBER_FREE(top); + } else { + return false; + } + _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n"); + break; + case DW_CFA_def_cfa: + reg = addressSpace.getULEB128(p, instructionsEnd); + offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big"); + return false; + } + results->cfaRegister = (uint32_t)reg; + results->cfaRegisterOffset = (int32_t)offset; + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 + ")\n", + reg, offset); + break; + case DW_CFA_def_cfa_register: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big"); + return false; + } + results->cfaRegister = (uint32_t)reg; + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg); + break; + case DW_CFA_def_cfa_offset: + results->cfaRegisterOffset = + (int32_t)addressSpace.getULEB128(p, instructionsEnd); + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n", + results->cfaRegisterOffset); + break; + case DW_CFA_def_cfa_expression: + results->cfaRegister = 0; + results->cfaExpression = (int64_t)p; + length = addressSpace.getULEB128(p, instructionsEnd); + assert(length < static_cast<pint_t>(~0) && "pointer overflow"); + p += static_cast<pint_t>(length); + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 + ", length=%" PRIu64 ")\n", + results->cfaExpression, length); + break; + case DW_CFA_expression: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_expression DWARF unwind, reg too big"); + return false; + } + results->setRegister(reg, kRegisterAtExpression, (int64_t)p, + initialState); + length = addressSpace.getULEB128(p, instructionsEnd); + assert(length < static_cast<pint_t>(~0) && "pointer overflow"); + p += static_cast<pint_t>(length); + _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " + "expression=0x%" PRIx64 ", " + "length=%" PRIu64 ")\n", + reg, results->savedRegisters[reg].value, length); + break; + case DW_CFA_offset_extended_sf: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big"); + return false; + } + offset = addressSpace.getSLEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + results->setRegister(reg, kRegisterInCFA, offset, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", " + "offset=%" PRId64 ")\n", + reg, offset); + break; + case DW_CFA_def_cfa_sf: + reg = addressSpace.getULEB128(p, instructionsEnd); + offset = addressSpace.getSLEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big"); + return false; + } + results->cfaRegister = (uint32_t)reg; + results->cfaRegisterOffset = (int32_t)offset; + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", " + "offset=%" PRId64 ")\n", + reg, offset); + break; + case DW_CFA_def_cfa_offset_sf: + results->cfaRegisterOffset = + (int32_t)(addressSpace.getSLEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor); + _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n", + results->cfaRegisterOffset); + break; + case DW_CFA_val_offset: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG( + "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64 + ") out of range\n", + reg); + return false; + } + offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", " + "offset=%" PRId64 "\n", + reg, offset); + break; + case DW_CFA_val_offset_sf: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big"); + return false; + } + offset = addressSpace.getSLEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", " + "offset=%" PRId64 "\n", + reg, offset); + break; + case DW_CFA_val_expression: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0( + "malformed DW_CFA_val_expression DWARF unwind, reg too big"); + return false; + } + results->setRegister(reg, kRegisterIsExpression, (int64_t)p, + initialState); + length = addressSpace.getULEB128(p, instructionsEnd); + assert(length < static_cast<pint_t>(~0) && "pointer overflow"); + p += static_cast<pint_t>(length); + _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " + "expression=0x%" PRIx64 ", length=%" PRIu64 + ")\n", + reg, results->savedRegisters[reg].value, length); + break; + case DW_CFA_GNU_args_size: + length = addressSpace.getULEB128(p, instructionsEnd); + results->spExtraArgSize = (uint32_t)length; + _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length); + break; + case DW_CFA_GNU_negative_offset_extended: + reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF " + "unwind, reg too big"); + return false; + } + offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + results->setRegister(reg, kRegisterInCFA, -offset, initialState); + _LIBUNWIND_TRACE_DWARF( + "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset); + break; + #if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \ defined(_LIBUNWIND_TARGET_SPARC64) - // The same constant is used to represent different instructions on - // AArch64 (negate_ra_state) and SPARC (window_save). - static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save, - "uses the same constant"); - case DW_CFA_AARCH64_negate_ra_state: - switch (arch) { -#if defined(_LIBUNWIND_TARGET_AARCH64) - case REGISTERS_ARM64: { - int64_t value = + // The same constant is used to represent different instructions on + // AArch64 (negate_ra_state) and SPARC (window_save). + static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save, + "uses the same constant"); + case DW_CFA_AARCH64_negate_ra_state: + switch (arch) { +#if defined(_LIBUNWIND_TARGET_AARCH64) + case REGISTERS_ARM64: { + int64_t value = results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x1; results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value, - initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n"); - } break; -#endif - -#if defined(_LIBUNWIND_TARGET_SPARC) - // case DW_CFA_GNU_window_save: - case REGISTERS_SPARC: - _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n"); - for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) { - results->setRegister(reg, kRegisterInRegister, - ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0, - initialState); - } - - for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) { - results->setRegister(reg, kRegisterInCFA, - ((int64_t)reg - UNW_SPARC_L0) * 4, - initialState); - } - break; -#endif + initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n"); + } break; +#endif + +#if defined(_LIBUNWIND_TARGET_SPARC) + // case DW_CFA_GNU_window_save: + case REGISTERS_SPARC: + _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n"); + for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) { + results->setRegister(reg, kRegisterInRegister, + ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0, + initialState); + } + + for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) { + results->setRegister(reg, kRegisterInCFA, + ((int64_t)reg - UNW_SPARC_L0) * 4, + initialState); + } + break; +#endif #if defined(_LIBUNWIND_TARGET_SPARC64) // case DW_CFA_GNU_window_save: @@ -791,52 +791,52 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n"); break; #endif - } - break; - -#else - (void)arch; -#endif + } + break; +#else + (void)arch; +#endif + default: - operand = opcode & 0x3F; - switch (opcode & 0xC0) { - case DW_CFA_offset: - reg = operand; - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64 - ") out of range", - reg); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * - cieInfo.dataAlignFactor; - results->setRegister(reg, kRegisterInCFA, offset, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n", - operand, offset); - break; - case DW_CFA_advance_loc: - codeOffset += operand * cieInfo.codeAlignFactor; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_restore: - reg = operand; - if (reg > kMaxRegisterNumber) { - _LIBUNWIND_LOG( - "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64 - ") out of range", - reg); - return false; - } - results->restoreRegisterToInitialState(reg, initialState); - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n", - static_cast<uint64_t>(operand)); - break; - default: - _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode); - return false; - } + operand = opcode & 0x3F; + switch (opcode & 0xC0) { + case DW_CFA_offset: + reg = operand; + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64 + ") out of range", + reg); + return false; + } + offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * + cieInfo.dataAlignFactor; + results->setRegister(reg, kRegisterInCFA, offset, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n", + operand, offset); + break; + case DW_CFA_advance_loc: + codeOffset += operand * cieInfo.codeAlignFactor; + _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n", + static_cast<uint64_t>(codeOffset)); + break; + case DW_CFA_restore: + reg = operand; + if (reg > kMaxRegisterNumber) { + _LIBUNWIND_LOG( + "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64 + ") out of range", + reg); + return false; + } + results->restoreRegisterToInitialState(reg, initialState); + _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n", + static_cast<uint64_t>(operand)); + break; + default: + _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode); + return false; + } } } } diff --git a/contrib/libs/libunwind/src/EHHeaderParser.hpp b/contrib/libs/libunwind/src/EHHeaderParser.hpp index 9a38070fab..1c828e4ffb 100644 --- a/contrib/libs/libunwind/src/EHHeaderParser.hpp +++ b/contrib/libs/libunwind/src/EHHeaderParser.hpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Parses ELF .eh_frame_hdr sections. @@ -57,7 +57,7 @@ bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t p = ehHdrStart; uint8_t version = addressSpace.get8(p++); if (version != 1) { - _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version"); + _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version"); return false; } @@ -68,9 +68,9 @@ bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, ehHdrInfo.eh_frame_ptr = addressSpace.getEncodedP(p, ehHdrEnd, eh_frame_ptr_enc, ehHdrStart); ehHdrInfo.fde_count = - fde_count_enc == DW_EH_PE_omit - ? 0 - : addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart); + fde_count_enc == DW_EH_PE_omit + ? 0 + : addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart); ehHdrInfo.table = p; return true; @@ -89,7 +89,7 @@ bool EHHeaderParser<A>::decodeTableEntry( const char *message = CFI_Parser<A>::decodeFDE(addressSpace, fde, fdeInfo, cieInfo); if (message != NULL) { - _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s", + _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s", message); return false; } @@ -105,12 +105,12 @@ bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, pint_t ehHdrEnd = ehHdrStart + sectionLength; EHHeaderParser<A>::EHHeaderInfo hdrInfo; - if (!EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, - hdrInfo)) + if (!EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, + hdrInfo)) return false; - if (hdrInfo.fde_count == 0) return false; - + if (hdrInfo.fde_count == 0) return false; + size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc); pint_t tableEntry; diff --git a/contrib/libs/libunwind/src/FrameHeaderCache.hpp b/contrib/libs/libunwind/src/FrameHeaderCache.hpp index 54d5d33c3c..2df7e5cd09 100644 --- a/contrib/libs/libunwind/src/FrameHeaderCache.hpp +++ b/contrib/libs/libunwind/src/FrameHeaderCache.hpp @@ -1,149 +1,149 @@ -//===-FrameHeaderCache.hpp ------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// Cache the elf program headers necessary to unwind the stack more efficiently -// in the presence of many dsos. -// -//===----------------------------------------------------------------------===// - -#ifndef __FRAMEHEADER_CACHE_HPP__ -#define __FRAMEHEADER_CACHE_HPP__ - -#include "config.h" -#include <limits.h> - -#ifdef _LIBUNWIND_DEBUG_FRAMEHEADER_CACHE -#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x) _LIBUNWIND_LOG0(x) -#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...) \ - _LIBUNWIND_LOG(msg, __VA_ARGS__) -#else -#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x) -#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...) -#endif - -// This cache should only be be used from within a dl_iterate_phdr callback. -// dl_iterate_phdr does the necessary synchronization to prevent problems -// with concurrent access via the libc load lock. Adding synchronization -// for other uses is possible, but not currently done. - -class _LIBUNWIND_HIDDEN FrameHeaderCache { - struct CacheEntry { - uintptr_t LowPC() { return Info.dso_base; }; - uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; }; - UnwindInfoSections Info; - CacheEntry *Next; - }; - - static const size_t kCacheEntryCount = 8; - - // Can't depend on the C++ standard library in libunwind, so use an array to - // allocate the entries, and two linked lists for ordering unused and recently - // used entries. FIXME: Would the the extra memory for a doubly-linked list - // be better than the runtime cost of traversing a very short singly-linked - // list on a cache miss? The entries themselves are all small and consecutive, - // so unlikely to cause page faults when following the pointers. The memory - // spent on additional pointers could also be spent on more entries. - - CacheEntry Entries[kCacheEntryCount]; - CacheEntry *MostRecentlyUsed; - CacheEntry *Unused; - - void resetCache() { - _LIBUNWIND_FRAMEHEADERCACHE_TRACE0("FrameHeaderCache reset"); - MostRecentlyUsed = nullptr; - Unused = &Entries[0]; - for (size_t i = 0; i < kCacheEntryCount - 1; i++) { - Entries[i].Next = &Entries[i + 1]; - } - Entries[kCacheEntryCount - 1].Next = nullptr; - } - - bool cacheNeedsReset(dl_phdr_info *PInfo) { - // C libraries increment dl_phdr_info.adds and dl_phdr_info.subs when - // loading and unloading shared libraries. If these values change between - // iterations of dl_iterate_phdr, then invalidate the cache. - - // These are static to avoid needing an initializer, and unsigned long long - // because that is their type within the extended dl_phdr_info. Initialize - // these to something extremely unlikely to be found upon the first call to - // dl_iterate_phdr. - static unsigned long long LastAdds = ULLONG_MAX; - static unsigned long long LastSubs = ULLONG_MAX; - if (PInfo->dlpi_adds != LastAdds || PInfo->dlpi_subs != LastSubs) { - // Resetting the entire cache is a big hammer, but this path is rare-- - // usually just on the very first call, when the cache is empty anyway--so - // added complexity doesn't buy much. - LastAdds = PInfo->dlpi_adds; - LastSubs = PInfo->dlpi_subs; - resetCache(); - return true; - } - return false; - } - -public: - bool find(dl_phdr_info *PInfo, size_t, void *data) { - if (cacheNeedsReset(PInfo) || MostRecentlyUsed == nullptr) - return false; - - auto *CBData = static_cast<dl_iterate_cb_data *>(data); - CacheEntry *Current = MostRecentlyUsed; - CacheEntry *Previous = nullptr; - while (Current != nullptr) { - _LIBUNWIND_FRAMEHEADERCACHE_TRACE( - "FrameHeaderCache check %lx in [%lx - %lx)", CBData->targetAddr, - Current->LowPC(), Current->HighPC()); - if (Current->LowPC() <= CBData->targetAddr && - CBData->targetAddr < Current->HighPC()) { - _LIBUNWIND_FRAMEHEADERCACHE_TRACE( - "FrameHeaderCache hit %lx in [%lx - %lx)", CBData->targetAddr, - Current->LowPC(), Current->HighPC()); - if (Previous) { - // If there is no Previous, then Current is already the - // MostRecentlyUsed, and no need to move it up. - Previous->Next = Current->Next; - Current->Next = MostRecentlyUsed; - MostRecentlyUsed = Current; - } - *CBData->sects = Current->Info; - return true; - } - Previous = Current; - Current = Current->Next; - } - _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache miss for address %lx", - CBData->targetAddr); - return false; - } - - void add(const UnwindInfoSections *UIS) { - CacheEntry *Current = nullptr; - - if (Unused != nullptr) { - Current = Unused; - Unused = Unused->Next; - } else { - Current = MostRecentlyUsed; - CacheEntry *Previous = nullptr; - while (Current->Next != nullptr) { - Previous = Current; - Current = Current->Next; - } - Previous->Next = nullptr; - _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache evict [%lx - %lx)", - Current->LowPC(), Current->HighPC()); - } - - Current->Info = *UIS; - Current->Next = MostRecentlyUsed; - MostRecentlyUsed = Current; - _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache add [%lx - %lx)", - MostRecentlyUsed->LowPC(), - MostRecentlyUsed->HighPC()); - } -}; - -#endif // __FRAMEHEADER_CACHE_HPP__ +//===-FrameHeaderCache.hpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Cache the elf program headers necessary to unwind the stack more efficiently +// in the presence of many dsos. +// +//===----------------------------------------------------------------------===// + +#ifndef __FRAMEHEADER_CACHE_HPP__ +#define __FRAMEHEADER_CACHE_HPP__ + +#include "config.h" +#include <limits.h> + +#ifdef _LIBUNWIND_DEBUG_FRAMEHEADER_CACHE +#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x) _LIBUNWIND_LOG0(x) +#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...) \ + _LIBUNWIND_LOG(msg, __VA_ARGS__) +#else +#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x) +#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...) +#endif + +// This cache should only be be used from within a dl_iterate_phdr callback. +// dl_iterate_phdr does the necessary synchronization to prevent problems +// with concurrent access via the libc load lock. Adding synchronization +// for other uses is possible, but not currently done. + +class _LIBUNWIND_HIDDEN FrameHeaderCache { + struct CacheEntry { + uintptr_t LowPC() { return Info.dso_base; }; + uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; }; + UnwindInfoSections Info; + CacheEntry *Next; + }; + + static const size_t kCacheEntryCount = 8; + + // Can't depend on the C++ standard library in libunwind, so use an array to + // allocate the entries, and two linked lists for ordering unused and recently + // used entries. FIXME: Would the the extra memory for a doubly-linked list + // be better than the runtime cost of traversing a very short singly-linked + // list on a cache miss? The entries themselves are all small and consecutive, + // so unlikely to cause page faults when following the pointers. The memory + // spent on additional pointers could also be spent on more entries. + + CacheEntry Entries[kCacheEntryCount]; + CacheEntry *MostRecentlyUsed; + CacheEntry *Unused; + + void resetCache() { + _LIBUNWIND_FRAMEHEADERCACHE_TRACE0("FrameHeaderCache reset"); + MostRecentlyUsed = nullptr; + Unused = &Entries[0]; + for (size_t i = 0; i < kCacheEntryCount - 1; i++) { + Entries[i].Next = &Entries[i + 1]; + } + Entries[kCacheEntryCount - 1].Next = nullptr; + } + + bool cacheNeedsReset(dl_phdr_info *PInfo) { + // C libraries increment dl_phdr_info.adds and dl_phdr_info.subs when + // loading and unloading shared libraries. If these values change between + // iterations of dl_iterate_phdr, then invalidate the cache. + + // These are static to avoid needing an initializer, and unsigned long long + // because that is their type within the extended dl_phdr_info. Initialize + // these to something extremely unlikely to be found upon the first call to + // dl_iterate_phdr. + static unsigned long long LastAdds = ULLONG_MAX; + static unsigned long long LastSubs = ULLONG_MAX; + if (PInfo->dlpi_adds != LastAdds || PInfo->dlpi_subs != LastSubs) { + // Resetting the entire cache is a big hammer, but this path is rare-- + // usually just on the very first call, when the cache is empty anyway--so + // added complexity doesn't buy much. + LastAdds = PInfo->dlpi_adds; + LastSubs = PInfo->dlpi_subs; + resetCache(); + return true; + } + return false; + } + +public: + bool find(dl_phdr_info *PInfo, size_t, void *data) { + if (cacheNeedsReset(PInfo) || MostRecentlyUsed == nullptr) + return false; + + auto *CBData = static_cast<dl_iterate_cb_data *>(data); + CacheEntry *Current = MostRecentlyUsed; + CacheEntry *Previous = nullptr; + while (Current != nullptr) { + _LIBUNWIND_FRAMEHEADERCACHE_TRACE( + "FrameHeaderCache check %lx in [%lx - %lx)", CBData->targetAddr, + Current->LowPC(), Current->HighPC()); + if (Current->LowPC() <= CBData->targetAddr && + CBData->targetAddr < Current->HighPC()) { + _LIBUNWIND_FRAMEHEADERCACHE_TRACE( + "FrameHeaderCache hit %lx in [%lx - %lx)", CBData->targetAddr, + Current->LowPC(), Current->HighPC()); + if (Previous) { + // If there is no Previous, then Current is already the + // MostRecentlyUsed, and no need to move it up. + Previous->Next = Current->Next; + Current->Next = MostRecentlyUsed; + MostRecentlyUsed = Current; + } + *CBData->sects = Current->Info; + return true; + } + Previous = Current; + Current = Current->Next; + } + _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache miss for address %lx", + CBData->targetAddr); + return false; + } + + void add(const UnwindInfoSections *UIS) { + CacheEntry *Current = nullptr; + + if (Unused != nullptr) { + Current = Unused; + Unused = Unused->Next; + } else { + Current = MostRecentlyUsed; + CacheEntry *Previous = nullptr; + while (Current->Next != nullptr) { + Previous = Current; + Current = Current->Next; + } + Previous->Next = nullptr; + _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache evict [%lx - %lx)", + Current->LowPC(), Current->HighPC()); + } + + Current->Info = *UIS; + Current->Next = MostRecentlyUsed; + MostRecentlyUsed = Current; + _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache add [%lx - %lx)", + MostRecentlyUsed->LowPC(), + MostRecentlyUsed->HighPC()); + } +}; + +#endif // __FRAMEHEADER_CACHE_HPP__ diff --git a/contrib/libs/libunwind/src/RWMutex.hpp b/contrib/libs/libunwind/src/RWMutex.hpp index 344d35641f..6703f9d551 100644 --- a/contrib/libs/libunwind/src/RWMutex.hpp +++ b/contrib/libs/libunwind/src/RWMutex.hpp @@ -1,114 +1,114 @@ //===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// -// Abstract interface to shared reader/writer log, hiding platform and -// configuration differences. -// -//===----------------------------------------------------------------------===// - -#ifndef __RWMUTEX_HPP__ -#define __RWMUTEX_HPP__ - -#if defined(_WIN32) -#include <windows.h> -#elif !defined(_LIBUNWIND_HAS_NO_THREADS) -#include <pthread.h> -#if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB) -#pragma comment(lib, "pthread") -#endif -#endif - -namespace libunwind { - -#if defined(_LIBUNWIND_HAS_NO_THREADS) - -class _LIBUNWIND_HIDDEN RWMutex { -public: - bool lock_shared() { return true; } - bool unlock_shared() { return true; } - bool lock() { return true; } - bool unlock() { return true; } -}; - -#elif defined(_WIN32) - -class _LIBUNWIND_HIDDEN RWMutex { -public: - bool lock_shared() { - AcquireSRWLockShared(&_lock); - return true; - } - bool unlock_shared() { - ReleaseSRWLockShared(&_lock); - return true; - } - bool lock() { - AcquireSRWLockExclusive(&_lock); - return true; - } - bool unlock() { - ReleaseSRWLockExclusive(&_lock); - return true; - } - -private: - SRWLOCK _lock = SRWLOCK_INIT; -}; - -#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD) - -class _LIBUNWIND_HIDDEN RWMutex { -public: - bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; } - bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; } - bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; } - bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; } - -private: - pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; -}; - -#else - -extern "C" int __attribute__((weak)) -pthread_create(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine)(void *), void *arg); -extern "C" int __attribute__((weak)) -pthread_rwlock_rdlock(pthread_rwlock_t *lock); -extern "C" int __attribute__((weak)) -pthread_rwlock_wrlock(pthread_rwlock_t *lock); -extern "C" int __attribute__((weak)) -pthread_rwlock_unlock(pthread_rwlock_t *lock); - -// Calls to the locking functions are gated on pthread_create, and not the -// functions themselves, because the data structure should only be locked if -// another thread has been created. This is what similar libraries do. - -class _LIBUNWIND_HIDDEN RWMutex { -public: - bool lock_shared() { - return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0); - } - bool unlock_shared() { - return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); - } - bool lock() { - return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0); - } - bool unlock() { - return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); - } - -private: - pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; -}; - -#endif - -} // namespace libunwind - -#endif // __RWMUTEX_HPP__ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// +// Abstract interface to shared reader/writer log, hiding platform and +// configuration differences. +// +//===----------------------------------------------------------------------===// + +#ifndef __RWMUTEX_HPP__ +#define __RWMUTEX_HPP__ + +#if defined(_WIN32) +#include <windows.h> +#elif !defined(_LIBUNWIND_HAS_NO_THREADS) +#include <pthread.h> +#if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB) +#pragma comment(lib, "pthread") +#endif +#endif + +namespace libunwind { + +#if defined(_LIBUNWIND_HAS_NO_THREADS) + +class _LIBUNWIND_HIDDEN RWMutex { +public: + bool lock_shared() { return true; } + bool unlock_shared() { return true; } + bool lock() { return true; } + bool unlock() { return true; } +}; + +#elif defined(_WIN32) + +class _LIBUNWIND_HIDDEN RWMutex { +public: + bool lock_shared() { + AcquireSRWLockShared(&_lock); + return true; + } + bool unlock_shared() { + ReleaseSRWLockShared(&_lock); + return true; + } + bool lock() { + AcquireSRWLockExclusive(&_lock); + return true; + } + bool unlock() { + ReleaseSRWLockExclusive(&_lock); + return true; + } + +private: + SRWLOCK _lock = SRWLOCK_INIT; +}; + +#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD) + +class _LIBUNWIND_HIDDEN RWMutex { +public: + bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; } + bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; } + bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; } + bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; } + +private: + pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; +}; + +#else + +extern "C" int __attribute__((weak)) +pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg); +extern "C" int __attribute__((weak)) +pthread_rwlock_rdlock(pthread_rwlock_t *lock); +extern "C" int __attribute__((weak)) +pthread_rwlock_wrlock(pthread_rwlock_t *lock); +extern "C" int __attribute__((weak)) +pthread_rwlock_unlock(pthread_rwlock_t *lock); + +// Calls to the locking functions are gated on pthread_create, and not the +// functions themselves, because the data structure should only be locked if +// another thread has been created. This is what similar libraries do. + +class _LIBUNWIND_HIDDEN RWMutex { +public: + bool lock_shared() { + return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0); + } + bool unlock_shared() { + return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); + } + bool lock() { + return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0); + } + bool unlock() { + return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); + } + +private: + pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; +}; + +#endif + +} // namespace libunwind + +#endif // __RWMUTEX_HPP__ diff --git a/contrib/libs/libunwind/src/Registers.hpp b/contrib/libs/libunwind/src/Registers.hpp index cbc3876d67..8d5e8b7b6e 100644 --- a/contrib/libs/libunwind/src/Registers.hpp +++ b/contrib/libs/libunwind/src/Registers.hpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Models register sets for supported processors. @@ -24,26 +24,26 @@ namespace libunwind { // For emulating 128-bit registers struct v128 { uint32_t vec[4]; }; -enum { - REGISTERS_X86, - REGISTERS_X86_64, - REGISTERS_PPC, - REGISTERS_PPC64, - REGISTERS_ARM64, - REGISTERS_ARM, - REGISTERS_OR1K, - REGISTERS_MIPS_O32, - REGISTERS_MIPS_NEWABI, - REGISTERS_SPARC, +enum { + REGISTERS_X86, + REGISTERS_X86_64, + REGISTERS_PPC, + REGISTERS_PPC64, + REGISTERS_ARM64, + REGISTERS_ARM, + REGISTERS_OR1K, + REGISTERS_MIPS_O32, + REGISTERS_MIPS_NEWABI, + REGISTERS_SPARC, REGISTERS_SPARC64, - REGISTERS_HEXAGON, - REGISTERS_RISCV, + REGISTERS_HEXAGON, + REGISTERS_RISCV, REGISTERS_VE, -}; +}; -#if defined(_LIBUNWIND_TARGET_I386) -class _LIBUNWIND_HIDDEN Registers_x86; -extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *); +#if defined(_LIBUNWIND_TARGET_I386) +class _LIBUNWIND_HIDDEN Registers_x86; +extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *); #if defined(_LIBUNWIND_USE_CET) extern "C" void *__libunwind_cet_get_jump_target() { @@ -67,10 +67,10 @@ public: bool validVectorRegister(int) const { return false; } v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto() { __libunwind_Registers_x86_jumpto(this); } - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } - static int getArch() { return REGISTERS_X86; } + static const char *getRegisterName(int num); + void jumpto() { __libunwind_Registers_x86_jumpto(this); } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } + static int getArch() { return REGISTERS_X86; } uint32_t getSP() const { return _registers.__esp; } void setSP(uint32_t value) { _registers.__esp = value; } @@ -113,8 +113,8 @@ private: }; inline Registers_x86::Registers_x86(const void *registers) { - static_assert((check_fit<Registers_x86, unw_context_t>::does_fit), - "x86 registers do not fit into unw_context_t"); + static_assert((check_fit<Registers_x86, unw_context_t>::does_fit), + "x86 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); } @@ -148,17 +148,17 @@ inline uint32_t Registers_x86::getRegister(int regNum) const { return _registers.__edx; case UNW_X86_EBX: return _registers.__ebx; -#if !defined(__APPLE__) - case UNW_X86_ESP: -#else +#if !defined(__APPLE__) + case UNW_X86_ESP: +#else case UNW_X86_EBP: -#endif +#endif return _registers.__ebp; -#if !defined(__APPLE__) - case UNW_X86_EBP: -#else +#if !defined(__APPLE__) + case UNW_X86_EBP: +#else case UNW_X86_ESP: -#endif +#endif return _registers.__esp; case UNW_X86_ESI: return _registers.__esi; @@ -188,18 +188,18 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value) { case UNW_X86_EBX: _registers.__ebx = value; return; -#if !defined(__APPLE__) - case UNW_X86_ESP: -#else +#if !defined(__APPLE__) + case UNW_X86_ESP: +#else case UNW_X86_EBP: -#endif +#endif _registers.__ebp = value; return; -#if !defined(__APPLE__) - case UNW_X86_EBP: -#else +#if !defined(__APPLE__) + case UNW_X86_EBP: +#else case UNW_X86_ESP: -#endif +#endif _registers.__esp = value; return; case UNW_X86_ESI: @@ -254,14 +254,14 @@ inline v128 Registers_x86::getVectorRegister(int) const { inline void Registers_x86::setVectorRegister(int, v128) { _LIBUNWIND_ABORT("no x86 vector registers"); } -#endif // _LIBUNWIND_TARGET_I386 +#endif // _LIBUNWIND_TARGET_I386 -#if defined(_LIBUNWIND_TARGET_X86_64) +#if defined(_LIBUNWIND_TARGET_X86_64) /// Registers_x86_64 holds the register state of a thread in a 64-bit intel /// process. -class _LIBUNWIND_HIDDEN Registers_x86_64; -extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *); +class _LIBUNWIND_HIDDEN Registers_x86_64; +extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *); #if defined(_LIBUNWIND_USE_CET) extern "C" void *__libunwind_cet_get_jump_target() { @@ -280,13 +280,13 @@ public: bool validFloatRegister(int) const { return false; } double getFloatRegister(int num) const; void setFloatRegister(int num, double value); - bool validVectorRegister(int) const; + bool validVectorRegister(int) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto() { __libunwind_Registers_x86_64_jumpto(this); } - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } - static int getArch() { return REGISTERS_X86_64; } + static const char *getRegisterName(int num); + void jumpto() { __libunwind_Registers_x86_64_jumpto(this); } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } + static int getArch() { return REGISTERS_X86_64; } uint64_t getSP() const { return _registers.__rsp; } void setSP(uint64_t value) { _registers.__rsp = value; } @@ -328,19 +328,19 @@ private: uint64_t __cs; uint64_t __fs; uint64_t __gs; -#if defined(_WIN64) - uint64_t __padding; // 16-byte align -#endif +#if defined(_WIN64) + uint64_t __padding; // 16-byte align +#endif }; GPRs _registers; -#if defined(_WIN64) - v128 _xmm[16]; -#endif +#if defined(_WIN64) + v128 _xmm[16]; +#endif }; inline Registers_x86_64::Registers_x86_64(const void *registers) { - static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit), - "x86_64 registers do not fit into unw_context_t"); + static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit), + "x86_64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); } @@ -503,38 +503,38 @@ inline const char *Registers_x86_64::getRegisterName(int regNum) { return "r14"; case UNW_X86_64_R15: return "r15"; - case UNW_X86_64_XMM0: - return "xmm0"; - case UNW_X86_64_XMM1: - return "xmm1"; - case UNW_X86_64_XMM2: - return "xmm2"; - case UNW_X86_64_XMM3: - return "xmm3"; - case UNW_X86_64_XMM4: - return "xmm4"; - case UNW_X86_64_XMM5: - return "xmm5"; - case UNW_X86_64_XMM6: - return "xmm6"; - case UNW_X86_64_XMM7: - return "xmm7"; - case UNW_X86_64_XMM8: - return "xmm8"; - case UNW_X86_64_XMM9: - return "xmm9"; - case UNW_X86_64_XMM10: - return "xmm10"; - case UNW_X86_64_XMM11: - return "xmm11"; - case UNW_X86_64_XMM12: - return "xmm12"; - case UNW_X86_64_XMM13: - return "xmm13"; - case UNW_X86_64_XMM14: - return "xmm14"; - case UNW_X86_64_XMM15: - return "xmm15"; + case UNW_X86_64_XMM0: + return "xmm0"; + case UNW_X86_64_XMM1: + return "xmm1"; + case UNW_X86_64_XMM2: + return "xmm2"; + case UNW_X86_64_XMM3: + return "xmm3"; + case UNW_X86_64_XMM4: + return "xmm4"; + case UNW_X86_64_XMM5: + return "xmm5"; + case UNW_X86_64_XMM6: + return "xmm6"; + case UNW_X86_64_XMM7: + return "xmm7"; + case UNW_X86_64_XMM8: + return "xmm8"; + case UNW_X86_64_XMM9: + return "xmm9"; + case UNW_X86_64_XMM10: + return "xmm10"; + case UNW_X86_64_XMM11: + return "xmm11"; + case UNW_X86_64_XMM12: + return "xmm12"; + case UNW_X86_64_XMM13: + return "xmm13"; + case UNW_X86_64_XMM14: + return "xmm14"; + case UNW_X86_64_XMM15: + return "xmm15"; default: return "unknown register"; } @@ -548,42 +548,42 @@ inline void Registers_x86_64::setFloatRegister(int, double) { _LIBUNWIND_ABORT("no x86_64 float registers"); } -inline bool Registers_x86_64::validVectorRegister(int regNum) const { -#if defined(_WIN64) - if (regNum < UNW_X86_64_XMM0) - return false; - if (regNum > UNW_X86_64_XMM15) - return false; - return true; -#else - (void)regNum; // suppress unused parameter warning - return false; -#endif -} - -inline v128 Registers_x86_64::getVectorRegister(int regNum) const { -#if defined(_WIN64) - assert(validVectorRegister(regNum)); - return _xmm[regNum - UNW_X86_64_XMM0]; -#else - (void)regNum; // suppress unused parameter warning +inline bool Registers_x86_64::validVectorRegister(int regNum) const { +#if defined(_WIN64) + if (regNum < UNW_X86_64_XMM0) + return false; + if (regNum > UNW_X86_64_XMM15) + return false; + return true; +#else + (void)regNum; // suppress unused parameter warning + return false; +#endif +} + +inline v128 Registers_x86_64::getVectorRegister(int regNum) const { +#if defined(_WIN64) + assert(validVectorRegister(regNum)); + return _xmm[regNum - UNW_X86_64_XMM0]; +#else + (void)regNum; // suppress unused parameter warning _LIBUNWIND_ABORT("no x86_64 vector registers"); -#endif +#endif } -inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) { -#if defined(_WIN64) - assert(validVectorRegister(regNum)); - _xmm[regNum - UNW_X86_64_XMM0] = value; -#else - (void)regNum; (void)value; // suppress unused parameter warnings +inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) { +#if defined(_WIN64) + assert(validVectorRegister(regNum)); + _xmm[regNum - UNW_X86_64_XMM0] = value; +#else + (void)regNum; (void)value; // suppress unused parameter warnings _LIBUNWIND_ABORT("no x86_64 vector registers"); -#endif +#endif } -#endif // _LIBUNWIND_TARGET_X86_64 +#endif // _LIBUNWIND_TARGET_X86_64 -#if defined(_LIBUNWIND_TARGET_PPC) +#if defined(_LIBUNWIND_TARGET_PPC) /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC /// process. class _LIBUNWIND_HIDDEN Registers_ppc { @@ -600,10 +600,10 @@ public: bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); + static const char *getRegisterName(int num); void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } - static int getArch() { return REGISTERS_PPC; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } + static int getArch() { return REGISTERS_PPC; } uint64_t getSP() const { return _registers.__r1; } void setSP(uint32_t value) { _registers.__r1 = value; } @@ -667,8 +667,8 @@ private: }; inline Registers_ppc::Registers_ppc(const void *registers) { - static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit), - "ppc registers do not fit into unw_context_t"); + static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit), + "ppc registers do not fit into unw_context_t"); memcpy(&_registers, static_cast<const uint8_t *>(registers), sizeof(_registers)); static_assert(sizeof(ppc_thread_state_t) == 160, @@ -1147,656 +1147,656 @@ inline const char *Registers_ppc::getRegisterName(int regNum) { } } -#endif // _LIBUNWIND_TARGET_PPC - -#if defined(_LIBUNWIND_TARGET_PPC64) -/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC -/// process. -class _LIBUNWIND_HIDDEN Registers_ppc64 { -public: - Registers_ppc64(); - Registers_ppc64(const void *registers); - - bool validRegister(int num) const; - uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; } - static int getArch() { return REGISTERS_PPC64; } - - uint64_t getSP() const { return _registers.__r1; } - void setSP(uint64_t value) { _registers.__r1 = value; } - uint64_t getIP() const { return _registers.__srr0; } - void setIP(uint64_t value) { _registers.__srr0 = value; } - -private: - struct ppc64_thread_state_t { - uint64_t __srr0; // Instruction address register (PC) - uint64_t __srr1; // Machine state register (supervisor) - uint64_t __r0; - uint64_t __r1; - uint64_t __r2; - uint64_t __r3; - uint64_t __r4; - uint64_t __r5; - uint64_t __r6; - uint64_t __r7; - uint64_t __r8; - uint64_t __r9; - uint64_t __r10; - uint64_t __r11; - uint64_t __r12; - uint64_t __r13; - uint64_t __r14; - uint64_t __r15; - uint64_t __r16; - uint64_t __r17; - uint64_t __r18; - uint64_t __r19; - uint64_t __r20; - uint64_t __r21; - uint64_t __r22; - uint64_t __r23; - uint64_t __r24; - uint64_t __r25; - uint64_t __r26; - uint64_t __r27; - uint64_t __r28; - uint64_t __r29; - uint64_t __r30; - uint64_t __r31; - uint64_t __cr; // Condition register - uint64_t __xer; // User's integer exception register - uint64_t __lr; // Link register - uint64_t __ctr; // Count register - uint64_t __vrsave; // Vector Save Register - }; - - union ppc64_vsr_t { - struct asfloat_s { - double f; - uint64_t v2; - } asfloat; - v128 v; - }; - - ppc64_thread_state_t _registers; - ppc64_vsr_t _vectorScalarRegisters[64]; - - static int getVectorRegNum(int num); -}; - -inline Registers_ppc64::Registers_ppc64(const void *registers) { - static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit), - "ppc64 registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); - static_assert(sizeof(_registers) == 312, - "expected vector scalar register offset to be 312"); - memcpy(&_vectorScalarRegisters, - static_cast<const uint8_t *>(registers) + sizeof(_registers), - sizeof(_vectorScalarRegisters)); - static_assert(sizeof(_registers) + - sizeof(_vectorScalarRegisters) == 1336, - "expected vector register offset to be 1336 bytes"); -} - -inline Registers_ppc64::Registers_ppc64() { - memset(&_registers, 0, sizeof(_registers)); - memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters)); -} - -inline bool Registers_ppc64::validRegister(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - case UNW_REG_SP: - case UNW_PPC64_XER: - case UNW_PPC64_LR: - case UNW_PPC64_CTR: - case UNW_PPC64_VRSAVE: - return true; - } - - if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31) - return true; - if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7) - return true; - - return false; -} - -inline uint64_t Registers_ppc64::getRegister(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registers.__srr0; - case UNW_PPC64_R0: - return _registers.__r0; - case UNW_PPC64_R1: - case UNW_REG_SP: - return _registers.__r1; - case UNW_PPC64_R2: - return _registers.__r2; - case UNW_PPC64_R3: - return _registers.__r3; - case UNW_PPC64_R4: - return _registers.__r4; - case UNW_PPC64_R5: - return _registers.__r5; - case UNW_PPC64_R6: - return _registers.__r6; - case UNW_PPC64_R7: - return _registers.__r7; - case UNW_PPC64_R8: - return _registers.__r8; - case UNW_PPC64_R9: - return _registers.__r9; - case UNW_PPC64_R10: - return _registers.__r10; - case UNW_PPC64_R11: - return _registers.__r11; - case UNW_PPC64_R12: - return _registers.__r12; - case UNW_PPC64_R13: - return _registers.__r13; - case UNW_PPC64_R14: - return _registers.__r14; - case UNW_PPC64_R15: - return _registers.__r15; - case UNW_PPC64_R16: - return _registers.__r16; - case UNW_PPC64_R17: - return _registers.__r17; - case UNW_PPC64_R18: - return _registers.__r18; - case UNW_PPC64_R19: - return _registers.__r19; - case UNW_PPC64_R20: - return _registers.__r20; - case UNW_PPC64_R21: - return _registers.__r21; - case UNW_PPC64_R22: - return _registers.__r22; - case UNW_PPC64_R23: - return _registers.__r23; - case UNW_PPC64_R24: - return _registers.__r24; - case UNW_PPC64_R25: - return _registers.__r25; - case UNW_PPC64_R26: - return _registers.__r26; - case UNW_PPC64_R27: - return _registers.__r27; - case UNW_PPC64_R28: - return _registers.__r28; - case UNW_PPC64_R29: - return _registers.__r29; - case UNW_PPC64_R30: - return _registers.__r30; - case UNW_PPC64_R31: - return _registers.__r31; - case UNW_PPC64_CR0: - return (_registers.__cr & 0xF0000000); - case UNW_PPC64_CR1: - return (_registers.__cr & 0x0F000000); - case UNW_PPC64_CR2: - return (_registers.__cr & 0x00F00000); - case UNW_PPC64_CR3: - return (_registers.__cr & 0x000F0000); - case UNW_PPC64_CR4: - return (_registers.__cr & 0x0000F000); - case UNW_PPC64_CR5: - return (_registers.__cr & 0x00000F00); - case UNW_PPC64_CR6: - return (_registers.__cr & 0x000000F0); - case UNW_PPC64_CR7: - return (_registers.__cr & 0x0000000F); - case UNW_PPC64_XER: - return _registers.__xer; - case UNW_PPC64_LR: - return _registers.__lr; - case UNW_PPC64_CTR: - return _registers.__ctr; - case UNW_PPC64_VRSAVE: - return _registers.__vrsave; - } - _LIBUNWIND_ABORT("unsupported ppc64 register"); -} - -inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { - switch (regNum) { - case UNW_REG_IP: - _registers.__srr0 = value; - return; - case UNW_PPC64_R0: - _registers.__r0 = value; - return; - case UNW_PPC64_R1: - case UNW_REG_SP: - _registers.__r1 = value; - return; - case UNW_PPC64_R2: - _registers.__r2 = value; - return; - case UNW_PPC64_R3: - _registers.__r3 = value; - return; - case UNW_PPC64_R4: - _registers.__r4 = value; - return; - case UNW_PPC64_R5: - _registers.__r5 = value; - return; - case UNW_PPC64_R6: - _registers.__r6 = value; - return; - case UNW_PPC64_R7: - _registers.__r7 = value; - return; - case UNW_PPC64_R8: - _registers.__r8 = value; - return; - case UNW_PPC64_R9: - _registers.__r9 = value; - return; - case UNW_PPC64_R10: - _registers.__r10 = value; - return; - case UNW_PPC64_R11: - _registers.__r11 = value; - return; - case UNW_PPC64_R12: - _registers.__r12 = value; - return; - case UNW_PPC64_R13: - _registers.__r13 = value; - return; - case UNW_PPC64_R14: - _registers.__r14 = value; - return; - case UNW_PPC64_R15: - _registers.__r15 = value; - return; - case UNW_PPC64_R16: - _registers.__r16 = value; - return; - case UNW_PPC64_R17: - _registers.__r17 = value; - return; - case UNW_PPC64_R18: - _registers.__r18 = value; - return; - case UNW_PPC64_R19: - _registers.__r19 = value; - return; - case UNW_PPC64_R20: - _registers.__r20 = value; - return; - case UNW_PPC64_R21: - _registers.__r21 = value; - return; - case UNW_PPC64_R22: - _registers.__r22 = value; - return; - case UNW_PPC64_R23: - _registers.__r23 = value; - return; - case UNW_PPC64_R24: - _registers.__r24 = value; - return; - case UNW_PPC64_R25: - _registers.__r25 = value; - return; - case UNW_PPC64_R26: - _registers.__r26 = value; - return; - case UNW_PPC64_R27: - _registers.__r27 = value; - return; - case UNW_PPC64_R28: - _registers.__r28 = value; - return; - case UNW_PPC64_R29: - _registers.__r29 = value; - return; - case UNW_PPC64_R30: - _registers.__r30 = value; - return; - case UNW_PPC64_R31: - _registers.__r31 = value; - return; - case UNW_PPC64_CR0: - _registers.__cr &= 0x0FFFFFFF; - _registers.__cr |= (value & 0xF0000000); - return; - case UNW_PPC64_CR1: - _registers.__cr &= 0xF0FFFFFF; - _registers.__cr |= (value & 0x0F000000); - return; - case UNW_PPC64_CR2: - _registers.__cr &= 0xFF0FFFFF; - _registers.__cr |= (value & 0x00F00000); - return; - case UNW_PPC64_CR3: - _registers.__cr &= 0xFFF0FFFF; - _registers.__cr |= (value & 0x000F0000); - return; - case UNW_PPC64_CR4: - _registers.__cr &= 0xFFFF0FFF; - _registers.__cr |= (value & 0x0000F000); - return; - case UNW_PPC64_CR5: - _registers.__cr &= 0xFFFFF0FF; - _registers.__cr |= (value & 0x00000F00); - return; - case UNW_PPC64_CR6: - _registers.__cr &= 0xFFFFFF0F; - _registers.__cr |= (value & 0x000000F0); - return; - case UNW_PPC64_CR7: - _registers.__cr &= 0xFFFFFFF0; - _registers.__cr |= (value & 0x0000000F); - return; - case UNW_PPC64_XER: - _registers.__xer = value; - return; - case UNW_PPC64_LR: - _registers.__lr = value; - return; - case UNW_PPC64_CTR: - _registers.__ctr = value; - return; - case UNW_PPC64_VRSAVE: - _registers.__vrsave = value; - return; - } - _LIBUNWIND_ABORT("unsupported ppc64 register"); -} - -inline bool Registers_ppc64::validFloatRegister(int regNum) const { - return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31; -} - -inline double Registers_ppc64::getFloatRegister(int regNum) const { - assert(validFloatRegister(regNum)); - return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f; -} - -inline void Registers_ppc64::setFloatRegister(int regNum, double value) { - assert(validFloatRegister(regNum)); - _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value; -} - -inline bool Registers_ppc64::validVectorRegister(int regNum) const { -#if defined(__VSX__) - if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31) - return true; - if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63) - return true; -#elif defined(__ALTIVEC__) - if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31) - return true; -#endif - return false; -} - -inline int Registers_ppc64::getVectorRegNum(int num) -{ - if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31) - return num - UNW_PPC64_VS0; - else - return num - UNW_PPC64_VS32 + 32; -} - -inline v128 Registers_ppc64::getVectorRegister(int regNum) const { - assert(validVectorRegister(regNum)); - return _vectorScalarRegisters[getVectorRegNum(regNum)].v; -} - -inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) { - assert(validVectorRegister(regNum)); - _vectorScalarRegisters[getVectorRegNum(regNum)].v = value; -} - -inline const char *Registers_ppc64::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "ip"; - case UNW_REG_SP: - return "sp"; - case UNW_PPC64_R0: - return "r0"; - case UNW_PPC64_R1: - return "r1"; - case UNW_PPC64_R2: - return "r2"; - case UNW_PPC64_R3: - return "r3"; - case UNW_PPC64_R4: - return "r4"; - case UNW_PPC64_R5: - return "r5"; - case UNW_PPC64_R6: - return "r6"; - case UNW_PPC64_R7: - return "r7"; - case UNW_PPC64_R8: - return "r8"; - case UNW_PPC64_R9: - return "r9"; - case UNW_PPC64_R10: - return "r10"; - case UNW_PPC64_R11: - return "r11"; - case UNW_PPC64_R12: - return "r12"; - case UNW_PPC64_R13: - return "r13"; - case UNW_PPC64_R14: - return "r14"; - case UNW_PPC64_R15: - return "r15"; - case UNW_PPC64_R16: - return "r16"; - case UNW_PPC64_R17: - return "r17"; - case UNW_PPC64_R18: - return "r18"; - case UNW_PPC64_R19: - return "r19"; - case UNW_PPC64_R20: - return "r20"; - case UNW_PPC64_R21: - return "r21"; - case UNW_PPC64_R22: - return "r22"; - case UNW_PPC64_R23: - return "r23"; - case UNW_PPC64_R24: - return "r24"; - case UNW_PPC64_R25: - return "r25"; - case UNW_PPC64_R26: - return "r26"; - case UNW_PPC64_R27: - return "r27"; - case UNW_PPC64_R28: - return "r28"; - case UNW_PPC64_R29: - return "r29"; - case UNW_PPC64_R30: - return "r30"; - case UNW_PPC64_R31: - return "r31"; - case UNW_PPC64_CR0: - return "cr0"; - case UNW_PPC64_CR1: - return "cr1"; - case UNW_PPC64_CR2: - return "cr2"; - case UNW_PPC64_CR3: - return "cr3"; - case UNW_PPC64_CR4: - return "cr4"; - case UNW_PPC64_CR5: - return "cr5"; - case UNW_PPC64_CR6: - return "cr6"; - case UNW_PPC64_CR7: - return "cr7"; - case UNW_PPC64_XER: - return "xer"; - case UNW_PPC64_LR: - return "lr"; - case UNW_PPC64_CTR: - return "ctr"; - case UNW_PPC64_VRSAVE: - return "vrsave"; - case UNW_PPC64_F0: - return "fp0"; - case UNW_PPC64_F1: - return "fp1"; - case UNW_PPC64_F2: - return "fp2"; - case UNW_PPC64_F3: - return "fp3"; - case UNW_PPC64_F4: - return "fp4"; - case UNW_PPC64_F5: - return "fp5"; - case UNW_PPC64_F6: - return "fp6"; - case UNW_PPC64_F7: - return "fp7"; - case UNW_PPC64_F8: - return "fp8"; - case UNW_PPC64_F9: - return "fp9"; - case UNW_PPC64_F10: - return "fp10"; - case UNW_PPC64_F11: - return "fp11"; - case UNW_PPC64_F12: - return "fp12"; - case UNW_PPC64_F13: - return "fp13"; - case UNW_PPC64_F14: - return "fp14"; - case UNW_PPC64_F15: - return "fp15"; - case UNW_PPC64_F16: - return "fp16"; - case UNW_PPC64_F17: - return "fp17"; - case UNW_PPC64_F18: - return "fp18"; - case UNW_PPC64_F19: - return "fp19"; - case UNW_PPC64_F20: - return "fp20"; - case UNW_PPC64_F21: - return "fp21"; - case UNW_PPC64_F22: - return "fp22"; - case UNW_PPC64_F23: - return "fp23"; - case UNW_PPC64_F24: - return "fp24"; - case UNW_PPC64_F25: - return "fp25"; - case UNW_PPC64_F26: - return "fp26"; - case UNW_PPC64_F27: - return "fp27"; - case UNW_PPC64_F28: - return "fp28"; - case UNW_PPC64_F29: - return "fp29"; - case UNW_PPC64_F30: - return "fp30"; - case UNW_PPC64_F31: - return "fp31"; - case UNW_PPC64_V0: - return "v0"; - case UNW_PPC64_V1: - return "v1"; - case UNW_PPC64_V2: - return "v2"; - case UNW_PPC64_V3: - return "v3"; - case UNW_PPC64_V4: - return "v4"; - case UNW_PPC64_V5: - return "v5"; - case UNW_PPC64_V6: - return "v6"; - case UNW_PPC64_V7: - return "v7"; - case UNW_PPC64_V8: - return "v8"; - case UNW_PPC64_V9: - return "v9"; - case UNW_PPC64_V10: - return "v10"; - case UNW_PPC64_V11: - return "v11"; - case UNW_PPC64_V12: - return "v12"; - case UNW_PPC64_V13: - return "v13"; - case UNW_PPC64_V14: - return "v14"; - case UNW_PPC64_V15: - return "v15"; - case UNW_PPC64_V16: - return "v16"; - case UNW_PPC64_V17: - return "v17"; - case UNW_PPC64_V18: - return "v18"; - case UNW_PPC64_V19: - return "v19"; - case UNW_PPC64_V20: - return "v20"; - case UNW_PPC64_V21: - return "v21"; - case UNW_PPC64_V22: - return "v22"; - case UNW_PPC64_V23: - return "v23"; - case UNW_PPC64_V24: - return "v24"; - case UNW_PPC64_V25: - return "v25"; - case UNW_PPC64_V26: - return "v26"; - case UNW_PPC64_V27: - return "v27"; - case UNW_PPC64_V28: - return "v28"; - case UNW_PPC64_V29: - return "v29"; - case UNW_PPC64_V30: - return "v30"; - case UNW_PPC64_V31: - return "v31"; - } - return "unknown register"; -} -#endif // _LIBUNWIND_TARGET_PPC64 - - -#if defined(_LIBUNWIND_TARGET_AARCH64) +#endif // _LIBUNWIND_TARGET_PPC + +#if defined(_LIBUNWIND_TARGET_PPC64) +/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC +/// process. +class _LIBUNWIND_HIDDEN Registers_ppc64 { +public: + Registers_ppc64(); + Registers_ppc64(const void *registers); + + bool validRegister(int num) const; + uint64_t getRegister(int num) const; + void setRegister(int num, uint64_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; } + static int getArch() { return REGISTERS_PPC64; } + + uint64_t getSP() const { return _registers.__r1; } + void setSP(uint64_t value) { _registers.__r1 = value; } + uint64_t getIP() const { return _registers.__srr0; } + void setIP(uint64_t value) { _registers.__srr0 = value; } + +private: + struct ppc64_thread_state_t { + uint64_t __srr0; // Instruction address register (PC) + uint64_t __srr1; // Machine state register (supervisor) + uint64_t __r0; + uint64_t __r1; + uint64_t __r2; + uint64_t __r3; + uint64_t __r4; + uint64_t __r5; + uint64_t __r6; + uint64_t __r7; + uint64_t __r8; + uint64_t __r9; + uint64_t __r10; + uint64_t __r11; + uint64_t __r12; + uint64_t __r13; + uint64_t __r14; + uint64_t __r15; + uint64_t __r16; + uint64_t __r17; + uint64_t __r18; + uint64_t __r19; + uint64_t __r20; + uint64_t __r21; + uint64_t __r22; + uint64_t __r23; + uint64_t __r24; + uint64_t __r25; + uint64_t __r26; + uint64_t __r27; + uint64_t __r28; + uint64_t __r29; + uint64_t __r30; + uint64_t __r31; + uint64_t __cr; // Condition register + uint64_t __xer; // User's integer exception register + uint64_t __lr; // Link register + uint64_t __ctr; // Count register + uint64_t __vrsave; // Vector Save Register + }; + + union ppc64_vsr_t { + struct asfloat_s { + double f; + uint64_t v2; + } asfloat; + v128 v; + }; + + ppc64_thread_state_t _registers; + ppc64_vsr_t _vectorScalarRegisters[64]; + + static int getVectorRegNum(int num); +}; + +inline Registers_ppc64::Registers_ppc64(const void *registers) { + static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit), + "ppc64 registers do not fit into unw_context_t"); + memcpy(&_registers, static_cast<const uint8_t *>(registers), + sizeof(_registers)); + static_assert(sizeof(_registers) == 312, + "expected vector scalar register offset to be 312"); + memcpy(&_vectorScalarRegisters, + static_cast<const uint8_t *>(registers) + sizeof(_registers), + sizeof(_vectorScalarRegisters)); + static_assert(sizeof(_registers) + + sizeof(_vectorScalarRegisters) == 1336, + "expected vector register offset to be 1336 bytes"); +} + +inline Registers_ppc64::Registers_ppc64() { + memset(&_registers, 0, sizeof(_registers)); + memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters)); +} + +inline bool Registers_ppc64::validRegister(int regNum) const { + switch (regNum) { + case UNW_REG_IP: + case UNW_REG_SP: + case UNW_PPC64_XER: + case UNW_PPC64_LR: + case UNW_PPC64_CTR: + case UNW_PPC64_VRSAVE: + return true; + } + + if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31) + return true; + if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7) + return true; + + return false; +} + +inline uint64_t Registers_ppc64::getRegister(int regNum) const { + switch (regNum) { + case UNW_REG_IP: + return _registers.__srr0; + case UNW_PPC64_R0: + return _registers.__r0; + case UNW_PPC64_R1: + case UNW_REG_SP: + return _registers.__r1; + case UNW_PPC64_R2: + return _registers.__r2; + case UNW_PPC64_R3: + return _registers.__r3; + case UNW_PPC64_R4: + return _registers.__r4; + case UNW_PPC64_R5: + return _registers.__r5; + case UNW_PPC64_R6: + return _registers.__r6; + case UNW_PPC64_R7: + return _registers.__r7; + case UNW_PPC64_R8: + return _registers.__r8; + case UNW_PPC64_R9: + return _registers.__r9; + case UNW_PPC64_R10: + return _registers.__r10; + case UNW_PPC64_R11: + return _registers.__r11; + case UNW_PPC64_R12: + return _registers.__r12; + case UNW_PPC64_R13: + return _registers.__r13; + case UNW_PPC64_R14: + return _registers.__r14; + case UNW_PPC64_R15: + return _registers.__r15; + case UNW_PPC64_R16: + return _registers.__r16; + case UNW_PPC64_R17: + return _registers.__r17; + case UNW_PPC64_R18: + return _registers.__r18; + case UNW_PPC64_R19: + return _registers.__r19; + case UNW_PPC64_R20: + return _registers.__r20; + case UNW_PPC64_R21: + return _registers.__r21; + case UNW_PPC64_R22: + return _registers.__r22; + case UNW_PPC64_R23: + return _registers.__r23; + case UNW_PPC64_R24: + return _registers.__r24; + case UNW_PPC64_R25: + return _registers.__r25; + case UNW_PPC64_R26: + return _registers.__r26; + case UNW_PPC64_R27: + return _registers.__r27; + case UNW_PPC64_R28: + return _registers.__r28; + case UNW_PPC64_R29: + return _registers.__r29; + case UNW_PPC64_R30: + return _registers.__r30; + case UNW_PPC64_R31: + return _registers.__r31; + case UNW_PPC64_CR0: + return (_registers.__cr & 0xF0000000); + case UNW_PPC64_CR1: + return (_registers.__cr & 0x0F000000); + case UNW_PPC64_CR2: + return (_registers.__cr & 0x00F00000); + case UNW_PPC64_CR3: + return (_registers.__cr & 0x000F0000); + case UNW_PPC64_CR4: + return (_registers.__cr & 0x0000F000); + case UNW_PPC64_CR5: + return (_registers.__cr & 0x00000F00); + case UNW_PPC64_CR6: + return (_registers.__cr & 0x000000F0); + case UNW_PPC64_CR7: + return (_registers.__cr & 0x0000000F); + case UNW_PPC64_XER: + return _registers.__xer; + case UNW_PPC64_LR: + return _registers.__lr; + case UNW_PPC64_CTR: + return _registers.__ctr; + case UNW_PPC64_VRSAVE: + return _registers.__vrsave; + } + _LIBUNWIND_ABORT("unsupported ppc64 register"); +} + +inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { + switch (regNum) { + case UNW_REG_IP: + _registers.__srr0 = value; + return; + case UNW_PPC64_R0: + _registers.__r0 = value; + return; + case UNW_PPC64_R1: + case UNW_REG_SP: + _registers.__r1 = value; + return; + case UNW_PPC64_R2: + _registers.__r2 = value; + return; + case UNW_PPC64_R3: + _registers.__r3 = value; + return; + case UNW_PPC64_R4: + _registers.__r4 = value; + return; + case UNW_PPC64_R5: + _registers.__r5 = value; + return; + case UNW_PPC64_R6: + _registers.__r6 = value; + return; + case UNW_PPC64_R7: + _registers.__r7 = value; + return; + case UNW_PPC64_R8: + _registers.__r8 = value; + return; + case UNW_PPC64_R9: + _registers.__r9 = value; + return; + case UNW_PPC64_R10: + _registers.__r10 = value; + return; + case UNW_PPC64_R11: + _registers.__r11 = value; + return; + case UNW_PPC64_R12: + _registers.__r12 = value; + return; + case UNW_PPC64_R13: + _registers.__r13 = value; + return; + case UNW_PPC64_R14: + _registers.__r14 = value; + return; + case UNW_PPC64_R15: + _registers.__r15 = value; + return; + case UNW_PPC64_R16: + _registers.__r16 = value; + return; + case UNW_PPC64_R17: + _registers.__r17 = value; + return; + case UNW_PPC64_R18: + _registers.__r18 = value; + return; + case UNW_PPC64_R19: + _registers.__r19 = value; + return; + case UNW_PPC64_R20: + _registers.__r20 = value; + return; + case UNW_PPC64_R21: + _registers.__r21 = value; + return; + case UNW_PPC64_R22: + _registers.__r22 = value; + return; + case UNW_PPC64_R23: + _registers.__r23 = value; + return; + case UNW_PPC64_R24: + _registers.__r24 = value; + return; + case UNW_PPC64_R25: + _registers.__r25 = value; + return; + case UNW_PPC64_R26: + _registers.__r26 = value; + return; + case UNW_PPC64_R27: + _registers.__r27 = value; + return; + case UNW_PPC64_R28: + _registers.__r28 = value; + return; + case UNW_PPC64_R29: + _registers.__r29 = value; + return; + case UNW_PPC64_R30: + _registers.__r30 = value; + return; + case UNW_PPC64_R31: + _registers.__r31 = value; + return; + case UNW_PPC64_CR0: + _registers.__cr &= 0x0FFFFFFF; + _registers.__cr |= (value & 0xF0000000); + return; + case UNW_PPC64_CR1: + _registers.__cr &= 0xF0FFFFFF; + _registers.__cr |= (value & 0x0F000000); + return; + case UNW_PPC64_CR2: + _registers.__cr &= 0xFF0FFFFF; + _registers.__cr |= (value & 0x00F00000); + return; + case UNW_PPC64_CR3: + _registers.__cr &= 0xFFF0FFFF; + _registers.__cr |= (value & 0x000F0000); + return; + case UNW_PPC64_CR4: + _registers.__cr &= 0xFFFF0FFF; + _registers.__cr |= (value & 0x0000F000); + return; + case UNW_PPC64_CR5: + _registers.__cr &= 0xFFFFF0FF; + _registers.__cr |= (value & 0x00000F00); + return; + case UNW_PPC64_CR6: + _registers.__cr &= 0xFFFFFF0F; + _registers.__cr |= (value & 0x000000F0); + return; + case UNW_PPC64_CR7: + _registers.__cr &= 0xFFFFFFF0; + _registers.__cr |= (value & 0x0000000F); + return; + case UNW_PPC64_XER: + _registers.__xer = value; + return; + case UNW_PPC64_LR: + _registers.__lr = value; + return; + case UNW_PPC64_CTR: + _registers.__ctr = value; + return; + case UNW_PPC64_VRSAVE: + _registers.__vrsave = value; + return; + } + _LIBUNWIND_ABORT("unsupported ppc64 register"); +} + +inline bool Registers_ppc64::validFloatRegister(int regNum) const { + return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31; +} + +inline double Registers_ppc64::getFloatRegister(int regNum) const { + assert(validFloatRegister(regNum)); + return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f; +} + +inline void Registers_ppc64::setFloatRegister(int regNum, double value) { + assert(validFloatRegister(regNum)); + _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value; +} + +inline bool Registers_ppc64::validVectorRegister(int regNum) const { +#if defined(__VSX__) + if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31) + return true; + if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63) + return true; +#elif defined(__ALTIVEC__) + if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31) + return true; +#endif + return false; +} + +inline int Registers_ppc64::getVectorRegNum(int num) +{ + if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31) + return num - UNW_PPC64_VS0; + else + return num - UNW_PPC64_VS32 + 32; +} + +inline v128 Registers_ppc64::getVectorRegister(int regNum) const { + assert(validVectorRegister(regNum)); + return _vectorScalarRegisters[getVectorRegNum(regNum)].v; +} + +inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) { + assert(validVectorRegister(regNum)); + _vectorScalarRegisters[getVectorRegNum(regNum)].v = value; +} + +inline const char *Registers_ppc64::getRegisterName(int regNum) { + switch (regNum) { + case UNW_REG_IP: + return "ip"; + case UNW_REG_SP: + return "sp"; + case UNW_PPC64_R0: + return "r0"; + case UNW_PPC64_R1: + return "r1"; + case UNW_PPC64_R2: + return "r2"; + case UNW_PPC64_R3: + return "r3"; + case UNW_PPC64_R4: + return "r4"; + case UNW_PPC64_R5: + return "r5"; + case UNW_PPC64_R6: + return "r6"; + case UNW_PPC64_R7: + return "r7"; + case UNW_PPC64_R8: + return "r8"; + case UNW_PPC64_R9: + return "r9"; + case UNW_PPC64_R10: + return "r10"; + case UNW_PPC64_R11: + return "r11"; + case UNW_PPC64_R12: + return "r12"; + case UNW_PPC64_R13: + return "r13"; + case UNW_PPC64_R14: + return "r14"; + case UNW_PPC64_R15: + return "r15"; + case UNW_PPC64_R16: + return "r16"; + case UNW_PPC64_R17: + return "r17"; + case UNW_PPC64_R18: + return "r18"; + case UNW_PPC64_R19: + return "r19"; + case UNW_PPC64_R20: + return "r20"; + case UNW_PPC64_R21: + return "r21"; + case UNW_PPC64_R22: + return "r22"; + case UNW_PPC64_R23: + return "r23"; + case UNW_PPC64_R24: + return "r24"; + case UNW_PPC64_R25: + return "r25"; + case UNW_PPC64_R26: + return "r26"; + case UNW_PPC64_R27: + return "r27"; + case UNW_PPC64_R28: + return "r28"; + case UNW_PPC64_R29: + return "r29"; + case UNW_PPC64_R30: + return "r30"; + case UNW_PPC64_R31: + return "r31"; + case UNW_PPC64_CR0: + return "cr0"; + case UNW_PPC64_CR1: + return "cr1"; + case UNW_PPC64_CR2: + return "cr2"; + case UNW_PPC64_CR3: + return "cr3"; + case UNW_PPC64_CR4: + return "cr4"; + case UNW_PPC64_CR5: + return "cr5"; + case UNW_PPC64_CR6: + return "cr6"; + case UNW_PPC64_CR7: + return "cr7"; + case UNW_PPC64_XER: + return "xer"; + case UNW_PPC64_LR: + return "lr"; + case UNW_PPC64_CTR: + return "ctr"; + case UNW_PPC64_VRSAVE: + return "vrsave"; + case UNW_PPC64_F0: + return "fp0"; + case UNW_PPC64_F1: + return "fp1"; + case UNW_PPC64_F2: + return "fp2"; + case UNW_PPC64_F3: + return "fp3"; + case UNW_PPC64_F4: + return "fp4"; + case UNW_PPC64_F5: + return "fp5"; + case UNW_PPC64_F6: + return "fp6"; + case UNW_PPC64_F7: + return "fp7"; + case UNW_PPC64_F8: + return "fp8"; + case UNW_PPC64_F9: + return "fp9"; + case UNW_PPC64_F10: + return "fp10"; + case UNW_PPC64_F11: + return "fp11"; + case UNW_PPC64_F12: + return "fp12"; + case UNW_PPC64_F13: + return "fp13"; + case UNW_PPC64_F14: + return "fp14"; + case UNW_PPC64_F15: + return "fp15"; + case UNW_PPC64_F16: + return "fp16"; + case UNW_PPC64_F17: + return "fp17"; + case UNW_PPC64_F18: + return "fp18"; + case UNW_PPC64_F19: + return "fp19"; + case UNW_PPC64_F20: + return "fp20"; + case UNW_PPC64_F21: + return "fp21"; + case UNW_PPC64_F22: + return "fp22"; + case UNW_PPC64_F23: + return "fp23"; + case UNW_PPC64_F24: + return "fp24"; + case UNW_PPC64_F25: + return "fp25"; + case UNW_PPC64_F26: + return "fp26"; + case UNW_PPC64_F27: + return "fp27"; + case UNW_PPC64_F28: + return "fp28"; + case UNW_PPC64_F29: + return "fp29"; + case UNW_PPC64_F30: + return "fp30"; + case UNW_PPC64_F31: + return "fp31"; + case UNW_PPC64_V0: + return "v0"; + case UNW_PPC64_V1: + return "v1"; + case UNW_PPC64_V2: + return "v2"; + case UNW_PPC64_V3: + return "v3"; + case UNW_PPC64_V4: + return "v4"; + case UNW_PPC64_V5: + return "v5"; + case UNW_PPC64_V6: + return "v6"; + case UNW_PPC64_V7: + return "v7"; + case UNW_PPC64_V8: + return "v8"; + case UNW_PPC64_V9: + return "v9"; + case UNW_PPC64_V10: + return "v10"; + case UNW_PPC64_V11: + return "v11"; + case UNW_PPC64_V12: + return "v12"; + case UNW_PPC64_V13: + return "v13"; + case UNW_PPC64_V14: + return "v14"; + case UNW_PPC64_V15: + return "v15"; + case UNW_PPC64_V16: + return "v16"; + case UNW_PPC64_V17: + return "v17"; + case UNW_PPC64_V18: + return "v18"; + case UNW_PPC64_V19: + return "v19"; + case UNW_PPC64_V20: + return "v20"; + case UNW_PPC64_V21: + return "v21"; + case UNW_PPC64_V22: + return "v22"; + case UNW_PPC64_V23: + return "v23"; + case UNW_PPC64_V24: + return "v24"; + case UNW_PPC64_V25: + return "v25"; + case UNW_PPC64_V26: + return "v26"; + case UNW_PPC64_V27: + return "v27"; + case UNW_PPC64_V28: + return "v28"; + case UNW_PPC64_V29: + return "v29"; + case UNW_PPC64_V30: + return "v30"; + case UNW_PPC64_V31: + return "v31"; + } + return "unknown register"; +} +#endif // _LIBUNWIND_TARGET_PPC64 + + +#if defined(_LIBUNWIND_TARGET_AARCH64) /// Registers_arm64 holds the register state of a thread in a 64-bit arm /// process. -class _LIBUNWIND_HIDDEN Registers_arm64; -extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); +class _LIBUNWIND_HIDDEN Registers_arm64; +extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); class _LIBUNWIND_HIDDEN Registers_arm64 { public: Registers_arm64(); @@ -1811,10 +1811,10 @@ public: bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto() { __libunwind_Registers_arm64_jumpto(this); } - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } - static int getArch() { return REGISTERS_ARM64; } + static const char *getRegisterName(int num); + void jumpto() { __libunwind_Registers_arm64_jumpto(this); } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } + static int getArch() { return REGISTERS_ARM64; } uint64_t getSP() const { return _registers.__sp; } void setSP(uint64_t value) { _registers.__sp = value; } @@ -1830,7 +1830,7 @@ private: uint64_t __lr; // Link register x30 uint64_t __sp; // Stack pointer x31 uint64_t __pc; // Program counter - uint64_t __ra_sign_state; // RA sign state register + uint64_t __ra_sign_state; // RA sign state register }; GPRs _registers; @@ -1842,8 +1842,8 @@ private: }; inline Registers_arm64::Registers_arm64(const void *registers) { - static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit), - "arm64 registers do not fit into unw_context_t"); + static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit), + "arm64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); static_assert(sizeof(GPRs) == 0x110, "expected VFP registers to be at offset 272"); @@ -1867,7 +1867,7 @@ inline bool Registers_arm64::validRegister(int regNum) const { if (regNum > 95) return false; if (regNum == UNW_AARCH64_RA_SIGN_STATE) - return true; + return true; if ((regNum > 32) && (regNum < 64)) return false; return true; @@ -1879,7 +1879,7 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const { if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) return _registers.__sp; if (regNum == UNW_AARCH64_RA_SIGN_STATE) - return _registers.__ra_sign_state; + return _registers.__ra_sign_state; if (regNum == UNW_AARCH64_FP) return _registers.__fp; if (regNum == UNW_AARCH64_LR) @@ -1895,7 +1895,7 @@ inline void Registers_arm64::setRegister(int regNum, uint64_t value) { else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) _registers.__sp = value; else if (regNum == UNW_AARCH64_RA_SIGN_STATE) - _registers.__ra_sign_state = value; + _registers.__ra_sign_state = value; else if (regNum == UNW_AARCH64_FP) _registers.__fp = value; else if (regNum == UNW_AARCH64_LR) @@ -2076,9 +2076,9 @@ inline v128 Registers_arm64::getVectorRegister(int) const { inline void Registers_arm64::setVectorRegister(int, v128) { _LIBUNWIND_ABORT("no arm64 vector register support yet"); } -#endif // _LIBUNWIND_TARGET_AARCH64 +#endif // _LIBUNWIND_TARGET_AARCH64 -#if defined(_LIBUNWIND_TARGET_ARM) +#if defined(_LIBUNWIND_TARGET_ARM) /// Registers_arm holds the register state of a thread in a 32-bit arm /// process. /// @@ -2090,7 +2090,7 @@ public: Registers_arm(const void *registers); bool validRegister(int num) const; - uint32_t getRegister(int num) const; + uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; unw_fpreg_t getFloatRegister(int num); @@ -2098,13 +2098,13 @@ public: bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); + static const char *getRegisterName(int num); void jumpto() { restoreSavedFloatRegisters(); restoreCoreAndJumpTo(); } - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; } - static int getArch() { return REGISTERS_ARM; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; } + static int getArch() { return REGISTERS_ARM; } uint32_t getSP() const { return _registers.__sp; } void setSP(uint32_t value) { _registers.__sp = value; } @@ -2125,12 +2125,12 @@ public: } if (_saved_vfp_d16_d31) restoreVFPv3(_vfp_d16_d31); -#if defined(__ARM_WMMX) +#if defined(__ARM_WMMX) if (_saved_iwmmx) restoreiWMMX(_iwmmx); if (_saved_iwmmx_control) restoreiWMMXControl(_iwmmx_control); -#endif +#endif } private: @@ -2145,18 +2145,18 @@ private: uint32_t __pac; // Return Authentication Code (PAC) }; - static void saveVFPWithFSTMD(void*); - static void saveVFPWithFSTMX(void*); - static void saveVFPv3(void*); - static void restoreVFPWithFLDMD(void*); - static void restoreVFPWithFLDMX(void*); - static void restoreVFPv3(void*); -#if defined(__ARM_WMMX) - static void saveiWMMX(void*); + static void saveVFPWithFSTMD(void*); + static void saveVFPWithFSTMX(void*); + static void saveVFPv3(void*); + static void restoreVFPWithFLDMD(void*); + static void restoreVFPWithFLDMX(void*); + static void restoreVFPv3(void*); +#if defined(__ARM_WMMX) + static void saveiWMMX(void*); static void saveiWMMXControl(uint32_t*); - static void restoreiWMMX(void*); + static void restoreiWMMX(void*); static void restoreiWMMXControl(uint32_t*); -#endif +#endif void restoreCoreAndJumpTo(); // ARM registers @@ -2179,51 +2179,51 @@ private: unw_fpreg_t _vfp_d0_d15_pad[17]; // VFPv3 registers D16-D31, always saved using FSTMD unw_fpreg_t _vfp_d16_d31[16]; -#if defined(__ARM_WMMX) - // Whether iWMMX data registers are saved. - bool _saved_iwmmx; - // Whether iWMMX control registers are saved. - mutable bool _saved_iwmmx_control; +#if defined(__ARM_WMMX) + // Whether iWMMX data registers are saved. + bool _saved_iwmmx; + // Whether iWMMX control registers are saved. + mutable bool _saved_iwmmx_control; // iWMMX registers unw_fpreg_t _iwmmx[16]; // iWMMX control registers - mutable uint32_t _iwmmx_control[4]; -#endif + mutable uint32_t _iwmmx_control[4]; +#endif }; inline Registers_arm::Registers_arm(const void *registers) : _use_X_for_vfp_save(false), _saved_vfp_d0_d15(false), - _saved_vfp_d16_d31(false) { - static_assert((check_fit<Registers_arm, unw_context_t>::does_fit), - "arm registers do not fit into unw_context_t"); - // See __unw_getcontext() note about data. + _saved_vfp_d16_d31(false) { + static_assert((check_fit<Registers_arm, unw_context_t>::does_fit), + "arm registers do not fit into unw_context_t"); + // See __unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); -#if defined(__ARM_WMMX) - _saved_iwmmx = false; - _saved_iwmmx_control = false; +#if defined(__ARM_WMMX) + _saved_iwmmx = false; + _saved_iwmmx_control = false; memset(&_iwmmx, 0, sizeof(_iwmmx)); memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); -#endif +#endif } inline Registers_arm::Registers_arm() : _use_X_for_vfp_save(false), _saved_vfp_d0_d15(false), - _saved_vfp_d16_d31(false) { + _saved_vfp_d16_d31(false) { memset(&_registers, 0, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); -#if defined(__ARM_WMMX) - _saved_iwmmx = false; - _saved_iwmmx_control = false; +#if defined(__ARM_WMMX) + _saved_iwmmx = false; + _saved_iwmmx_control = false; memset(&_iwmmx, 0, sizeof(_iwmmx)); memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); -#endif +#endif } inline bool Registers_arm::validRegister(int regNum) const { @@ -2231,18 +2231,18 @@ inline bool Registers_arm::validRegister(int regNum) const { // virtual register set (VRS). if (regNum == UNW_REG_IP) return true; - + if (regNum == UNW_REG_SP) return true; - + if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) return true; - -#if defined(__ARM_WMMX) + +#if defined(__ARM_WMMX) if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) return true; -#endif - +#endif + #ifdef __ARM_FEATURE_PAUTH if (regNum == UNW_ARM_RA_AUTH_CODE) return true; @@ -2251,20 +2251,20 @@ inline bool Registers_arm::validRegister(int regNum) const { return false; } -inline uint32_t Registers_arm::getRegister(int regNum) const { +inline uint32_t Registers_arm::getRegister(int regNum) const { if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) return _registers.__sp; - + if (regNum == UNW_ARM_LR) return _registers.__lr; - + if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) return _registers.__pc; - + if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) return _registers.__r[regNum]; - -#if defined(__ARM_WMMX) + +#if defined(__ARM_WMMX) if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { if (!_saved_iwmmx_control) { _saved_iwmmx_control = true; @@ -2272,8 +2272,8 @@ inline uint32_t Registers_arm::getRegister(int regNum) const { } return _iwmmx_control[regNum - UNW_ARM_WC0]; } -#endif - +#endif + #ifdef __ARM_FEATURE_PAUTH if (regNum == UNW_ARM_RA_AUTH_CODE) return _pseudo_registers.__pac; @@ -2283,43 +2283,43 @@ inline uint32_t Registers_arm::getRegister(int regNum) const { } inline void Registers_arm::setRegister(int regNum, uint32_t value) { - if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { + if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { _registers.__sp = value; - return; - } - - if (regNum == UNW_ARM_LR) { + return; + } + + if (regNum == UNW_ARM_LR) { _registers.__lr = value; - return; - } - - if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { + return; + } + + if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { _registers.__pc = value; - return; - } - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { + return; + } + + if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { _registers.__r[regNum] = value; - return; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { + return; + } + +#if defined(__ARM_WMMX) + if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { if (!_saved_iwmmx_control) { _saved_iwmmx_control = true; saveiWMMXControl(_iwmmx_control); } _iwmmx_control[regNum - UNW_ARM_WC0] = value; - return; - } -#endif - + return; + } +#endif + if (regNum == UNW_ARM_RA_AUTH_CODE) { _pseudo_registers.__pac = value; return; } - _LIBUNWIND_ABORT("unsupported arm register"); + _LIBUNWIND_ABORT("unsupported arm register"); } inline const char *Registers_arm::getRegisterName(int regNum) { @@ -2493,12 +2493,12 @@ inline const char *Registers_arm::getRegisterName(int regNum) { inline bool Registers_arm::validFloatRegister(int regNum) const { // NOTE: Consider the intel MMX registers floating points so the - // __unw_get_fpreg can be used to transmit the 64-bit data back. + // __unw_get_fpreg can be used to transmit the 64-bit data back. return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) -#if defined(__ARM_WMMX) - || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)) -#endif - ; +#if defined(__ARM_WMMX) + || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)) +#endif + ; } inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { @@ -2511,27 +2511,27 @@ inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { saveVFPWithFSTMD(_vfp_d0_d15_pad); } return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; - } - - if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { + } + + if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { if (!_saved_vfp_d16_d31) { _saved_vfp_d16_d31 = true; saveVFPv3(_vfp_d16_d31); } return _vfp_d16_d31[regNum - UNW_ARM_D16]; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { + } + +#if defined(__ARM_WMMX) + if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { if (!_saved_iwmmx) { _saved_iwmmx = true; saveiWMMX(_iwmmx); } return _iwmmx[regNum - UNW_ARM_WR0]; } -#endif - - _LIBUNWIND_ABORT("Unknown ARM float register"); +#endif + + _LIBUNWIND_ABORT("Unknown ARM float register"); } inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { @@ -2544,30 +2544,30 @@ inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { saveVFPWithFSTMD(_vfp_d0_d15_pad); } _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; - return; - } - - if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { + return; + } + + if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { if (!_saved_vfp_d16_d31) { _saved_vfp_d16_d31 = true; saveVFPv3(_vfp_d16_d31); } _vfp_d16_d31[regNum - UNW_ARM_D16] = value; - return; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { + return; + } + +#if defined(__ARM_WMMX) + if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { if (!_saved_iwmmx) { _saved_iwmmx = true; saveiWMMX(_iwmmx); } _iwmmx[regNum - UNW_ARM_WR0] = value; - return; + return; } -#endif - - _LIBUNWIND_ABORT("Unknown ARM float register"); +#endif + + _LIBUNWIND_ABORT("Unknown ARM float register"); } inline bool Registers_arm::validVectorRegister(int) const { @@ -2581,10 +2581,10 @@ inline v128 Registers_arm::getVectorRegister(int) const { inline void Registers_arm::setVectorRegister(int, v128) { _LIBUNWIND_ABORT("ARM vector support not implemented"); } -#endif // _LIBUNWIND_TARGET_ARM - - -#if defined(_LIBUNWIND_TARGET_OR1K) +#endif // _LIBUNWIND_TARGET_ARM + + +#if defined(_LIBUNWIND_TARGET_OR1K) /// Registers_or1k holds the register state of a thread in an OpenRISC1000 /// process. class _LIBUNWIND_HIDDEN Registers_or1k { @@ -2601,29 +2601,29 @@ public: bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); + static const char *getRegisterName(int num); void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } - static int getArch() { return REGISTERS_OR1K; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } + static int getArch() { return REGISTERS_OR1K; } uint64_t getSP() const { return _registers.__r[1]; } void setSP(uint32_t value) { _registers.__r[1] = value; } - uint64_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value) { _registers.__pc = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint32_t value) { _registers.__pc = value; } private: struct or1k_thread_state_t { - unsigned int __r[32]; // r0-r31 - unsigned int __pc; // Program counter - unsigned int __epcr; // Program counter at exception + unsigned int __r[32]; // r0-r31 + unsigned int __pc; // Program counter + unsigned int __epcr; // Program counter at exception }; or1k_thread_state_t _registers; }; inline Registers_or1k::Registers_or1k(const void *registers) { - static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit), - "or1k registers do not fit into unw_context_t"); + static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit), + "or1k registers do not fit into unw_context_t"); memcpy(&_registers, static_cast<const uint8_t *>(registers), sizeof(_registers)); } @@ -2641,8 +2641,8 @@ inline bool Registers_or1k::validRegister(int regNum) const { return false; if (regNum <= UNW_OR1K_R31) return true; - if (regNum == UNW_OR1K_EPCR) - return true; + if (regNum == UNW_OR1K_EPCR) + return true; return false; } @@ -2652,11 +2652,11 @@ inline uint32_t Registers_or1k::getRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: - return _registers.__pc; + return _registers.__pc; case UNW_REG_SP: return _registers.__r[1]; - case UNW_OR1K_EPCR: - return _registers.__epcr; + case UNW_OR1K_EPCR: + return _registers.__epcr; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2669,14 +2669,14 @@ inline void Registers_or1k::setRegister(int regNum, uint32_t value) { switch (regNum) { case UNW_REG_IP: - _registers.__pc = value; + _registers.__pc = value; return; case UNW_REG_SP: _registers.__r[1] = value; return; - case UNW_OR1K_EPCR: - _registers.__epcr = value; - return; + case UNW_OR1K_EPCR: + _registers.__epcr = value; + return; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2772,821 +2772,821 @@ inline const char *Registers_or1k::getRegisterName(int regNum) { return "r30"; case UNW_OR1K_R31: return "r31"; - case UNW_OR1K_EPCR: - return "EPCR"; - default: - return "unknown register"; - } - -} -#endif // _LIBUNWIND_TARGET_OR1K - -#if defined(_LIBUNWIND_TARGET_MIPS_O32) -/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_o32 { -public: - Registers_mips_o32(); - Registers_mips_o32(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } - static int getArch() { return REGISTERS_MIPS_O32; } - - uint32_t getSP() const { return _registers.__r[29]; } - void setSP(uint32_t value) { _registers.__r[29] = value; } - uint32_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value) { _registers.__pc = value; } - -private: - struct mips_o32_thread_state_t { - uint32_t __r[32]; - uint32_t __pc; - uint32_t __hi; - uint32_t __lo; - }; - - mips_o32_thread_state_t _registers; -#ifdef __mips_hard_float - /// O32 with 32-bit floating point registers only uses half of this - /// space. However, using the same layout for 32-bit vs 64-bit - /// floating point registers results in a single context size for - /// O32 with hard float. - uint32_t _padding; - double _floats[32]; -#endif -}; - -inline Registers_mips_o32::Registers_mips_o32(const void *registers) { - static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit), - "mips_o32 registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); -} - -inline Registers_mips_o32::Registers_mips_o32() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_mips_o32::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum <= UNW_MIPS_R31) - return true; -#if __mips_isa_rev != 6 - if (regNum == UNW_MIPS_HI) - return true; - if (regNum == UNW_MIPS_LO) - return true; -#endif -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) - return true; -#endif - // FIXME: DSP accumulator registers, MSA registers - return false; -} - -inline uint32_t Registers_mips_o32::getRegister(int regNum) const { - if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) - return _registers.__r[regNum - UNW_MIPS_R0]; -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { - uint32_t *p; - - if (regNum % 2 == 0) - p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; - else - p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; - return *p; - } -#endif - - switch (regNum) { - case UNW_REG_IP: - return _registers.__pc; - case UNW_REG_SP: - return _registers.__r[29]; - case UNW_MIPS_HI: - return _registers.__hi; - case UNW_MIPS_LO: - return _registers.__lo; - } - _LIBUNWIND_ABORT("unsupported mips_o32 register"); -} - -inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { - if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { - _registers.__r[regNum - UNW_MIPS_R0] = value; - return; - } -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { - uint32_t *p; - - if (regNum % 2 == 0) - p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; - else - p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; - *p = value; - return; - } -#endif - - switch (regNum) { - case UNW_REG_IP: - _registers.__pc = value; - return; - case UNW_REG_SP: - _registers.__r[29] = value; - return; - case UNW_MIPS_HI: - _registers.__hi = value; - return; - case UNW_MIPS_LO: - _registers.__lo = value; - return; - } - _LIBUNWIND_ABORT("unsupported mips_o32 register"); -} - -inline bool Registers_mips_o32::validFloatRegister(int regNum) const { -#if defined(__mips_hard_float) && __mips_fpr == 64 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) - return true; -#else - (void)regNum; -#endif - return false; -} - -inline double Registers_mips_o32::getFloatRegister(int regNum) const { -#if defined(__mips_hard_float) && __mips_fpr == 64 - assert(validFloatRegister(regNum)); - return _floats[regNum - UNW_MIPS_F0]; -#else - (void)regNum; - _LIBUNWIND_ABORT("mips_o32 float support not implemented"); -#endif -} - -inline void Registers_mips_o32::setFloatRegister(int regNum, - double value) { -#if defined(__mips_hard_float) && __mips_fpr == 64 - assert(validFloatRegister(regNum)); - _floats[regNum - UNW_MIPS_F0] = value; -#else - (void)regNum; - (void)value; - _LIBUNWIND_ABORT("mips_o32 float support not implemented"); -#endif -} - -inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const { - return false; -} - -inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); -} - -inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); -} - -inline const char *Registers_mips_o32::getRegisterName(int regNum) { - switch (regNum) { - case UNW_MIPS_R0: - return "$0"; - case UNW_MIPS_R1: - return "$1"; - case UNW_MIPS_R2: - return "$2"; - case UNW_MIPS_R3: - return "$3"; - case UNW_MIPS_R4: - return "$4"; - case UNW_MIPS_R5: - return "$5"; - case UNW_MIPS_R6: - return "$6"; - case UNW_MIPS_R7: - return "$7"; - case UNW_MIPS_R8: - return "$8"; - case UNW_MIPS_R9: - return "$9"; - case UNW_MIPS_R10: - return "$10"; - case UNW_MIPS_R11: - return "$11"; - case UNW_MIPS_R12: - return "$12"; - case UNW_MIPS_R13: - return "$13"; - case UNW_MIPS_R14: - return "$14"; - case UNW_MIPS_R15: - return "$15"; - case UNW_MIPS_R16: - return "$16"; - case UNW_MIPS_R17: - return "$17"; - case UNW_MIPS_R18: - return "$18"; - case UNW_MIPS_R19: - return "$19"; - case UNW_MIPS_R20: - return "$20"; - case UNW_MIPS_R21: - return "$21"; - case UNW_MIPS_R22: - return "$22"; - case UNW_MIPS_R23: - return "$23"; - case UNW_MIPS_R24: - return "$24"; - case UNW_MIPS_R25: - return "$25"; - case UNW_MIPS_R26: - return "$26"; - case UNW_MIPS_R27: - return "$27"; - case UNW_MIPS_R28: - return "$28"; - case UNW_MIPS_R29: - return "$29"; - case UNW_MIPS_R30: - return "$30"; - case UNW_MIPS_R31: - return "$31"; - case UNW_MIPS_F0: - return "$f0"; - case UNW_MIPS_F1: - return "$f1"; - case UNW_MIPS_F2: - return "$f2"; - case UNW_MIPS_F3: - return "$f3"; - case UNW_MIPS_F4: - return "$f4"; - case UNW_MIPS_F5: - return "$f5"; - case UNW_MIPS_F6: - return "$f6"; - case UNW_MIPS_F7: - return "$f7"; - case UNW_MIPS_F8: - return "$f8"; - case UNW_MIPS_F9: - return "$f9"; - case UNW_MIPS_F10: - return "$f10"; - case UNW_MIPS_F11: - return "$f11"; - case UNW_MIPS_F12: - return "$f12"; - case UNW_MIPS_F13: - return "$f13"; - case UNW_MIPS_F14: - return "$f14"; - case UNW_MIPS_F15: - return "$f15"; - case UNW_MIPS_F16: - return "$f16"; - case UNW_MIPS_F17: - return "$f17"; - case UNW_MIPS_F18: - return "$f18"; - case UNW_MIPS_F19: - return "$f19"; - case UNW_MIPS_F20: - return "$f20"; - case UNW_MIPS_F21: - return "$f21"; - case UNW_MIPS_F22: - return "$f22"; - case UNW_MIPS_F23: - return "$f23"; - case UNW_MIPS_F24: - return "$f24"; - case UNW_MIPS_F25: - return "$f25"; - case UNW_MIPS_F26: - return "$f26"; - case UNW_MIPS_F27: - return "$f27"; - case UNW_MIPS_F28: - return "$f28"; - case UNW_MIPS_F29: - return "$f29"; - case UNW_MIPS_F30: - return "$f30"; - case UNW_MIPS_F31: - return "$f31"; - case UNW_MIPS_HI: - return "$hi"; - case UNW_MIPS_LO: - return "$lo"; + case UNW_OR1K_EPCR: + return "EPCR"; default: return "unknown register"; } -} -#endif // _LIBUNWIND_TARGET_MIPS_O32 - -#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) -/// Registers_mips_newabi holds the register state of a thread in a -/// MIPS process using NEWABI (the N32 or N64 ABIs). -class _LIBUNWIND_HIDDEN Registers_mips_newabi { -public: - Registers_mips_newabi(); - Registers_mips_newabi(const void *registers); - - bool validRegister(int num) const; - uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } - static int getArch() { return REGISTERS_MIPS_NEWABI; } - - uint64_t getSP() const { return _registers.__r[29]; } - void setSP(uint64_t value) { _registers.__r[29] = value; } - uint64_t getIP() const { return _registers.__pc; } - void setIP(uint64_t value) { _registers.__pc = value; } - -private: - struct mips_newabi_thread_state_t { - uint64_t __r[32]; - uint64_t __pc; - uint64_t __hi; - uint64_t __lo; - }; - - mips_newabi_thread_state_t _registers; -#ifdef __mips_hard_float - double _floats[32]; -#endif -}; - -inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { - static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit), - "mips_newabi registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); -} - -inline Registers_mips_newabi::Registers_mips_newabi() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_mips_newabi::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum <= UNW_MIPS_R31) - return true; -#if __mips_isa_rev != 6 - if (regNum == UNW_MIPS_HI) - return true; - if (regNum == UNW_MIPS_LO) - return true; -#endif - // FIXME: Hard float, DSP accumulator registers, MSA registers - return false; -} - -inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { - if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) - return _registers.__r[regNum - UNW_MIPS_R0]; - - switch (regNum) { - case UNW_REG_IP: - return _registers.__pc; - case UNW_REG_SP: - return _registers.__r[29]; - case UNW_MIPS_HI: - return _registers.__hi; - case UNW_MIPS_LO: - return _registers.__lo; - } - _LIBUNWIND_ABORT("unsupported mips_newabi register"); -} - -inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { - if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { - _registers.__r[regNum - UNW_MIPS_R0] = value; - return; - } - switch (regNum) { - case UNW_REG_IP: - _registers.__pc = value; - return; - case UNW_REG_SP: - _registers.__r[29] = value; - return; - case UNW_MIPS_HI: - _registers.__hi = value; - return; - case UNW_MIPS_LO: - _registers.__lo = value; - return; - } - _LIBUNWIND_ABORT("unsupported mips_newabi register"); -} - -inline bool Registers_mips_newabi::validFloatRegister(int regNum) const { -#ifdef __mips_hard_float - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) - return true; -#else - (void)regNum; -#endif - return false; -} - -inline double Registers_mips_newabi::getFloatRegister(int regNum) const { -#ifdef __mips_hard_float - assert(validFloatRegister(regNum)); - return _floats[regNum - UNW_MIPS_F0]; -#else - (void)regNum; - _LIBUNWIND_ABORT("mips_newabi float support not implemented"); -#endif -} - -inline void Registers_mips_newabi::setFloatRegister(int regNum, - double value) { -#ifdef __mips_hard_float - assert(validFloatRegister(regNum)); - _floats[regNum - UNW_MIPS_F0] = value; -#else - (void)regNum; - (void)value; - _LIBUNWIND_ABORT("mips_newabi float support not implemented"); -#endif -} - -inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const { - return false; -} - -inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); -} - -inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); -} - -inline const char *Registers_mips_newabi::getRegisterName(int regNum) { - switch (regNum) { - case UNW_MIPS_R0: - return "$0"; - case UNW_MIPS_R1: - return "$1"; - case UNW_MIPS_R2: - return "$2"; - case UNW_MIPS_R3: - return "$3"; - case UNW_MIPS_R4: - return "$4"; - case UNW_MIPS_R5: - return "$5"; - case UNW_MIPS_R6: - return "$6"; - case UNW_MIPS_R7: - return "$7"; - case UNW_MIPS_R8: - return "$8"; - case UNW_MIPS_R9: - return "$9"; - case UNW_MIPS_R10: - return "$10"; - case UNW_MIPS_R11: - return "$11"; - case UNW_MIPS_R12: - return "$12"; - case UNW_MIPS_R13: - return "$13"; - case UNW_MIPS_R14: - return "$14"; - case UNW_MIPS_R15: - return "$15"; - case UNW_MIPS_R16: - return "$16"; - case UNW_MIPS_R17: - return "$17"; - case UNW_MIPS_R18: - return "$18"; - case UNW_MIPS_R19: - return "$19"; - case UNW_MIPS_R20: - return "$20"; - case UNW_MIPS_R21: - return "$21"; - case UNW_MIPS_R22: - return "$22"; - case UNW_MIPS_R23: - return "$23"; - case UNW_MIPS_R24: - return "$24"; - case UNW_MIPS_R25: - return "$25"; - case UNW_MIPS_R26: - return "$26"; - case UNW_MIPS_R27: - return "$27"; - case UNW_MIPS_R28: - return "$28"; - case UNW_MIPS_R29: - return "$29"; - case UNW_MIPS_R30: - return "$30"; - case UNW_MIPS_R31: - return "$31"; - case UNW_MIPS_F0: - return "$f0"; - case UNW_MIPS_F1: - return "$f1"; - case UNW_MIPS_F2: - return "$f2"; - case UNW_MIPS_F3: - return "$f3"; - case UNW_MIPS_F4: - return "$f4"; - case UNW_MIPS_F5: - return "$f5"; - case UNW_MIPS_F6: - return "$f6"; - case UNW_MIPS_F7: - return "$f7"; - case UNW_MIPS_F8: - return "$f8"; - case UNW_MIPS_F9: - return "$f9"; - case UNW_MIPS_F10: - return "$f10"; - case UNW_MIPS_F11: - return "$f11"; - case UNW_MIPS_F12: - return "$f12"; - case UNW_MIPS_F13: - return "$f13"; - case UNW_MIPS_F14: - return "$f14"; - case UNW_MIPS_F15: - return "$f15"; - case UNW_MIPS_F16: - return "$f16"; - case UNW_MIPS_F17: - return "$f17"; - case UNW_MIPS_F18: - return "$f18"; - case UNW_MIPS_F19: - return "$f19"; - case UNW_MIPS_F20: - return "$f20"; - case UNW_MIPS_F21: - return "$f21"; - case UNW_MIPS_F22: - return "$f22"; - case UNW_MIPS_F23: - return "$f23"; - case UNW_MIPS_F24: - return "$f24"; - case UNW_MIPS_F25: - return "$f25"; - case UNW_MIPS_F26: - return "$f26"; - case UNW_MIPS_F27: - return "$f27"; - case UNW_MIPS_F28: - return "$f28"; - case UNW_MIPS_F29: - return "$f29"; - case UNW_MIPS_F30: - return "$f30"; - case UNW_MIPS_F31: - return "$f31"; - case UNW_MIPS_HI: - return "$hi"; - case UNW_MIPS_LO: - return "$lo"; - default: - return "unknown register"; - } -} -#endif // _LIBUNWIND_TARGET_MIPS_NEWABI - -#if defined(_LIBUNWIND_TARGET_SPARC) -/// Registers_sparc holds the register state of a thread in a 32-bit Sparc -/// process. -class _LIBUNWIND_HIDDEN Registers_sparc { -public: - Registers_sparc(); - Registers_sparc(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; } - static int getArch() { return REGISTERS_SPARC; } - - uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; } - void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; } - uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; } - void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; } - -private: - struct sparc_thread_state_t { - unsigned int __regs[32]; - }; - - sparc_thread_state_t _registers; -}; - -inline Registers_sparc::Registers_sparc(const void *registers) { - static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit), - "sparc registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); -} - -inline Registers_sparc::Registers_sparc() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_sparc::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum <= UNW_SPARC_I7) - return true; - return false; -} - -inline uint32_t Registers_sparc::getRegister(int regNum) const { - if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { - return _registers.__regs[regNum]; - } - - switch (regNum) { - case UNW_REG_IP: - return _registers.__regs[UNW_SPARC_O7]; - case UNW_REG_SP: - return _registers.__regs[UNW_SPARC_O6]; - } - _LIBUNWIND_ABORT("unsupported sparc register"); -} - -inline void Registers_sparc::setRegister(int regNum, uint32_t value) { - if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { - _registers.__regs[regNum] = value; - return; - } - - switch (regNum) { - case UNW_REG_IP: - _registers.__regs[UNW_SPARC_O7] = value; - return; - case UNW_REG_SP: - _registers.__regs[UNW_SPARC_O6] = value; - return; - } - _LIBUNWIND_ABORT("unsupported sparc register"); -} - -inline bool Registers_sparc::validFloatRegister(int) const { return false; } - -inline double Registers_sparc::getFloatRegister(int) const { - _LIBUNWIND_ABORT("no Sparc float registers"); -} - -inline void Registers_sparc::setFloatRegister(int, double) { - _LIBUNWIND_ABORT("no Sparc float registers"); -} - -inline bool Registers_sparc::validVectorRegister(int) const { return false; } - -inline v128 Registers_sparc::getVectorRegister(int) const { - _LIBUNWIND_ABORT("no Sparc vector registers"); -} - -inline void Registers_sparc::setVectorRegister(int, v128) { - _LIBUNWIND_ABORT("no Sparc vector registers"); -} - -inline const char *Registers_sparc::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "pc"; - case UNW_SPARC_G0: - return "g0"; - case UNW_SPARC_G1: - return "g1"; - case UNW_SPARC_G2: - return "g2"; - case UNW_SPARC_G3: - return "g3"; - case UNW_SPARC_G4: - return "g4"; - case UNW_SPARC_G5: - return "g5"; - case UNW_SPARC_G6: - return "g6"; - case UNW_SPARC_G7: - return "g7"; - case UNW_SPARC_O0: - return "o0"; - case UNW_SPARC_O1: - return "o1"; - case UNW_SPARC_O2: - return "o2"; - case UNW_SPARC_O3: - return "o3"; - case UNW_SPARC_O4: - return "o4"; - case UNW_SPARC_O5: - return "o5"; - case UNW_REG_SP: - case UNW_SPARC_O6: - return "sp"; - case UNW_SPARC_O7: - return "o7"; - case UNW_SPARC_L0: - return "l0"; - case UNW_SPARC_L1: - return "l1"; - case UNW_SPARC_L2: - return "l2"; - case UNW_SPARC_L3: - return "l3"; - case UNW_SPARC_L4: - return "l4"; - case UNW_SPARC_L5: - return "l5"; - case UNW_SPARC_L6: - return "l6"; - case UNW_SPARC_L7: - return "l7"; - case UNW_SPARC_I0: - return "i0"; - case UNW_SPARC_I1: - return "i1"; - case UNW_SPARC_I2: - return "i2"; - case UNW_SPARC_I3: - return "i3"; - case UNW_SPARC_I4: - return "i4"; - case UNW_SPARC_I5: - return "i5"; - case UNW_SPARC_I6: - return "fp"; - case UNW_SPARC_I7: - return "i7"; - default: - return "unknown register"; - } } -#endif // _LIBUNWIND_TARGET_SPARC - +#endif // _LIBUNWIND_TARGET_OR1K + +#if defined(_LIBUNWIND_TARGET_MIPS_O32) +/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS +/// process. +class _LIBUNWIND_HIDDEN Registers_mips_o32 { +public: + Registers_mips_o32(); + Registers_mips_o32(const void *registers); + + bool validRegister(int num) const; + uint32_t getRegister(int num) const; + void setRegister(int num, uint32_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } + static int getArch() { return REGISTERS_MIPS_O32; } + + uint32_t getSP() const { return _registers.__r[29]; } + void setSP(uint32_t value) { _registers.__r[29] = value; } + uint32_t getIP() const { return _registers.__pc; } + void setIP(uint32_t value) { _registers.__pc = value; } + +private: + struct mips_o32_thread_state_t { + uint32_t __r[32]; + uint32_t __pc; + uint32_t __hi; + uint32_t __lo; + }; + + mips_o32_thread_state_t _registers; +#ifdef __mips_hard_float + /// O32 with 32-bit floating point registers only uses half of this + /// space. However, using the same layout for 32-bit vs 64-bit + /// floating point registers results in a single context size for + /// O32 with hard float. + uint32_t _padding; + double _floats[32]; +#endif +}; + +inline Registers_mips_o32::Registers_mips_o32(const void *registers) { + static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit), + "mips_o32 registers do not fit into unw_context_t"); + memcpy(&_registers, static_cast<const uint8_t *>(registers), + sizeof(_registers)); +} + +inline Registers_mips_o32::Registers_mips_o32() { + memset(&_registers, 0, sizeof(_registers)); +} + +inline bool Registers_mips_o32::validRegister(int regNum) const { + if (regNum == UNW_REG_IP) + return true; + if (regNum == UNW_REG_SP) + return true; + if (regNum < 0) + return false; + if (regNum <= UNW_MIPS_R31) + return true; +#if __mips_isa_rev != 6 + if (regNum == UNW_MIPS_HI) + return true; + if (regNum == UNW_MIPS_LO) + return true; +#endif +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) + return true; +#endif + // FIXME: DSP accumulator registers, MSA registers + return false; +} + +inline uint32_t Registers_mips_o32::getRegister(int regNum) const { + if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) + return _registers.__r[regNum - UNW_MIPS_R0]; +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { + uint32_t *p; + + if (regNum % 2 == 0) + p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; + else + p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; + return *p; + } +#endif + + switch (regNum) { + case UNW_REG_IP: + return _registers.__pc; + case UNW_REG_SP: + return _registers.__r[29]; + case UNW_MIPS_HI: + return _registers.__hi; + case UNW_MIPS_LO: + return _registers.__lo; + } + _LIBUNWIND_ABORT("unsupported mips_o32 register"); +} + +inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { + if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { + _registers.__r[regNum - UNW_MIPS_R0] = value; + return; + } +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { + uint32_t *p; + + if (regNum % 2 == 0) + p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; + else + p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; + *p = value; + return; + } +#endif + + switch (regNum) { + case UNW_REG_IP: + _registers.__pc = value; + return; + case UNW_REG_SP: + _registers.__r[29] = value; + return; + case UNW_MIPS_HI: + _registers.__hi = value; + return; + case UNW_MIPS_LO: + _registers.__lo = value; + return; + } + _LIBUNWIND_ABORT("unsupported mips_o32 register"); +} + +inline bool Registers_mips_o32::validFloatRegister(int regNum) const { +#if defined(__mips_hard_float) && __mips_fpr == 64 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) + return true; +#else + (void)regNum; +#endif + return false; +} + +inline double Registers_mips_o32::getFloatRegister(int regNum) const { +#if defined(__mips_hard_float) && __mips_fpr == 64 + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_MIPS_F0]; +#else + (void)regNum; + _LIBUNWIND_ABORT("mips_o32 float support not implemented"); +#endif +} + +inline void Registers_mips_o32::setFloatRegister(int regNum, + double value) { +#if defined(__mips_hard_float) && __mips_fpr == 64 + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_MIPS_F0] = value; +#else + (void)regNum; + (void)value; + _LIBUNWIND_ABORT("mips_o32 float support not implemented"); +#endif +} + +inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const { + return false; +} + +inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); +} + +inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) { + _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); +} + +inline const char *Registers_mips_o32::getRegisterName(int regNum) { + switch (regNum) { + case UNW_MIPS_R0: + return "$0"; + case UNW_MIPS_R1: + return "$1"; + case UNW_MIPS_R2: + return "$2"; + case UNW_MIPS_R3: + return "$3"; + case UNW_MIPS_R4: + return "$4"; + case UNW_MIPS_R5: + return "$5"; + case UNW_MIPS_R6: + return "$6"; + case UNW_MIPS_R7: + return "$7"; + case UNW_MIPS_R8: + return "$8"; + case UNW_MIPS_R9: + return "$9"; + case UNW_MIPS_R10: + return "$10"; + case UNW_MIPS_R11: + return "$11"; + case UNW_MIPS_R12: + return "$12"; + case UNW_MIPS_R13: + return "$13"; + case UNW_MIPS_R14: + return "$14"; + case UNW_MIPS_R15: + return "$15"; + case UNW_MIPS_R16: + return "$16"; + case UNW_MIPS_R17: + return "$17"; + case UNW_MIPS_R18: + return "$18"; + case UNW_MIPS_R19: + return "$19"; + case UNW_MIPS_R20: + return "$20"; + case UNW_MIPS_R21: + return "$21"; + case UNW_MIPS_R22: + return "$22"; + case UNW_MIPS_R23: + return "$23"; + case UNW_MIPS_R24: + return "$24"; + case UNW_MIPS_R25: + return "$25"; + case UNW_MIPS_R26: + return "$26"; + case UNW_MIPS_R27: + return "$27"; + case UNW_MIPS_R28: + return "$28"; + case UNW_MIPS_R29: + return "$29"; + case UNW_MIPS_R30: + return "$30"; + case UNW_MIPS_R31: + return "$31"; + case UNW_MIPS_F0: + return "$f0"; + case UNW_MIPS_F1: + return "$f1"; + case UNW_MIPS_F2: + return "$f2"; + case UNW_MIPS_F3: + return "$f3"; + case UNW_MIPS_F4: + return "$f4"; + case UNW_MIPS_F5: + return "$f5"; + case UNW_MIPS_F6: + return "$f6"; + case UNW_MIPS_F7: + return "$f7"; + case UNW_MIPS_F8: + return "$f8"; + case UNW_MIPS_F9: + return "$f9"; + case UNW_MIPS_F10: + return "$f10"; + case UNW_MIPS_F11: + return "$f11"; + case UNW_MIPS_F12: + return "$f12"; + case UNW_MIPS_F13: + return "$f13"; + case UNW_MIPS_F14: + return "$f14"; + case UNW_MIPS_F15: + return "$f15"; + case UNW_MIPS_F16: + return "$f16"; + case UNW_MIPS_F17: + return "$f17"; + case UNW_MIPS_F18: + return "$f18"; + case UNW_MIPS_F19: + return "$f19"; + case UNW_MIPS_F20: + return "$f20"; + case UNW_MIPS_F21: + return "$f21"; + case UNW_MIPS_F22: + return "$f22"; + case UNW_MIPS_F23: + return "$f23"; + case UNW_MIPS_F24: + return "$f24"; + case UNW_MIPS_F25: + return "$f25"; + case UNW_MIPS_F26: + return "$f26"; + case UNW_MIPS_F27: + return "$f27"; + case UNW_MIPS_F28: + return "$f28"; + case UNW_MIPS_F29: + return "$f29"; + case UNW_MIPS_F30: + return "$f30"; + case UNW_MIPS_F31: + return "$f31"; + case UNW_MIPS_HI: + return "$hi"; + case UNW_MIPS_LO: + return "$lo"; + default: + return "unknown register"; + } +} +#endif // _LIBUNWIND_TARGET_MIPS_O32 + +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a +/// MIPS process using NEWABI (the N32 or N64 ABIs). +class _LIBUNWIND_HIDDEN Registers_mips_newabi { +public: + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); + + bool validRegister(int num) const; + uint64_t getRegister(int num) const; + void setRegister(int num, uint64_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } + static int getArch() { return REGISTERS_MIPS_NEWABI; } + + uint64_t getSP() const { return _registers.__r[29]; } + void setSP(uint64_t value) { _registers.__r[29] = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint64_t value) { _registers.__pc = value; } + +private: + struct mips_newabi_thread_state_t { + uint64_t __r[32]; + uint64_t __pc; + uint64_t __hi; + uint64_t __lo; + }; + + mips_newabi_thread_state_t _registers; +#ifdef __mips_hard_float + double _floats[32]; +#endif +}; + +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit), + "mips_newabi registers do not fit into unw_context_t"); + memcpy(&_registers, static_cast<const uint8_t *>(registers), + sizeof(_registers)); +} + +inline Registers_mips_newabi::Registers_mips_newabi() { + memset(&_registers, 0, sizeof(_registers)); +} + +inline bool Registers_mips_newabi::validRegister(int regNum) const { + if (regNum == UNW_REG_IP) + return true; + if (regNum == UNW_REG_SP) + return true; + if (regNum < 0) + return false; + if (regNum <= UNW_MIPS_R31) + return true; +#if __mips_isa_rev != 6 + if (regNum == UNW_MIPS_HI) + return true; + if (regNum == UNW_MIPS_LO) + return true; +#endif + // FIXME: Hard float, DSP accumulator registers, MSA registers + return false; +} + +inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { + if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) + return _registers.__r[regNum - UNW_MIPS_R0]; + + switch (regNum) { + case UNW_REG_IP: + return _registers.__pc; + case UNW_REG_SP: + return _registers.__r[29]; + case UNW_MIPS_HI: + return _registers.__hi; + case UNW_MIPS_LO: + return _registers.__lo; + } + _LIBUNWIND_ABORT("unsupported mips_newabi register"); +} + +inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { + if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { + _registers.__r[regNum - UNW_MIPS_R0] = value; + return; + } + + switch (regNum) { + case UNW_REG_IP: + _registers.__pc = value; + return; + case UNW_REG_SP: + _registers.__r[29] = value; + return; + case UNW_MIPS_HI: + _registers.__hi = value; + return; + case UNW_MIPS_LO: + _registers.__lo = value; + return; + } + _LIBUNWIND_ABORT("unsupported mips_newabi register"); +} + +inline bool Registers_mips_newabi::validFloatRegister(int regNum) const { +#ifdef __mips_hard_float + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) + return true; +#else + (void)regNum; +#endif + return false; +} + +inline double Registers_mips_newabi::getFloatRegister(int regNum) const { +#ifdef __mips_hard_float + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_MIPS_F0]; +#else + (void)regNum; + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); +#endif +} + +inline void Registers_mips_newabi::setFloatRegister(int regNum, + double value) { +#ifdef __mips_hard_float + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_MIPS_F0] = value; +#else + (void)regNum; + (void)value; + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); +#endif +} + +inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const { + return false; +} + +inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); +} + +inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); +} + +inline const char *Registers_mips_newabi::getRegisterName(int regNum) { + switch (regNum) { + case UNW_MIPS_R0: + return "$0"; + case UNW_MIPS_R1: + return "$1"; + case UNW_MIPS_R2: + return "$2"; + case UNW_MIPS_R3: + return "$3"; + case UNW_MIPS_R4: + return "$4"; + case UNW_MIPS_R5: + return "$5"; + case UNW_MIPS_R6: + return "$6"; + case UNW_MIPS_R7: + return "$7"; + case UNW_MIPS_R8: + return "$8"; + case UNW_MIPS_R9: + return "$9"; + case UNW_MIPS_R10: + return "$10"; + case UNW_MIPS_R11: + return "$11"; + case UNW_MIPS_R12: + return "$12"; + case UNW_MIPS_R13: + return "$13"; + case UNW_MIPS_R14: + return "$14"; + case UNW_MIPS_R15: + return "$15"; + case UNW_MIPS_R16: + return "$16"; + case UNW_MIPS_R17: + return "$17"; + case UNW_MIPS_R18: + return "$18"; + case UNW_MIPS_R19: + return "$19"; + case UNW_MIPS_R20: + return "$20"; + case UNW_MIPS_R21: + return "$21"; + case UNW_MIPS_R22: + return "$22"; + case UNW_MIPS_R23: + return "$23"; + case UNW_MIPS_R24: + return "$24"; + case UNW_MIPS_R25: + return "$25"; + case UNW_MIPS_R26: + return "$26"; + case UNW_MIPS_R27: + return "$27"; + case UNW_MIPS_R28: + return "$28"; + case UNW_MIPS_R29: + return "$29"; + case UNW_MIPS_R30: + return "$30"; + case UNW_MIPS_R31: + return "$31"; + case UNW_MIPS_F0: + return "$f0"; + case UNW_MIPS_F1: + return "$f1"; + case UNW_MIPS_F2: + return "$f2"; + case UNW_MIPS_F3: + return "$f3"; + case UNW_MIPS_F4: + return "$f4"; + case UNW_MIPS_F5: + return "$f5"; + case UNW_MIPS_F6: + return "$f6"; + case UNW_MIPS_F7: + return "$f7"; + case UNW_MIPS_F8: + return "$f8"; + case UNW_MIPS_F9: + return "$f9"; + case UNW_MIPS_F10: + return "$f10"; + case UNW_MIPS_F11: + return "$f11"; + case UNW_MIPS_F12: + return "$f12"; + case UNW_MIPS_F13: + return "$f13"; + case UNW_MIPS_F14: + return "$f14"; + case UNW_MIPS_F15: + return "$f15"; + case UNW_MIPS_F16: + return "$f16"; + case UNW_MIPS_F17: + return "$f17"; + case UNW_MIPS_F18: + return "$f18"; + case UNW_MIPS_F19: + return "$f19"; + case UNW_MIPS_F20: + return "$f20"; + case UNW_MIPS_F21: + return "$f21"; + case UNW_MIPS_F22: + return "$f22"; + case UNW_MIPS_F23: + return "$f23"; + case UNW_MIPS_F24: + return "$f24"; + case UNW_MIPS_F25: + return "$f25"; + case UNW_MIPS_F26: + return "$f26"; + case UNW_MIPS_F27: + return "$f27"; + case UNW_MIPS_F28: + return "$f28"; + case UNW_MIPS_F29: + return "$f29"; + case UNW_MIPS_F30: + return "$f30"; + case UNW_MIPS_F31: + return "$f31"; + case UNW_MIPS_HI: + return "$hi"; + case UNW_MIPS_LO: + return "$lo"; + default: + return "unknown register"; + } +} +#endif // _LIBUNWIND_TARGET_MIPS_NEWABI + +#if defined(_LIBUNWIND_TARGET_SPARC) +/// Registers_sparc holds the register state of a thread in a 32-bit Sparc +/// process. +class _LIBUNWIND_HIDDEN Registers_sparc { +public: + Registers_sparc(); + Registers_sparc(const void *registers); + + bool validRegister(int num) const; + uint32_t getRegister(int num) const; + void setRegister(int num, uint32_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; } + static int getArch() { return REGISTERS_SPARC; } + + uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; } + void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; } + uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; } + void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; } + +private: + struct sparc_thread_state_t { + unsigned int __regs[32]; + }; + + sparc_thread_state_t _registers; +}; + +inline Registers_sparc::Registers_sparc(const void *registers) { + static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit), + "sparc registers do not fit into unw_context_t"); + memcpy(&_registers, static_cast<const uint8_t *>(registers), + sizeof(_registers)); +} + +inline Registers_sparc::Registers_sparc() { + memset(&_registers, 0, sizeof(_registers)); +} + +inline bool Registers_sparc::validRegister(int regNum) const { + if (regNum == UNW_REG_IP) + return true; + if (regNum == UNW_REG_SP) + return true; + if (regNum < 0) + return false; + if (regNum <= UNW_SPARC_I7) + return true; + return false; +} + +inline uint32_t Registers_sparc::getRegister(int regNum) const { + if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { + return _registers.__regs[regNum]; + } + + switch (regNum) { + case UNW_REG_IP: + return _registers.__regs[UNW_SPARC_O7]; + case UNW_REG_SP: + return _registers.__regs[UNW_SPARC_O6]; + } + _LIBUNWIND_ABORT("unsupported sparc register"); +} + +inline void Registers_sparc::setRegister(int regNum, uint32_t value) { + if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { + _registers.__regs[regNum] = value; + return; + } + + switch (regNum) { + case UNW_REG_IP: + _registers.__regs[UNW_SPARC_O7] = value; + return; + case UNW_REG_SP: + _registers.__regs[UNW_SPARC_O6] = value; + return; + } + _LIBUNWIND_ABORT("unsupported sparc register"); +} + +inline bool Registers_sparc::validFloatRegister(int) const { return false; } + +inline double Registers_sparc::getFloatRegister(int) const { + _LIBUNWIND_ABORT("no Sparc float registers"); +} + +inline void Registers_sparc::setFloatRegister(int, double) { + _LIBUNWIND_ABORT("no Sparc float registers"); +} + +inline bool Registers_sparc::validVectorRegister(int) const { return false; } + +inline v128 Registers_sparc::getVectorRegister(int) const { + _LIBUNWIND_ABORT("no Sparc vector registers"); +} + +inline void Registers_sparc::setVectorRegister(int, v128) { + _LIBUNWIND_ABORT("no Sparc vector registers"); +} + +inline const char *Registers_sparc::getRegisterName(int regNum) { + switch (regNum) { + case UNW_REG_IP: + return "pc"; + case UNW_SPARC_G0: + return "g0"; + case UNW_SPARC_G1: + return "g1"; + case UNW_SPARC_G2: + return "g2"; + case UNW_SPARC_G3: + return "g3"; + case UNW_SPARC_G4: + return "g4"; + case UNW_SPARC_G5: + return "g5"; + case UNW_SPARC_G6: + return "g6"; + case UNW_SPARC_G7: + return "g7"; + case UNW_SPARC_O0: + return "o0"; + case UNW_SPARC_O1: + return "o1"; + case UNW_SPARC_O2: + return "o2"; + case UNW_SPARC_O3: + return "o3"; + case UNW_SPARC_O4: + return "o4"; + case UNW_SPARC_O5: + return "o5"; + case UNW_REG_SP: + case UNW_SPARC_O6: + return "sp"; + case UNW_SPARC_O7: + return "o7"; + case UNW_SPARC_L0: + return "l0"; + case UNW_SPARC_L1: + return "l1"; + case UNW_SPARC_L2: + return "l2"; + case UNW_SPARC_L3: + return "l3"; + case UNW_SPARC_L4: + return "l4"; + case UNW_SPARC_L5: + return "l5"; + case UNW_SPARC_L6: + return "l6"; + case UNW_SPARC_L7: + return "l7"; + case UNW_SPARC_I0: + return "i0"; + case UNW_SPARC_I1: + return "i1"; + case UNW_SPARC_I2: + return "i2"; + case UNW_SPARC_I3: + return "i3"; + case UNW_SPARC_I4: + return "i4"; + case UNW_SPARC_I5: + return "i5"; + case UNW_SPARC_I6: + return "fp"; + case UNW_SPARC_I7: + return "i7"; + default: + return "unknown register"; + } +} +#endif // _LIBUNWIND_TARGET_SPARC + #if defined(_LIBUNWIND_TARGET_SPARC64) /// Registers_sparc64 holds the register state of a thread in a 64-bit /// sparc process. @@ -3772,190 +3772,190 @@ inline const char *Registers_sparc64::getRegisterName(int regNum) { } #endif // _LIBUNWIND_TARGET_SPARC64 -#if defined(_LIBUNWIND_TARGET_HEXAGON) -/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6 -/// process. -class _LIBUNWIND_HIDDEN Registers_hexagon { -public: - Registers_hexagon(); - Registers_hexagon(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; } - static int getArch() { return REGISTERS_HEXAGON; } - - uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; } - void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; } - uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; } - void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; } - -private: - struct hexagon_thread_state_t { - unsigned int __r[35]; - }; - - hexagon_thread_state_t _registers; -}; - -inline Registers_hexagon::Registers_hexagon(const void *registers) { - static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit), - "hexagon registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); -} - -inline Registers_hexagon::Registers_hexagon() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_hexagon::validRegister(int regNum) const { - if (regNum <= UNW_HEXAGON_R31) - return true; - return false; -} - -inline uint32_t Registers_hexagon::getRegister(int regNum) const { - if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) - return _registers.__r[regNum - UNW_HEXAGON_R0]; - - switch (regNum) { - case UNW_REG_IP: - return _registers.__r[UNW_HEXAGON_PC]; - case UNW_REG_SP: - return _registers.__r[UNW_HEXAGON_R29]; - } - _LIBUNWIND_ABORT("unsupported hexagon register"); -} - -inline void Registers_hexagon::setRegister(int regNum, uint32_t value) { - if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) { - _registers.__r[regNum - UNW_HEXAGON_R0] = value; - return; - } - - switch (regNum) { - case UNW_REG_IP: - _registers.__r[UNW_HEXAGON_PC] = value; - return; - case UNW_REG_SP: - _registers.__r[UNW_HEXAGON_R29] = value; - return; - } - _LIBUNWIND_ABORT("unsupported hexagon register"); -} - -inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const { - return false; -} - -inline double Registers_hexagon::getFloatRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("hexagon float support not implemented"); -} - -inline void Registers_hexagon::setFloatRegister(int /* regNum */, - double /* value */) { - _LIBUNWIND_ABORT("hexagon float support not implemented"); -} - -inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const { - return false; -} - -inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("hexagon vector support not implemented"); -} - -inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("hexagon vector support not implemented"); -} - -inline const char *Registers_hexagon::getRegisterName(int regNum) { - switch (regNum) { - case UNW_HEXAGON_R0: - return "r0"; - case UNW_HEXAGON_R1: - return "r1"; - case UNW_HEXAGON_R2: - return "r2"; - case UNW_HEXAGON_R3: - return "r3"; - case UNW_HEXAGON_R4: - return "r4"; - case UNW_HEXAGON_R5: - return "r5"; - case UNW_HEXAGON_R6: - return "r6"; - case UNW_HEXAGON_R7: - return "r7"; - case UNW_HEXAGON_R8: - return "r8"; - case UNW_HEXAGON_R9: - return "r9"; - case UNW_HEXAGON_R10: - return "r10"; - case UNW_HEXAGON_R11: - return "r11"; - case UNW_HEXAGON_R12: - return "r12"; - case UNW_HEXAGON_R13: - return "r13"; - case UNW_HEXAGON_R14: - return "r14"; - case UNW_HEXAGON_R15: - return "r15"; - case UNW_HEXAGON_R16: - return "r16"; - case UNW_HEXAGON_R17: - return "r17"; - case UNW_HEXAGON_R18: - return "r18"; - case UNW_HEXAGON_R19: - return "r19"; - case UNW_HEXAGON_R20: - return "r20"; - case UNW_HEXAGON_R21: - return "r21"; - case UNW_HEXAGON_R22: - return "r22"; - case UNW_HEXAGON_R23: - return "r23"; - case UNW_HEXAGON_R24: - return "r24"; - case UNW_HEXAGON_R25: - return "r25"; - case UNW_HEXAGON_R26: - return "r26"; - case UNW_HEXAGON_R27: - return "r27"; - case UNW_HEXAGON_R28: - return "r28"; - case UNW_HEXAGON_R29: - return "r29"; - case UNW_HEXAGON_R30: - return "r30"; - case UNW_HEXAGON_R31: - return "r31"; - default: - return "unknown register"; - } - -} -#endif // _LIBUNWIND_TARGET_HEXAGON - - -#if defined(_LIBUNWIND_TARGET_RISCV) +#if defined(_LIBUNWIND_TARGET_HEXAGON) +/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6 +/// process. +class _LIBUNWIND_HIDDEN Registers_hexagon { +public: + Registers_hexagon(); + Registers_hexagon(const void *registers); + + bool validRegister(int num) const; + uint32_t getRegister(int num) const; + void setRegister(int num, uint32_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; } + static int getArch() { return REGISTERS_HEXAGON; } + + uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; } + void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; } + uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; } + void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; } + +private: + struct hexagon_thread_state_t { + unsigned int __r[35]; + }; + + hexagon_thread_state_t _registers; +}; + +inline Registers_hexagon::Registers_hexagon(const void *registers) { + static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit), + "hexagon registers do not fit into unw_context_t"); + memcpy(&_registers, static_cast<const uint8_t *>(registers), + sizeof(_registers)); +} + +inline Registers_hexagon::Registers_hexagon() { + memset(&_registers, 0, sizeof(_registers)); +} + +inline bool Registers_hexagon::validRegister(int regNum) const { + if (regNum <= UNW_HEXAGON_R31) + return true; + return false; +} + +inline uint32_t Registers_hexagon::getRegister(int regNum) const { + if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) + return _registers.__r[regNum - UNW_HEXAGON_R0]; + + switch (regNum) { + case UNW_REG_IP: + return _registers.__r[UNW_HEXAGON_PC]; + case UNW_REG_SP: + return _registers.__r[UNW_HEXAGON_R29]; + } + _LIBUNWIND_ABORT("unsupported hexagon register"); +} + +inline void Registers_hexagon::setRegister(int regNum, uint32_t value) { + if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) { + _registers.__r[regNum - UNW_HEXAGON_R0] = value; + return; + } + + switch (regNum) { + case UNW_REG_IP: + _registers.__r[UNW_HEXAGON_PC] = value; + return; + case UNW_REG_SP: + _registers.__r[UNW_HEXAGON_R29] = value; + return; + } + _LIBUNWIND_ABORT("unsupported hexagon register"); +} + +inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const { + return false; +} + +inline double Registers_hexagon::getFloatRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("hexagon float support not implemented"); +} + +inline void Registers_hexagon::setFloatRegister(int /* regNum */, + double /* value */) { + _LIBUNWIND_ABORT("hexagon float support not implemented"); +} + +inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const { + return false; +} + +inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("hexagon vector support not implemented"); +} + +inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) { + _LIBUNWIND_ABORT("hexagon vector support not implemented"); +} + +inline const char *Registers_hexagon::getRegisterName(int regNum) { + switch (regNum) { + case UNW_HEXAGON_R0: + return "r0"; + case UNW_HEXAGON_R1: + return "r1"; + case UNW_HEXAGON_R2: + return "r2"; + case UNW_HEXAGON_R3: + return "r3"; + case UNW_HEXAGON_R4: + return "r4"; + case UNW_HEXAGON_R5: + return "r5"; + case UNW_HEXAGON_R6: + return "r6"; + case UNW_HEXAGON_R7: + return "r7"; + case UNW_HEXAGON_R8: + return "r8"; + case UNW_HEXAGON_R9: + return "r9"; + case UNW_HEXAGON_R10: + return "r10"; + case UNW_HEXAGON_R11: + return "r11"; + case UNW_HEXAGON_R12: + return "r12"; + case UNW_HEXAGON_R13: + return "r13"; + case UNW_HEXAGON_R14: + return "r14"; + case UNW_HEXAGON_R15: + return "r15"; + case UNW_HEXAGON_R16: + return "r16"; + case UNW_HEXAGON_R17: + return "r17"; + case UNW_HEXAGON_R18: + return "r18"; + case UNW_HEXAGON_R19: + return "r19"; + case UNW_HEXAGON_R20: + return "r20"; + case UNW_HEXAGON_R21: + return "r21"; + case UNW_HEXAGON_R22: + return "r22"; + case UNW_HEXAGON_R23: + return "r23"; + case UNW_HEXAGON_R24: + return "r24"; + case UNW_HEXAGON_R25: + return "r25"; + case UNW_HEXAGON_R26: + return "r26"; + case UNW_HEXAGON_R27: + return "r27"; + case UNW_HEXAGON_R28: + return "r28"; + case UNW_HEXAGON_R29: + return "r29"; + case UNW_HEXAGON_R30: + return "r30"; + case UNW_HEXAGON_R31: + return "r31"; + default: + return "unknown register"; + } + +} +#endif // _LIBUNWIND_TARGET_HEXAGON + + +#if defined(_LIBUNWIND_TARGET_RISCV) /// Registers_riscv holds the register state of a thread in a RISC-V -/// process. +/// process. // This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled. # ifdef __riscv @@ -3988,289 +3988,289 @@ typedef double fp_t; #endif /// Registers_riscv holds the register state of a thread. -class _LIBUNWIND_HIDDEN Registers_riscv { -public: - Registers_riscv(); - Registers_riscv(const void *registers); - - bool validRegister(int num) const; +class _LIBUNWIND_HIDDEN Registers_riscv { +public: + Registers_riscv(); + Registers_riscv(const void *registers); + + bool validRegister(int num) const; reg_t getRegister(int num) const; void setRegister(int num, reg_t value); - bool validFloatRegister(int num) const; + bool validFloatRegister(int num) const; fp_t getFloatRegister(int num) const; void setFloatRegister(int num, fp_t value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - static const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; } - static int getArch() { return REGISTERS_RISCV; } - + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; } + static int getArch() { return REGISTERS_RISCV; } + reg_t getSP() const { return _registers[2]; } void setSP(reg_t value) { _registers[2] = value; } reg_t getIP() const { return _registers[0]; } void setIP(reg_t value) { _registers[0] = value; } - -private: - // _registers[0] holds the pc + +private: + // _registers[0] holds the pc reg_t _registers[32]; # if defined(__riscv_flen) fp_t _floats[32]; # endif -}; - -inline Registers_riscv::Registers_riscv(const void *registers) { - static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit), - "riscv registers do not fit into unw_context_t"); - memcpy(&_registers, registers, sizeof(_registers)); +}; + +inline Registers_riscv::Registers_riscv(const void *registers) { + static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit), + "riscv registers do not fit into unw_context_t"); + memcpy(&_registers, registers, sizeof(_registers)); # if __riscv_xlen == 32 static_assert(sizeof(_registers) == 0x80, "expected float registers to be at offset 128"); # elif __riscv_xlen == 64 - static_assert(sizeof(_registers) == 0x100, - "expected float registers to be at offset 256"); + static_assert(sizeof(_registers) == 0x100, + "expected float registers to be at offset 256"); # else # error "Unexpected float registers." # endif # if defined(__riscv_flen) - memcpy(_floats, - static_cast<const uint8_t *>(registers) + sizeof(_registers), - sizeof(_floats)); + memcpy(_floats, + static_cast<const uint8_t *>(registers) + sizeof(_registers), + sizeof(_floats)); # endif -} - -inline Registers_riscv::Registers_riscv() { - memset(&_registers, 0, sizeof(_registers)); +} + +inline Registers_riscv::Registers_riscv() { + memset(&_registers, 0, sizeof(_registers)); # if defined(__riscv_flen) - memset(&_floats, 0, sizeof(_floats)); + memset(&_floats, 0, sizeof(_floats)); # endif -} - -inline bool Registers_riscv::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum > UNW_RISCV_F31) - return false; - return true; -} - +} + +inline bool Registers_riscv::validRegister(int regNum) const { + if (regNum == UNW_REG_IP) + return true; + if (regNum == UNW_REG_SP) + return true; + if (regNum < 0) + return false; + if (regNum > UNW_RISCV_F31) + return false; + return true; +} + inline reg_t Registers_riscv::getRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return _registers[0]; - if (regNum == UNW_REG_SP) - return _registers[2]; - if (regNum == UNW_RISCV_X0) - return 0; - if ((regNum > 0) && (regNum < 32)) - return _registers[regNum]; - _LIBUNWIND_ABORT("unsupported riscv register"); -} - + if (regNum == UNW_REG_IP) + return _registers[0]; + if (regNum == UNW_REG_SP) + return _registers[2]; + if (regNum == UNW_RISCV_X0) + return 0; + if ((regNum > 0) && (regNum < 32)) + return _registers[regNum]; + _LIBUNWIND_ABORT("unsupported riscv register"); +} + inline void Registers_riscv::setRegister(int regNum, reg_t value) { - if (regNum == UNW_REG_IP) - _registers[0] = value; - else if (regNum == UNW_REG_SP) - _registers[2] = value; - else if (regNum == UNW_RISCV_X0) - /* x0 is hardwired to zero */ - return; - else if ((regNum > 0) && (regNum < 32)) - _registers[regNum] = value; - else - _LIBUNWIND_ABORT("unsupported riscv register"); -} - -inline const char *Registers_riscv::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "pc"; - case UNW_REG_SP: - return "sp"; - case UNW_RISCV_X0: - return "zero"; - case UNW_RISCV_X1: - return "ra"; - case UNW_RISCV_X2: - return "sp"; - case UNW_RISCV_X3: - return "gp"; - case UNW_RISCV_X4: - return "tp"; - case UNW_RISCV_X5: - return "t0"; - case UNW_RISCV_X6: - return "t1"; - case UNW_RISCV_X7: - return "t2"; - case UNW_RISCV_X8: - return "s0"; - case UNW_RISCV_X9: - return "s1"; - case UNW_RISCV_X10: - return "a0"; - case UNW_RISCV_X11: - return "a1"; - case UNW_RISCV_X12: - return "a2"; - case UNW_RISCV_X13: - return "a3"; - case UNW_RISCV_X14: - return "a4"; - case UNW_RISCV_X15: - return "a5"; - case UNW_RISCV_X16: - return "a6"; - case UNW_RISCV_X17: - return "a7"; - case UNW_RISCV_X18: - return "s2"; - case UNW_RISCV_X19: - return "s3"; - case UNW_RISCV_X20: - return "s4"; - case UNW_RISCV_X21: - return "s5"; - case UNW_RISCV_X22: - return "s6"; - case UNW_RISCV_X23: - return "s7"; - case UNW_RISCV_X24: - return "s8"; - case UNW_RISCV_X25: - return "s9"; - case UNW_RISCV_X26: - return "s10"; - case UNW_RISCV_X27: - return "s11"; - case UNW_RISCV_X28: - return "t3"; - case UNW_RISCV_X29: - return "t4"; - case UNW_RISCV_X30: - return "t5"; - case UNW_RISCV_X31: - return "t6"; - case UNW_RISCV_F0: - return "ft0"; - case UNW_RISCV_F1: - return "ft1"; - case UNW_RISCV_F2: - return "ft2"; - case UNW_RISCV_F3: - return "ft3"; - case UNW_RISCV_F4: - return "ft4"; - case UNW_RISCV_F5: - return "ft5"; - case UNW_RISCV_F6: - return "ft6"; - case UNW_RISCV_F7: - return "ft7"; - case UNW_RISCV_F8: - return "fs0"; - case UNW_RISCV_F9: - return "fs1"; - case UNW_RISCV_F10: - return "fa0"; - case UNW_RISCV_F11: - return "fa1"; - case UNW_RISCV_F12: - return "fa2"; - case UNW_RISCV_F13: - return "fa3"; - case UNW_RISCV_F14: - return "fa4"; - case UNW_RISCV_F15: - return "fa5"; - case UNW_RISCV_F16: - return "fa6"; - case UNW_RISCV_F17: - return "fa7"; - case UNW_RISCV_F18: - return "fs2"; - case UNW_RISCV_F19: - return "fs3"; - case UNW_RISCV_F20: - return "fs4"; - case UNW_RISCV_F21: - return "fs5"; - case UNW_RISCV_F22: - return "fs6"; - case UNW_RISCV_F23: - return "fs7"; - case UNW_RISCV_F24: - return "fs8"; - case UNW_RISCV_F25: - return "fs9"; - case UNW_RISCV_F26: - return "fs10"; - case UNW_RISCV_F27: - return "fs11"; - case UNW_RISCV_F28: - return "ft8"; - case UNW_RISCV_F29: - return "ft9"; - case UNW_RISCV_F30: - return "ft10"; - case UNW_RISCV_F31: - return "ft11"; - default: - return "unknown register"; - } -} - -inline bool Registers_riscv::validFloatRegister(int regNum) const { + if (regNum == UNW_REG_IP) + _registers[0] = value; + else if (regNum == UNW_REG_SP) + _registers[2] = value; + else if (regNum == UNW_RISCV_X0) + /* x0 is hardwired to zero */ + return; + else if ((regNum > 0) && (regNum < 32)) + _registers[regNum] = value; + else + _LIBUNWIND_ABORT("unsupported riscv register"); +} + +inline const char *Registers_riscv::getRegisterName(int regNum) { + switch (regNum) { + case UNW_REG_IP: + return "pc"; + case UNW_REG_SP: + return "sp"; + case UNW_RISCV_X0: + return "zero"; + case UNW_RISCV_X1: + return "ra"; + case UNW_RISCV_X2: + return "sp"; + case UNW_RISCV_X3: + return "gp"; + case UNW_RISCV_X4: + return "tp"; + case UNW_RISCV_X5: + return "t0"; + case UNW_RISCV_X6: + return "t1"; + case UNW_RISCV_X7: + return "t2"; + case UNW_RISCV_X8: + return "s0"; + case UNW_RISCV_X9: + return "s1"; + case UNW_RISCV_X10: + return "a0"; + case UNW_RISCV_X11: + return "a1"; + case UNW_RISCV_X12: + return "a2"; + case UNW_RISCV_X13: + return "a3"; + case UNW_RISCV_X14: + return "a4"; + case UNW_RISCV_X15: + return "a5"; + case UNW_RISCV_X16: + return "a6"; + case UNW_RISCV_X17: + return "a7"; + case UNW_RISCV_X18: + return "s2"; + case UNW_RISCV_X19: + return "s3"; + case UNW_RISCV_X20: + return "s4"; + case UNW_RISCV_X21: + return "s5"; + case UNW_RISCV_X22: + return "s6"; + case UNW_RISCV_X23: + return "s7"; + case UNW_RISCV_X24: + return "s8"; + case UNW_RISCV_X25: + return "s9"; + case UNW_RISCV_X26: + return "s10"; + case UNW_RISCV_X27: + return "s11"; + case UNW_RISCV_X28: + return "t3"; + case UNW_RISCV_X29: + return "t4"; + case UNW_RISCV_X30: + return "t5"; + case UNW_RISCV_X31: + return "t6"; + case UNW_RISCV_F0: + return "ft0"; + case UNW_RISCV_F1: + return "ft1"; + case UNW_RISCV_F2: + return "ft2"; + case UNW_RISCV_F3: + return "ft3"; + case UNW_RISCV_F4: + return "ft4"; + case UNW_RISCV_F5: + return "ft5"; + case UNW_RISCV_F6: + return "ft6"; + case UNW_RISCV_F7: + return "ft7"; + case UNW_RISCV_F8: + return "fs0"; + case UNW_RISCV_F9: + return "fs1"; + case UNW_RISCV_F10: + return "fa0"; + case UNW_RISCV_F11: + return "fa1"; + case UNW_RISCV_F12: + return "fa2"; + case UNW_RISCV_F13: + return "fa3"; + case UNW_RISCV_F14: + return "fa4"; + case UNW_RISCV_F15: + return "fa5"; + case UNW_RISCV_F16: + return "fa6"; + case UNW_RISCV_F17: + return "fa7"; + case UNW_RISCV_F18: + return "fs2"; + case UNW_RISCV_F19: + return "fs3"; + case UNW_RISCV_F20: + return "fs4"; + case UNW_RISCV_F21: + return "fs5"; + case UNW_RISCV_F22: + return "fs6"; + case UNW_RISCV_F23: + return "fs7"; + case UNW_RISCV_F24: + return "fs8"; + case UNW_RISCV_F25: + return "fs9"; + case UNW_RISCV_F26: + return "fs10"; + case UNW_RISCV_F27: + return "fs11"; + case UNW_RISCV_F28: + return "ft8"; + case UNW_RISCV_F29: + return "ft9"; + case UNW_RISCV_F30: + return "ft10"; + case UNW_RISCV_F31: + return "ft11"; + default: + return "unknown register"; + } +} + +inline bool Registers_riscv::validFloatRegister(int regNum) const { # if defined(__riscv_flen) - if (regNum < UNW_RISCV_F0) - return false; - if (regNum > UNW_RISCV_F31) - return false; - return true; + if (regNum < UNW_RISCV_F0) + return false; + if (regNum > UNW_RISCV_F31) + return false; + return true; # else (void)regNum; return false; # endif -} - +} + inline fp_t Registers_riscv::getFloatRegister(int regNum) const { # if defined(__riscv_flen) - assert(validFloatRegister(regNum)); - return _floats[regNum - UNW_RISCV_F0]; + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_RISCV_F0]; # else - (void)regNum; - _LIBUNWIND_ABORT("libunwind not built with float support"); + (void)regNum; + _LIBUNWIND_ABORT("libunwind not built with float support"); # endif -} - +} + inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) { # if defined(__riscv_flen) - assert(validFloatRegister(regNum)); - _floats[regNum - UNW_RISCV_F0] = value; + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_RISCV_F0] = value; # else - (void)regNum; - (void)value; - _LIBUNWIND_ABORT("libunwind not built with float support"); + (void)regNum; + (void)value; + _LIBUNWIND_ABORT("libunwind not built with float support"); # endif -} - -inline bool Registers_riscv::validVectorRegister(int) const { - return false; -} - -inline v128 Registers_riscv::getVectorRegister(int) const { - _LIBUNWIND_ABORT("no riscv vector register support yet"); -} - -inline void Registers_riscv::setVectorRegister(int, v128) { - _LIBUNWIND_ABORT("no riscv vector register support yet"); -} -#endif // _LIBUNWIND_TARGET_RISCV +} + +inline bool Registers_riscv::validVectorRegister(int) const { + return false; +} + +inline v128 Registers_riscv::getVectorRegister(int) const { + _LIBUNWIND_ABORT("no riscv vector register support yet"); +} + +inline void Registers_riscv::setVectorRegister(int, v128) { + _LIBUNWIND_ABORT("no riscv vector register support yet"); +} +#endif // _LIBUNWIND_TARGET_RISCV #if defined(_LIBUNWIND_TARGET_VE) /// Registers_ve holds the register state of a thread in a VE process. diff --git a/contrib/libs/libunwind/src/Unwind-EHABI.cpp b/contrib/libs/libunwind/src/Unwind-EHABI.cpp index 21c8b2777b..fa5780674d 100644 --- a/contrib/libs/libunwind/src/Unwind-EHABI.cpp +++ b/contrib/libs/libunwind/src/Unwind-EHABI.cpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Implements ARM zero-cost C++ exceptions @@ -11,9 +11,9 @@ #include "Unwind-EHABI.h" -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) -#include <inttypes.h> +#include <inttypes.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> @@ -31,13 +31,13 @@ namespace { // signinficant byte. uint8_t getByte(const uint32_t* data, size_t offset) { const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data); -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))]; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return byteData[offset]; -#else -#error "Unable to determine endianess" -#endif +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return byteData[offset]; +#else +#error "Unable to determine endianess" +#endif } const char* getNextWord(const char* data, uint32_t* out) { @@ -256,9 +256,9 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) { return data; } -_LIBUNWIND_EXPORT _Unwind_Reason_Code -_Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, - size_t offset, size_t len) { +_LIBUNWIND_EXPORT _Unwind_Reason_Code +_Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, + size_t offset, size_t len) { bool wrotePC = false; bool finish = false; bool hasReturnAddrAuthCode = false; @@ -365,7 +365,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, } case 0xc0: { switch (byte) { -#if defined(__ARM_WMMX) +#if defined(__ARM_WMMX) case 0xc0: case 0xc1: case 0xc2: @@ -393,7 +393,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, _Unwind_VRS_Pop(context, _UVRSC_WMMXC, v, _UVRSD_DOUBLE); break; } -#endif +#endif case 0xc8: case 0xc9: { uint8_t v = getByte(data, offset++); @@ -442,44 +442,44 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, return _URC_CONTINUE_UNWIND; } -extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code -__aeabi_unwind_cpp_pr0(_Unwind_State state, _Unwind_Control_Block *ucbp, - _Unwind_Context *context) { +extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code +__aeabi_unwind_cpp_pr0(_Unwind_State state, _Unwind_Control_Block *ucbp, + _Unwind_Context *context) { return unwindOneFrame(state, ucbp, context); } -extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code -__aeabi_unwind_cpp_pr1(_Unwind_State state, _Unwind_Control_Block *ucbp, - _Unwind_Context *context) { +extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code +__aeabi_unwind_cpp_pr1(_Unwind_State state, _Unwind_Control_Block *ucbp, + _Unwind_Context *context) { return unwindOneFrame(state, ucbp, context); } -extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code -__aeabi_unwind_cpp_pr2(_Unwind_State state, _Unwind_Control_Block *ucbp, - _Unwind_Context *context) { +extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code +__aeabi_unwind_cpp_pr2(_Unwind_State state, _Unwind_Control_Block *ucbp, + _Unwind_Context *context) { return unwindOneFrame(state, ucbp, context); } static _Unwind_Reason_Code -unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { +unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { // EHABI #7.3 discusses preserving the VRS in a "temporary VRS" during // phase 1 and then restoring it to the "primary VRS" for phase 2. The // effect is phase 2 doesn't see any of the VRS manipulations from phase 1. // In this implementation, the phases don't share the VRS backing store. // Instead, they are passed the original |uc| and they create a new VRS // from scratch thus achieving the same effect. - __unw_init_local(cursor, uc); + __unw_init_local(cursor, uc); // Walk each frame looking for a place to stop. for (bool handlerNotFound = true; handlerNotFound;) { // See if frame has code to run (has personality routine). unw_proc_info_t frameInfo; - if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR", - static_cast<void *>(exception_object)); + if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase1(ex_ojb=%p): __unw_get_proc_info " + "failed => _URC_FATAL_PHASE1_ERROR", + static_cast<void *>(exception_object)); return _URC_FATAL_PHASE1_ERROR; } @@ -489,31 +489,31 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; unw_word_t pc; - __unw_get_reg(cursor, UNW_REG_IP, &pc); + __unw_get_reg(cursor, UNW_REG_IP, &pc); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR ", func=%s, " - "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, - static_cast<void *>(exception_object), pc, - frameInfo.start_ip, functionName, - frameInfo.lsda, frameInfo.handler); + "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR ", func=%s, " + "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, + static_cast<void *>(exception_object), pc, + frameInfo.start_ip, functionName, + frameInfo.lsda, frameInfo.handler); } #endif // If there is a personality routine, ask it if it will want to stop at // this frame. if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = - (_Unwind_Personality_Fn)(long)(frameInfo.handler); + _Unwind_Personality_Fn p = + (_Unwind_Personality_Fn)(long)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): calling personality function %p", + "unwind_phase1(ex_ojb=%p): calling personality function %p", static_cast<void *>(exception_object), reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p))); - struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); + struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); exception_object->pr_cache.fnstart = frameInfo.start_ip; exception_object->pr_cache.ehtp = (_Unwind_EHT_Header *)frameInfo.unwind_info; @@ -522,7 +522,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except (*p)(_US_VIRTUAL_UNWIND_FRAME, exception_object, context); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p " - "additional %x", + "additional %x", static_cast<void *>(exception_object), personalityResult, exception_object->pr_cache.fnstart, static_cast<void *>(exception_object->pr_cache.ehtp), @@ -534,13 +534,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except handlerNotFound = false; // p should have initialized barrier_cache. EHABI #7.3.5 _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", + "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", static_cast<void *>(exception_object)); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", static_cast<void *>(exception_object)); // continue unwinding break; @@ -552,7 +552,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", static_cast<void *>(exception_object)); return _URC_FATAL_PHASE1_ERROR; } @@ -561,19 +561,19 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except return _URC_NO_REASON; } -static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, +static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object, bool resume) { // See comment at the start of unwind_phase1 regarding VRS integrity. - __unw_init_local(cursor, uc); + __unw_init_local(cursor, uc); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", static_cast<void *>(exception_object)); int frame_count = 0; // Walk each frame until we reach where search phase said to stop. while (true) { - // Ask libunwind to get next frame (skip over first which is + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException or _Unwind_Resume). // // Resume only ever makes sense for 1 frame. @@ -587,20 +587,20 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // for. After this, continue unwinding as if normal. // // See #7.4.6 for details. - __unw_set_reg(cursor, UNW_REG_IP, - exception_object->unwinder_cache.reserved2); + __unw_set_reg(cursor, UNW_REG_IP, + exception_object->unwinder_cache.reserved2); resume = false; } // Get info about this frame. unw_word_t sp; unw_proc_info_t frameInfo; - __unw_get_reg(cursor, UNW_REG_SP, &sp); - if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_get_proc_info " - "failed => _URC_FATAL_PHASE2_ERROR", - static_cast<void *>(exception_object)); + __unw_get_reg(cursor, UNW_REG_SP, &sp); + if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_get_proc_info " + "failed => _URC_FATAL_PHASE2_ERROR", + static_cast<void *>(exception_object)); return _URC_FATAL_PHASE2_ERROR; } @@ -610,24 +610,24 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR ", func=%s, sp=0x%" PRIxPTR ", " - "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "", - static_cast<void *>(exception_object), frameInfo.start_ip, - functionName, sp, frameInfo.lsda, - frameInfo.handler); + "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR ", func=%s, sp=0x%" PRIxPTR ", " + "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "", + static_cast<void *>(exception_object), frameInfo.start_ip, + functionName, sp, frameInfo.lsda, + frameInfo.handler); } #endif // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = + _Unwind_Personality_Fn p = (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); - struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); + struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); // EHABI #7.2 exception_object->pr_cache.fnstart = frameInfo.start_ip; exception_object->pr_cache.ehtp = @@ -639,7 +639,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor case _URC_CONTINUE_UNWIND: // Continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", static_cast<void *>(exception_object)); // EHABI #7.2 if (sp == exception_object->barrier_cache.sp) { @@ -650,29 +650,29 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", + "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", static_cast<void *>(exception_object)); // Personality routine says to transfer control to landing pad. // We may get control back if landing pad calls _Unwind_Resume(). if (_LIBUNWIND_TRACING_UNWINDING) { unw_word_t pc; - __unw_get_reg(cursor, UNW_REG_IP, &pc); - __unw_get_reg(cursor, UNW_REG_SP, &sp); + __unw_get_reg(cursor, UNW_REG_IP, &pc); + __unw_get_reg(cursor, UNW_REG_SP, &sp); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering " - "user code with ip=0x%" PRIxPTR ", sp=0x%" PRIxPTR, + "user code with ip=0x%" PRIxPTR ", sp=0x%" PRIxPTR, static_cast<void *>(exception_object), - pc, sp); + pc, sp); } { // EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume // is called back, to find this same frame. unw_word_t pc; - __unw_get_reg(cursor, UNW_REG_IP, &pc); + __unw_get_reg(cursor, UNW_REG_IP, &pc); exception_object->unwinder_cache.reserved2 = (uint32_t)pc; } - __unw_resume(cursor); - // __unw_resume() only returns if there was an error. + __unw_resume(cursor); + // __unw_resume() only returns if there was an error. return _URC_FATAL_PHASE2_ERROR; // # EHABI #7.4.3 @@ -814,23 +814,23 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, /// Called by __cxa_throw. Only returns if there is a fatal error. _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", static_cast<void *>(exception_object)); unw_context_t uc; - unw_cursor_t cursor; - __unw_getcontext(&uc); + unw_cursor_t cursor; + __unw_getcontext(&uc); // This field for is for compatibility with GCC to say this isn't a forced // unwind. EHABI #7.2 exception_object->unwinder_cache.reserved1 = 0; // phase 1: the search phase - _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); + _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); if (phase1 != _URC_NO_REASON) return phase1; // phase 2: the clean up phase - return unwind_phase2(&uc, &cursor, exception_object, false); + return unwind_phase2(&uc, &cursor, exception_object, false); } _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) { @@ -852,11 +852,11 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) { /// in turn calls _Unwind_Resume_or_Rethrow(). _LIBUNWIND_EXPORT void _Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", + _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", static_cast<void *>(exception_object)); unw_context_t uc; - unw_cursor_t cursor; - __unw_getcontext(&uc); + unw_cursor_t cursor; + __unw_getcontext(&uc); if (exception_object->unwinder_cache.reserved1) unwind_phase2_forced( @@ -876,10 +876,10 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_proc_info_t frameInfo; uintptr_t result = 0; - if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) + if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.lsda; _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx", + "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx", static_cast<void *>(context), (long long)result); return result; } @@ -902,12 +902,12 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { return value; } -_LIBUNWIND_EXPORT _Unwind_VRS_Result +_LIBUNWIND_EXPORT _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, void *valuep) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " - "rep=%d, value=0x%llX)", + "rep=%d, value=0x%llX)", static_cast<void *>(context), regclass, regno, representation, ValueAsBitPattern(representation, valuep)); @@ -916,8 +916,8 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, case _UVRSC_CORE: if (representation != _UVRSD_UINT32 || regno > 15) return _UVRSR_FAILED; - return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), - *(unw_word_t *)valuep) == UNW_ESUCCESS + return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), + *(unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; case _UVRSC_VFP: @@ -927,35 +927,35 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, // Can only touch d0-15 with FSTMFDX. if (regno > 15) return _UVRSR_FAILED; - __unw_save_vfp_as_X(cursor); + __unw_save_vfp_as_X(cursor); } else { if (regno > 31) return _UVRSR_FAILED; } - return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), - *(unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#if defined(__ARM_WMMX) - case _UVRSC_WMMXC: - if (representation != _UVRSD_UINT32 || regno > 3) - return _UVRSR_FAILED; - return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), - *(unw_word_t *)valuep) == UNW_ESUCCESS + return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), + *(unw_fpreg_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; +#if defined(__ARM_WMMX) + case _UVRSC_WMMXC: + if (representation != _UVRSD_UINT32 || regno > 3) + return _UVRSR_FAILED; + return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), + *(unw_word_t *)valuep) == UNW_ESUCCESS + ? _UVRSR_OK + : _UVRSR_FAILED; case _UVRSC_WMMXD: if (representation != _UVRSD_DOUBLE || regno > 31) return _UVRSR_FAILED; - return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), - *(unw_fpreg_t *)valuep) == UNW_ESUCCESS + return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), + *(unw_fpreg_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; -#else - case _UVRSC_WMMXC: - case _UVRSC_WMMXD: - break; -#endif +#else + case _UVRSC_WMMXC: + case _UVRSC_WMMXD: + break; +#endif case _UVRSC_PSEUDO: // There's only one pseudo-register, PAC, with regno == 0. if (representation != _UVRSD_UINT32 || regno != 0) @@ -979,8 +979,8 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context, case _UVRSC_CORE: if (representation != _UVRSD_UINT32 || regno > 15) return _UVRSR_FAILED; - return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), - (unw_word_t *)valuep) == UNW_ESUCCESS + return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), + (unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; case _UVRSC_VFP: @@ -990,35 +990,35 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context, // Can only touch d0-15 with FSTMFDX. if (regno > 15) return _UVRSR_FAILED; - __unw_save_vfp_as_X(cursor); + __unw_save_vfp_as_X(cursor); } else { if (regno > 31) return _UVRSR_FAILED; } - return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), - (unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#if defined(__ARM_WMMX) - case _UVRSC_WMMXC: - if (representation != _UVRSD_UINT32 || regno > 3) - return _UVRSR_FAILED; - return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), - (unw_word_t *)valuep) == UNW_ESUCCESS + return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), + (unw_fpreg_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; +#if defined(__ARM_WMMX) + case _UVRSC_WMMXC: + if (representation != _UVRSD_UINT32 || regno > 3) + return _UVRSR_FAILED; + return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), + (unw_word_t *)valuep) == UNW_ESUCCESS + ? _UVRSR_OK + : _UVRSR_FAILED; case _UVRSC_WMMXD: if (representation != _UVRSD_DOUBLE || regno > 31) return _UVRSR_FAILED; - return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), - (unw_fpreg_t *)valuep) == UNW_ESUCCESS + return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), + (unw_fpreg_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; -#else - case _UVRSC_WMMXC: - case _UVRSC_WMMXD: - break; -#endif +#else + case _UVRSC_WMMXC: + case _UVRSC_WMMXD: + break; +#endif case _UVRSC_PSEUDO: // There's only one pseudo-register, PAC, with regno == 0. if (representation != _UVRSD_UINT32 || regno != 0) @@ -1032,15 +1032,15 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context, _LIBUNWIND_ABORT("unsupported register class"); } -_LIBUNWIND_EXPORT _Unwind_VRS_Result -_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, - uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep) { +_LIBUNWIND_EXPORT _Unwind_VRS_Result +_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, + uint32_t regno, _Unwind_VRS_DataRepresentation representation, + void *valuep) { _Unwind_VRS_Result result = _Unwind_VRS_Get_Internal(context, regclass, regno, representation, valuep); _LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, " - "rep=%d, value=0x%llX, result = %d)", + "rep=%d, value=0x%llX, result = %d)", static_cast<void *>(context), regclass, regno, representation, ValueAsBitPattern(representation, valuep), result); @@ -1052,15 +1052,15 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t discriminator, _Unwind_VRS_DataRepresentation representation) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, " - "discriminator=%d, representation=%d)", + "discriminator=%d, representation=%d)", static_cast<void *>(context), regclass, discriminator, representation); switch (regclass) { - case _UVRSC_WMMXC: -#if !defined(__ARM_WMMX) - break; -#endif - case _UVRSC_CORE: { + case _UVRSC_WMMXC: +#if !defined(__ARM_WMMX) + break; +#endif + case _UVRSC_CORE: { if (representation != _UVRSD_UINT32) return _UVRSR_FAILED; // When popping SP from the stack, we don't want to override it from the @@ -1088,11 +1088,11 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, } return _UVRSR_OK; } - case _UVRSC_WMMXD: -#if !defined(__ARM_WMMX) - break; -#endif - case _UVRSC_VFP: { + case _UVRSC_WMMXD: +#if !defined(__ARM_WMMX) + break; +#endif + case _UVRSC_VFP: { if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) return _UVRSR_FAILED; uint32_t first = discriminator >> 16; @@ -1107,15 +1107,15 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, // format 1", which is equivalent to FSTMD + a padding word. for (uint32_t i = first; i < end; ++i) { // SP is only 32-bit aligned so don't copy 64-bit at a time. - uint64_t w0 = *sp++; - uint64_t w1 = *sp++; -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - uint64_t value = (w1 << 32) | w0; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - uint64_t value = (w0 << 32) | w1; -#else -#error "Unable to determine endianess" -#endif + uint64_t w0 = *sp++; + uint64_t w1 = *sp++; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint64_t value = (w1 << 32) | w0; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint64_t value = (w0 << 32) | w1; +#else +#error "Unable to determine endianess" +#endif if (_Unwind_VRS_Set(context, regclass, i, representation, &value) != _UVRSR_OK) return _UVRSR_FAILED; @@ -1171,9 +1171,9 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_proc_info_t frameInfo; uintptr_t result = 0; - if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) + if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX", + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX", static_cast<void *>(context), (long long)result); return result; } @@ -1183,7 +1183,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { // is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", static_cast<void *>(exception_object)); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, @@ -1204,4 +1204,4 @@ __gnu_unwind_frame(_Unwind_Exception * /* exception_object */, } } -#endif // defined(_LIBUNWIND_ARM_EHABI) +#endif // defined(_LIBUNWIND_ARM_EHABI) diff --git a/contrib/libs/libunwind/src/Unwind-EHABI.h b/contrib/libs/libunwind/src/Unwind-EHABI.h index ff3b5fc6fe..0bc5fa832c 100644 --- a/contrib/libs/libunwind/src/Unwind-EHABI.h +++ b/contrib/libs/libunwind/src/Unwind-EHABI.h @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // //===----------------------------------------------------------------------===// @@ -12,7 +12,7 @@ #include <__libunwind_config.h> -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) #include <stdint.h> #include <unwind.h> @@ -45,6 +45,6 @@ extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2( } // extern "C" #endif -#endif // defined(_LIBUNWIND_ARM_EHABI) +#endif // defined(_LIBUNWIND_ARM_EHABI) #endif // __UNWIND_EHABI_H__ diff --git a/contrib/libs/libunwind/src/Unwind-seh.cpp b/contrib/libs/libunwind/src/Unwind-seh.cpp index f00bc4721b..9f474b8c07 100644 --- a/contrib/libs/libunwind/src/Unwind-seh.cpp +++ b/contrib/libs/libunwind/src/Unwind-seh.cpp @@ -1,491 +1,491 @@ //===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Implements SEH-based Itanium C++ exceptions. -// -//===----------------------------------------------------------------------===// - -#include "config.h" - -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) - -#include <unwind.h> - -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> - -#include <windef.h> -#include <excpt.h> -#include <winnt.h> -#include <ntstatus.h> - -#include "libunwind_ext.h" -#include "UnwindCursor.hpp" - -using namespace libunwind; - -#define STATUS_USER_DEFINED (1u << 29) - -#define STATUS_GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C') - -#define MAKE_CUSTOM_STATUS(s, c) \ - ((NTSTATUS)(((s) << 30) | STATUS_USER_DEFINED | (c))) -#define MAKE_GCC_EXCEPTION(c) \ - MAKE_CUSTOM_STATUS(STATUS_SEVERITY_SUCCESS, STATUS_GCC_MAGIC | ((c) << 24)) - -/// SEH exception raised by libunwind when the program calls -/// \c _Unwind_RaiseException. -#define STATUS_GCC_THROW MAKE_GCC_EXCEPTION(0) // 0x20474343 -/// SEH exception raised by libunwind to initiate phase 2 of exception -/// handling. -#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343 - -static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx); -static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor); -static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, - DISPATCHER_CONTEXT *disp); - -/// Common implementation of SEH-style handler functions used by Itanium- -/// style frames. Depending on how and why it was called, it may do one of: -/// a) Delegate to the given Itanium-style personality function; or -/// b) Initiate a collided unwind to halt unwinding. -_LIBUNWIND_EXPORT EXCEPTION_DISPOSITION -_GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, - DISPATCHER_CONTEXT *disp, _Unwind_Personality_Fn pers) { - unw_cursor_t cursor; - _Unwind_Exception *exc; - _Unwind_Action action; - struct _Unwind_Context *ctx = nullptr; - _Unwind_Reason_Code urc; - uintptr_t retval, target; - bool ours = false; - - _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler(%#010lx(%lx), %p)", - ms_exc->ExceptionCode, ms_exc->ExceptionFlags, - (void *)frame); - if (ms_exc->ExceptionCode == STATUS_GCC_UNWIND) { - if (IS_TARGET_UNWIND(ms_exc->ExceptionFlags)) { - // Set up the upper return value (the lower one and the target PC - // were set in the call to RtlUnwindEx()) for the landing pad. -#ifdef __x86_64__ - disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3]; -#elif defined(__arm__) - disp->ContextRecord->R1 = ms_exc->ExceptionInformation[3]; -#elif defined(__aarch64__) - disp->ContextRecord->X1 = ms_exc->ExceptionInformation[3]; -#endif - } - // This is the collided unwind to the landing pad. Nothing to do. - return ExceptionContinueSearch; - } - - if (ms_exc->ExceptionCode == STATUS_GCC_THROW) { - // This is (probably) a libunwind-controlled exception/unwind. Recover the - // parameters which we set below, and pass them to the personality function. - ours = true; - exc = (_Unwind_Exception *)ms_exc->ExceptionInformation[0]; - if (!IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1) { - ctx = (struct _Unwind_Context *)ms_exc->ExceptionInformation[1]; - action = (_Unwind_Action)ms_exc->ExceptionInformation[2]; - } - } else { - // Foreign exception. - // We can't interact with them (we don't know the original target frame - // that we should pass on to RtlUnwindEx in _Unwind_Resume), so just - // pass without calling our destructors here. - return ExceptionContinueSearch; - } - if (!ctx) { - __unw_init_seh(&cursor, disp->ContextRecord); - __unw_seh_set_disp_ctx(&cursor, disp); - __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc - 1); - ctx = (struct _Unwind_Context *)&cursor; - - if (!IS_UNWINDING(ms_exc->ExceptionFlags)) { - if (ours && ms_exc->NumberParameters > 1) - action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_FORCE_UNWIND); - else - action = _UA_SEARCH_PHASE; - } else { - if (ours && ms_exc->ExceptionInformation[1] == (ULONG_PTR)frame) - action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME); - else - action = _UA_CLEANUP_PHASE; - } - } - - _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler() calling personality " - "function %p(1, %d, %llx, %p, %p)", - (void *)pers, action, exc->exception_class, - (void *)exc, (void *)ctx); - urc = pers(1, action, exc->exception_class, exc, ctx); - _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler() personality returned %d", urc); - switch (urc) { - case _URC_CONTINUE_UNWIND: - // If we're in phase 2, and the personality routine said to continue - // at the target frame, we're in real trouble. - if (action & _UA_HANDLER_FRAME) - _LIBUNWIND_ABORT("Personality continued unwind at the target frame!"); - return ExceptionContinueSearch; - case _URC_HANDLER_FOUND: - // If we were called by __libunwind_seh_personality(), indicate that - // a handler was found; otherwise, initiate phase 2 by unwinding. - if (ours && ms_exc->NumberParameters > 1) - return 4 /* ExecptionExecuteHandler in mingw */; - // This should never happen in phase 2. - if (IS_UNWINDING(ms_exc->ExceptionFlags)) - _LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!"); - exc->private_[1] = (ULONG_PTR)frame; - if (ours) { - ms_exc->NumberParameters = 4; - ms_exc->ExceptionInformation[1] = (ULONG_PTR)frame; - } - // FIXME: Indicate target frame in foreign case! - // phase 2: the clean up phase - RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, ms_ctx, disp->HistoryTable); - _LIBUNWIND_ABORT("RtlUnwindEx() failed"); - case _URC_INSTALL_CONTEXT: { - // If we were called by __libunwind_seh_personality(), indicate that - // a handler was found; otherwise, it's time to initiate a collided - // unwind to the target. - if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1) - return 4 /* ExecptionExecuteHandler in mingw */; - // This should never happen in phase 1. - if (!IS_UNWINDING(ms_exc->ExceptionFlags)) - _LIBUNWIND_ABORT("Personality installed context during phase 1!"); -#ifdef __x86_64__ - exc->private_[2] = disp->TargetIp; - __unw_get_reg(&cursor, UNW_X86_64_RAX, &retval); - __unw_get_reg(&cursor, UNW_X86_64_RDX, &exc->private_[3]); -#elif defined(__arm__) - exc->private_[2] = disp->TargetPc; - __unw_get_reg(&cursor, UNW_ARM_R0, &retval); - __unw_get_reg(&cursor, UNW_ARM_R1, &exc->private_[3]); -#elif defined(__aarch64__) - exc->private_[2] = disp->TargetPc; +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implements SEH-based Itanium C++ exceptions. +// +//===----------------------------------------------------------------------===// + +#include "config.h" + +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + +#include <unwind.h> + +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> + +#include <windef.h> +#include <excpt.h> +#include <winnt.h> +#include <ntstatus.h> + +#include "libunwind_ext.h" +#include "UnwindCursor.hpp" + +using namespace libunwind; + +#define STATUS_USER_DEFINED (1u << 29) + +#define STATUS_GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C') + +#define MAKE_CUSTOM_STATUS(s, c) \ + ((NTSTATUS)(((s) << 30) | STATUS_USER_DEFINED | (c))) +#define MAKE_GCC_EXCEPTION(c) \ + MAKE_CUSTOM_STATUS(STATUS_SEVERITY_SUCCESS, STATUS_GCC_MAGIC | ((c) << 24)) + +/// SEH exception raised by libunwind when the program calls +/// \c _Unwind_RaiseException. +#define STATUS_GCC_THROW MAKE_GCC_EXCEPTION(0) // 0x20474343 +/// SEH exception raised by libunwind to initiate phase 2 of exception +/// handling. +#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343 + +static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx); +static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor); +static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, + DISPATCHER_CONTEXT *disp); + +/// Common implementation of SEH-style handler functions used by Itanium- +/// style frames. Depending on how and why it was called, it may do one of: +/// a) Delegate to the given Itanium-style personality function; or +/// b) Initiate a collided unwind to halt unwinding. +_LIBUNWIND_EXPORT EXCEPTION_DISPOSITION +_GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, + DISPATCHER_CONTEXT *disp, _Unwind_Personality_Fn pers) { + unw_cursor_t cursor; + _Unwind_Exception *exc; + _Unwind_Action action; + struct _Unwind_Context *ctx = nullptr; + _Unwind_Reason_Code urc; + uintptr_t retval, target; + bool ours = false; + + _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler(%#010lx(%lx), %p)", + ms_exc->ExceptionCode, ms_exc->ExceptionFlags, + (void *)frame); + if (ms_exc->ExceptionCode == STATUS_GCC_UNWIND) { + if (IS_TARGET_UNWIND(ms_exc->ExceptionFlags)) { + // Set up the upper return value (the lower one and the target PC + // were set in the call to RtlUnwindEx()) for the landing pad. +#ifdef __x86_64__ + disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3]; +#elif defined(__arm__) + disp->ContextRecord->R1 = ms_exc->ExceptionInformation[3]; +#elif defined(__aarch64__) + disp->ContextRecord->X1 = ms_exc->ExceptionInformation[3]; +#endif + } + // This is the collided unwind to the landing pad. Nothing to do. + return ExceptionContinueSearch; + } + + if (ms_exc->ExceptionCode == STATUS_GCC_THROW) { + // This is (probably) a libunwind-controlled exception/unwind. Recover the + // parameters which we set below, and pass them to the personality function. + ours = true; + exc = (_Unwind_Exception *)ms_exc->ExceptionInformation[0]; + if (!IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1) { + ctx = (struct _Unwind_Context *)ms_exc->ExceptionInformation[1]; + action = (_Unwind_Action)ms_exc->ExceptionInformation[2]; + } + } else { + // Foreign exception. + // We can't interact with them (we don't know the original target frame + // that we should pass on to RtlUnwindEx in _Unwind_Resume), so just + // pass without calling our destructors here. + return ExceptionContinueSearch; + } + if (!ctx) { + __unw_init_seh(&cursor, disp->ContextRecord); + __unw_seh_set_disp_ctx(&cursor, disp); + __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc - 1); + ctx = (struct _Unwind_Context *)&cursor; + + if (!IS_UNWINDING(ms_exc->ExceptionFlags)) { + if (ours && ms_exc->NumberParameters > 1) + action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_FORCE_UNWIND); + else + action = _UA_SEARCH_PHASE; + } else { + if (ours && ms_exc->ExceptionInformation[1] == (ULONG_PTR)frame) + action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME); + else + action = _UA_CLEANUP_PHASE; + } + } + + _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler() calling personality " + "function %p(1, %d, %llx, %p, %p)", + (void *)pers, action, exc->exception_class, + (void *)exc, (void *)ctx); + urc = pers(1, action, exc->exception_class, exc, ctx); + _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler() personality returned %d", urc); + switch (urc) { + case _URC_CONTINUE_UNWIND: + // If we're in phase 2, and the personality routine said to continue + // at the target frame, we're in real trouble. + if (action & _UA_HANDLER_FRAME) + _LIBUNWIND_ABORT("Personality continued unwind at the target frame!"); + return ExceptionContinueSearch; + case _URC_HANDLER_FOUND: + // If we were called by __libunwind_seh_personality(), indicate that + // a handler was found; otherwise, initiate phase 2 by unwinding. + if (ours && ms_exc->NumberParameters > 1) + return 4 /* ExecptionExecuteHandler in mingw */; + // This should never happen in phase 2. + if (IS_UNWINDING(ms_exc->ExceptionFlags)) + _LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!"); + exc->private_[1] = (ULONG_PTR)frame; + if (ours) { + ms_exc->NumberParameters = 4; + ms_exc->ExceptionInformation[1] = (ULONG_PTR)frame; + } + // FIXME: Indicate target frame in foreign case! + // phase 2: the clean up phase + RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, ms_ctx, disp->HistoryTable); + _LIBUNWIND_ABORT("RtlUnwindEx() failed"); + case _URC_INSTALL_CONTEXT: { + // If we were called by __libunwind_seh_personality(), indicate that + // a handler was found; otherwise, it's time to initiate a collided + // unwind to the target. + if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1) + return 4 /* ExecptionExecuteHandler in mingw */; + // This should never happen in phase 1. + if (!IS_UNWINDING(ms_exc->ExceptionFlags)) + _LIBUNWIND_ABORT("Personality installed context during phase 1!"); +#ifdef __x86_64__ + exc->private_[2] = disp->TargetIp; + __unw_get_reg(&cursor, UNW_X86_64_RAX, &retval); + __unw_get_reg(&cursor, UNW_X86_64_RDX, &exc->private_[3]); +#elif defined(__arm__) + exc->private_[2] = disp->TargetPc; + __unw_get_reg(&cursor, UNW_ARM_R0, &retval); + __unw_get_reg(&cursor, UNW_ARM_R1, &exc->private_[3]); +#elif defined(__aarch64__) + exc->private_[2] = disp->TargetPc; __unw_get_reg(&cursor, UNW_AARCH64_X0, &retval); __unw_get_reg(&cursor, UNW_AARCH64_X1, &exc->private_[3]); -#endif - __unw_get_reg(&cursor, UNW_REG_IP, &target); - ms_exc->ExceptionCode = STATUS_GCC_UNWIND; -#ifdef __x86_64__ - ms_exc->ExceptionInformation[2] = disp->TargetIp; -#elif defined(__arm__) || defined(__aarch64__) - ms_exc->ExceptionInformation[2] = disp->TargetPc; -#endif - ms_exc->ExceptionInformation[3] = exc->private_[3]; - // Give NTRTL some scratch space to keep track of the collided unwind. - // Don't use the one that was passed in; we don't want to overwrite the - // context in the DISPATCHER_CONTEXT. - CONTEXT new_ctx; - RtlUnwindEx(frame, (PVOID)target, ms_exc, (PVOID)retval, &new_ctx, disp->HistoryTable); - _LIBUNWIND_ABORT("RtlUnwindEx() failed"); - } - // Anything else indicates a serious problem. - default: return ExceptionContinueExecution; - } -} - -/// Personality function returned by \c __unw_get_proc_info() in SEH contexts. -/// This is a wrapper that calls the real SEH handler function, which in -/// turn (at least, for Itanium-style frames) calls the real Itanium -/// personality function (see \c _GCC_specific_handler()). -extern "C" _Unwind_Reason_Code -__libunwind_seh_personality(int version, _Unwind_Action state, - uint64_t klass, _Unwind_Exception *exc, - struct _Unwind_Context *context) { - (void)version; - (void)klass; - EXCEPTION_RECORD ms_exc; - bool phase2 = (state & (_UA_SEARCH_PHASE|_UA_CLEANUP_PHASE)) == _UA_CLEANUP_PHASE; - ms_exc.ExceptionCode = STATUS_GCC_THROW; - ms_exc.ExceptionFlags = 0; - ms_exc.NumberParameters = 3; - ms_exc.ExceptionInformation[0] = (ULONG_PTR)exc; - ms_exc.ExceptionInformation[1] = (ULONG_PTR)context; - ms_exc.ExceptionInformation[2] = state; - DISPATCHER_CONTEXT *disp_ctx = - __unw_seh_get_disp_ctx((unw_cursor_t *)context); - EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, - (PVOID)disp_ctx->EstablisherFrame, - disp_ctx->ContextRecord, - disp_ctx); - switch (ms_act) { - case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; - case 4 /*ExceptionExecuteHandler*/: - return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; - default: - return phase2 ? _URC_FATAL_PHASE2_ERROR : _URC_FATAL_PHASE1_ERROR; - } -} - -static _Unwind_Reason_Code -unwind_phase2_forced(unw_context_t *uc, - _Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter) { - unw_cursor_t cursor2; - __unw_init_local(&cursor2, uc); - - // Walk each frame until we reach where search phase said to stop - while (__unw_step(&cursor2) > 0) { - - // Update info about this frame. - unw_proc_info_t frameInfo; - if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " - "failed => _URC_END_OF_STACK", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - +#endif + __unw_get_reg(&cursor, UNW_REG_IP, &target); + ms_exc->ExceptionCode = STATUS_GCC_UNWIND; +#ifdef __x86_64__ + ms_exc->ExceptionInformation[2] = disp->TargetIp; +#elif defined(__arm__) || defined(__aarch64__) + ms_exc->ExceptionInformation[2] = disp->TargetPc; +#endif + ms_exc->ExceptionInformation[3] = exc->private_[3]; + // Give NTRTL some scratch space to keep track of the collided unwind. + // Don't use the one that was passed in; we don't want to overwrite the + // context in the DISPATCHER_CONTEXT. + CONTEXT new_ctx; + RtlUnwindEx(frame, (PVOID)target, ms_exc, (PVOID)retval, &new_ctx, disp->HistoryTable); + _LIBUNWIND_ABORT("RtlUnwindEx() failed"); + } + // Anything else indicates a serious problem. + default: return ExceptionContinueExecution; + } +} + +/// Personality function returned by \c __unw_get_proc_info() in SEH contexts. +/// This is a wrapper that calls the real SEH handler function, which in +/// turn (at least, for Itanium-style frames) calls the real Itanium +/// personality function (see \c _GCC_specific_handler()). +extern "C" _Unwind_Reason_Code +__libunwind_seh_personality(int version, _Unwind_Action state, + uint64_t klass, _Unwind_Exception *exc, + struct _Unwind_Context *context) { + (void)version; + (void)klass; + EXCEPTION_RECORD ms_exc; + bool phase2 = (state & (_UA_SEARCH_PHASE|_UA_CLEANUP_PHASE)) == _UA_CLEANUP_PHASE; + ms_exc.ExceptionCode = STATUS_GCC_THROW; + ms_exc.ExceptionFlags = 0; + ms_exc.NumberParameters = 3; + ms_exc.ExceptionInformation[0] = (ULONG_PTR)exc; + ms_exc.ExceptionInformation[1] = (ULONG_PTR)context; + ms_exc.ExceptionInformation[2] = state; + DISPATCHER_CONTEXT *disp_ctx = + __unw_seh_get_disp_ctx((unw_cursor_t *)context); + EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, + (PVOID)disp_ctx->EstablisherFrame, + disp_ctx->ContextRecord, + disp_ctx); + switch (ms_act) { + case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; + case 4 /*ExceptionExecuteHandler*/: + return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; + default: + return phase2 ? _URC_FATAL_PHASE2_ERROR : _URC_FATAL_PHASE1_ERROR; + } +} + +static _Unwind_Reason_Code +unwind_phase2_forced(unw_context_t *uc, + _Unwind_Exception *exception_object, + _Unwind_Stop_Fn stop, void *stop_parameter) { + unw_cursor_t cursor2; + __unw_init_local(&cursor2, uc); + + // Walk each frame until we reach where search phase said to stop + while (__unw_step(&cursor2) > 0) { + + // Update info about this frame. + unw_proc_info_t frameInfo; + if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " + "failed => _URC_END_OF_STACK", + (void *)exception_object); + return _URC_FATAL_PHASE2_ERROR; + } + #ifndef NDEBUG - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((__unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || - (frameInfo.start_ip + offset > frameInfo.end_ip)) - functionName = ".anonymous."; - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64 - ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64, - (void *)exception_object, frameInfo.start_ip, functionName, - frameInfo.lsda, frameInfo.handler); - } -#endif - - // Call stop function at each frame. - _Unwind_Action action = - (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); - _Unwind_Reason_Code stopResult = - (*stop)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(&cursor2), stop_parameter); - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", - (void *)exception_object, stopResult); - if (stopResult != _URC_NO_REASON) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // If there is a personality routine, tell it we are unwinding. - if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = - (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", - (void *)exception_object, (void *)(uintptr_t)p); - _Unwind_Reason_Code personalityResult = - (*p)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(&cursor2)); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned " - "_URC_CONTINUE_UNWIND", - (void *)exception_object); - // Destructors called, continue unwinding - break; - case _URC_INSTALL_CONTEXT: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned " - "_URC_INSTALL_CONTEXT", - (void *)exception_object); - // We may get control back if landing pad calls _Unwind_Resume(). - __unw_resume(&cursor2); - break; - default: - // Personality routine returned an unknown result code. - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR", - (void *)exception_object, personalityResult); - return _URC_FATAL_PHASE2_ERROR; - } - } - } - - // Call stop function one last time and tell it we've reached the end - // of the stack. - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " - "function with _UA_END_OF_STACK", - (void *)exception_object); - _Unwind_Action lastAction = - (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); - (*stop)(1, lastAction, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(&cursor2), stop_parameter); - - // Clean up phase did not resume at the frame that the search phase said it - // would. - return _URC_FATAL_PHASE2_ERROR; -} - -/// Called by \c __cxa_throw(). Only returns if there is a fatal error. -_LIBUNWIND_EXPORT _Unwind_Reason_Code -_Unwind_RaiseException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", - (void *)exception_object); - - // Mark that this is a non-forced unwind, so _Unwind_Resume() - // can do the right thing. - memset(exception_object->private_, 0, sizeof(exception_object->private_)); - - // phase 1: the search phase - // We'll let the system do that for us. - RaiseException(STATUS_GCC_THROW, 0, 1, (ULONG_PTR *)&exception_object); - - // If we get here, either something went horribly wrong or we reached the - // top of the stack. Either way, let libc++abi call std::terminate(). - return _URC_END_OF_STACK; -} - -/// When \c _Unwind_RaiseException() is in phase2, it hands control -/// to the personality function at each frame. The personality -/// may force a jump to a landing pad in that function; the landing -/// pad code may then call \c _Unwind_Resume() to continue with the -/// unwinding. Note: the call to \c _Unwind_Resume() is from compiler -/// geneated user code. All other \c _Unwind_* routines are called -/// by the C++ runtime \c __cxa_* routines. -/// -/// Note: re-throwing an exception (as opposed to continuing the unwind) -/// is implemented by having the code call \c __cxa_rethrow() which -/// in turn calls \c _Unwind_Resume_or_Rethrow(). -_LIBUNWIND_EXPORT void -_Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); - - if (exception_object->private_[0] != 0) { - unw_context_t uc; - - __unw_getcontext(&uc); - unwind_phase2_forced(&uc, exception_object, - (_Unwind_Stop_Fn) exception_object->private_[0], - (void *)exception_object->private_[4]); - } else { - // Recover the parameters for the unwind from the exception object - // so we can start unwinding again. - EXCEPTION_RECORD ms_exc; - CONTEXT ms_ctx; - UNWIND_HISTORY_TABLE hist; - - memset(&ms_exc, 0, sizeof(ms_exc)); - memset(&hist, 0, sizeof(hist)); - ms_exc.ExceptionCode = STATUS_GCC_THROW; - ms_exc.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - ms_exc.NumberParameters = 4; - ms_exc.ExceptionInformation[0] = (ULONG_PTR)exception_object; - ms_exc.ExceptionInformation[1] = exception_object->private_[1]; - ms_exc.ExceptionInformation[2] = exception_object->private_[2]; - ms_exc.ExceptionInformation[3] = exception_object->private_[3]; - RtlUnwindEx((PVOID)exception_object->private_[1], - (PVOID)exception_object->private_[2], &ms_exc, - exception_object, &ms_ctx, &hist); - } - - // Clients assume _Unwind_Resume() does not return, so all we can do is abort. - _LIBUNWIND_ABORT("_Unwind_Resume() can't return"); -} - -/// Not used by C++. -/// Unwinds stack, calling "stop" function at each frame. -/// Could be used to implement \c longjmp(). -_LIBUNWIND_EXPORT _Unwind_Reason_Code -_Unwind_ForcedUnwind(_Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter) { - _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", - (void *)exception_object, (void *)(uintptr_t)stop); - unw_context_t uc; - __unw_getcontext(&uc); - - // Mark that this is a forced unwind, so _Unwind_Resume() can do - // the right thing. - exception_object->private_[0] = (uintptr_t) stop; - exception_object->private_[4] = (uintptr_t) stop_parameter; - - // do it - return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter); -} - -/// Called by personality handler during phase 2 to get LSDA for current frame. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { - uintptr_t result = - (uintptr_t)__unw_seh_get_disp_ctx((unw_cursor_t *)context)->HandlerData; - _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR, - (void *)context, result); - return result; -} - -/// Called by personality handler during phase 2 to find the start of the -/// function. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetRegionStart(struct _Unwind_Context *context) { - DISPATCHER_CONTEXT *disp = __unw_seh_get_disp_ctx((unw_cursor_t *)context); - uintptr_t result = (uintptr_t)disp->FunctionEntry->BeginAddress + disp->ImageBase; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR, - (void *)context, result); - return result; -} - -static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { -#ifdef _LIBUNWIND_TARGET_X86_64 - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)) - UnwindCursor<LocalAddressSpace, Registers_x86_64>( - context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); - co->setInfoBasedOnIPRegister(); - return UNW_ESUCCESS; -#elif defined(_LIBUNWIND_TARGET_ARM) - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)) - UnwindCursor<LocalAddressSpace, Registers_arm>( - context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); - co->setInfoBasedOnIPRegister(); - return UNW_ESUCCESS; -#elif defined(_LIBUNWIND_TARGET_AARCH64) - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)) - UnwindCursor<LocalAddressSpace, Registers_arm64>( - context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); - co->setInfoBasedOnIPRegister(); - return UNW_ESUCCESS; -#else - return UNW_EINVAL; -#endif -} - -static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { -#ifdef _LIBUNWIND_TARGET_X86_64 - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext(); -#elif defined(_LIBUNWIND_TARGET_ARM) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext(); -#elif defined(_LIBUNWIND_TARGET_AARCH64) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->getDispatcherContext(); -#else - return nullptr; -#endif -} - -static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, - DISPATCHER_CONTEXT *disp) { -#ifdef _LIBUNWIND_TARGET_X86_64 - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->setDispatcherContext(disp); -#elif defined(_LIBUNWIND_TARGET_ARM) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp); -#elif defined(_LIBUNWIND_TARGET_AARCH64) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->setDispatcherContext(disp); + // When tracing, print state information. + if (_LIBUNWIND_TRACING_UNWINDING) { + char functionBuf[512]; + const char *functionName = functionBuf; + unw_word_t offset; + if ((__unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || + (frameInfo.start_ip + offset > frameInfo.end_ip)) + functionName = ".anonymous."; + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64 + ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64, + (void *)exception_object, frameInfo.start_ip, functionName, + frameInfo.lsda, frameInfo.handler); + } #endif -} - -#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + + // Call stop function at each frame. + _Unwind_Action action = + (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); + _Unwind_Reason_Code stopResult = + (*stop)(1, action, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)(&cursor2), stop_parameter); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", + (void *)exception_object, stopResult); + if (stopResult != _URC_NO_REASON) { + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", + (void *)exception_object); + return _URC_FATAL_PHASE2_ERROR; + } + + // If there is a personality routine, tell it we are unwinding. + if (frameInfo.handler != 0) { + _Unwind_Personality_Fn p = + (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", + (void *)exception_object, (void *)(uintptr_t)p); + _Unwind_Reason_Code personalityResult = + (*p)(1, action, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)(&cursor2)); + switch (personalityResult) { + case _URC_CONTINUE_UNWIND: + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned " + "_URC_CONTINUE_UNWIND", + (void *)exception_object); + // Destructors called, continue unwinding + break; + case _URC_INSTALL_CONTEXT: + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned " + "_URC_INSTALL_CONTEXT", + (void *)exception_object); + // We may get control back if landing pad calls _Unwind_Resume(). + __unw_resume(&cursor2); + break; + default: + // Personality routine returned an unknown result code. + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned %d, " + "_URC_FATAL_PHASE2_ERROR", + (void *)exception_object, personalityResult); + return _URC_FATAL_PHASE2_ERROR; + } + } + } + + // Call stop function one last time and tell it we've reached the end + // of the stack. + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " + "function with _UA_END_OF_STACK", + (void *)exception_object); + _Unwind_Action lastAction = + (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); + (*stop)(1, lastAction, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)(&cursor2), stop_parameter); + + // Clean up phase did not resume at the frame that the search phase said it + // would. + return _URC_FATAL_PHASE2_ERROR; +} + +/// Called by \c __cxa_throw(). Only returns if there is a fatal error. +_LIBUNWIND_EXPORT _Unwind_Reason_Code +_Unwind_RaiseException(_Unwind_Exception *exception_object) { + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", + (void *)exception_object); + + // Mark that this is a non-forced unwind, so _Unwind_Resume() + // can do the right thing. + memset(exception_object->private_, 0, sizeof(exception_object->private_)); + + // phase 1: the search phase + // We'll let the system do that for us. + RaiseException(STATUS_GCC_THROW, 0, 1, (ULONG_PTR *)&exception_object); + + // If we get here, either something went horribly wrong or we reached the + // top of the stack. Either way, let libc++abi call std::terminate(). + return _URC_END_OF_STACK; +} + +/// When \c _Unwind_RaiseException() is in phase2, it hands control +/// to the personality function at each frame. The personality +/// may force a jump to a landing pad in that function; the landing +/// pad code may then call \c _Unwind_Resume() to continue with the +/// unwinding. Note: the call to \c _Unwind_Resume() is from compiler +/// geneated user code. All other \c _Unwind_* routines are called +/// by the C++ runtime \c __cxa_* routines. +/// +/// Note: re-throwing an exception (as opposed to continuing the unwind) +/// is implemented by having the code call \c __cxa_rethrow() which +/// in turn calls \c _Unwind_Resume_or_Rethrow(). +_LIBUNWIND_EXPORT void +_Unwind_Resume(_Unwind_Exception *exception_object) { + _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); + + if (exception_object->private_[0] != 0) { + unw_context_t uc; + + __unw_getcontext(&uc); + unwind_phase2_forced(&uc, exception_object, + (_Unwind_Stop_Fn) exception_object->private_[0], + (void *)exception_object->private_[4]); + } else { + // Recover the parameters for the unwind from the exception object + // so we can start unwinding again. + EXCEPTION_RECORD ms_exc; + CONTEXT ms_ctx; + UNWIND_HISTORY_TABLE hist; + + memset(&ms_exc, 0, sizeof(ms_exc)); + memset(&hist, 0, sizeof(hist)); + ms_exc.ExceptionCode = STATUS_GCC_THROW; + ms_exc.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + ms_exc.NumberParameters = 4; + ms_exc.ExceptionInformation[0] = (ULONG_PTR)exception_object; + ms_exc.ExceptionInformation[1] = exception_object->private_[1]; + ms_exc.ExceptionInformation[2] = exception_object->private_[2]; + ms_exc.ExceptionInformation[3] = exception_object->private_[3]; + RtlUnwindEx((PVOID)exception_object->private_[1], + (PVOID)exception_object->private_[2], &ms_exc, + exception_object, &ms_ctx, &hist); + } + + // Clients assume _Unwind_Resume() does not return, so all we can do is abort. + _LIBUNWIND_ABORT("_Unwind_Resume() can't return"); +} + +/// Not used by C++. +/// Unwinds stack, calling "stop" function at each frame. +/// Could be used to implement \c longjmp(). +_LIBUNWIND_EXPORT _Unwind_Reason_Code +_Unwind_ForcedUnwind(_Unwind_Exception *exception_object, + _Unwind_Stop_Fn stop, void *stop_parameter) { + _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", + (void *)exception_object, (void *)(uintptr_t)stop); + unw_context_t uc; + __unw_getcontext(&uc); + + // Mark that this is a forced unwind, so _Unwind_Resume() can do + // the right thing. + exception_object->private_[0] = (uintptr_t) stop; + exception_object->private_[4] = (uintptr_t) stop_parameter; + + // do it + return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter); +} + +/// Called by personality handler during phase 2 to get LSDA for current frame. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { + uintptr_t result = + (uintptr_t)__unw_seh_get_disp_ctx((unw_cursor_t *)context)->HandlerData; + _LIBUNWIND_TRACE_API( + "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR, + (void *)context, result); + return result; +} + +/// Called by personality handler during phase 2 to find the start of the +/// function. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetRegionStart(struct _Unwind_Context *context) { + DISPATCHER_CONTEXT *disp = __unw_seh_get_disp_ctx((unw_cursor_t *)context); + uintptr_t result = (uintptr_t)disp->FunctionEntry->BeginAddress + disp->ImageBase; + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR, + (void *)context, result); + return result; +} + +static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { +#ifdef _LIBUNWIND_TARGET_X86_64 + new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)) + UnwindCursor<LocalAddressSpace, Registers_x86_64>( + context, LocalAddressSpace::sThisAddressSpace); + auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); + co->setInfoBasedOnIPRegister(); + return UNW_ESUCCESS; +#elif defined(_LIBUNWIND_TARGET_ARM) + new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)) + UnwindCursor<LocalAddressSpace, Registers_arm>( + context, LocalAddressSpace::sThisAddressSpace); + auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); + co->setInfoBasedOnIPRegister(); + return UNW_ESUCCESS; +#elif defined(_LIBUNWIND_TARGET_AARCH64) + new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)) + UnwindCursor<LocalAddressSpace, Registers_arm64>( + context, LocalAddressSpace::sThisAddressSpace); + auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); + co->setInfoBasedOnIPRegister(); + return UNW_ESUCCESS; +#else + return UNW_EINVAL; +#endif +} + +static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { +#ifdef _LIBUNWIND_TARGET_X86_64 + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext(); +#elif defined(_LIBUNWIND_TARGET_ARM) + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext(); +#elif defined(_LIBUNWIND_TARGET_AARCH64) + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->getDispatcherContext(); +#else + return nullptr; +#endif +} + +static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, + DISPATCHER_CONTEXT *disp) { +#ifdef _LIBUNWIND_TARGET_X86_64 + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->setDispatcherContext(disp); +#elif defined(_LIBUNWIND_TARGET_ARM) + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp); +#elif defined(_LIBUNWIND_TARGET_AARCH64) + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->setDispatcherContext(disp); +#endif +} + +#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) diff --git a/contrib/libs/libunwind/src/Unwind-sjlj.c b/contrib/libs/libunwind/src/Unwind-sjlj.c index d487995bb7..449354686b 100644 --- a/contrib/libs/libunwind/src/Unwind-sjlj.c +++ b/contrib/libs/libunwind/src/Unwind-sjlj.c @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Implements setjump-longjump based C++ exceptions @@ -11,22 +11,22 @@ #include <unwind.h> -#include <inttypes.h> +#include <inttypes.h> #include <stdint.h> #include <stdbool.h> #include <stdlib.h> #include "config.h" -/// With SJLJ based exceptions, any function that has a catch clause or needs to -/// do any clean up when an exception propagates through it, needs to call -/// \c _Unwind_SjLj_Register at the start of the function and -/// \c _Unwind_SjLj_Unregister at the end. The register function is called with -/// the address of a block of memory in the function's stack frame. The runtime -/// keeps a linked list (stack) of these blocks - one per thread. The calling -/// function also sets the personality and lsda fields of the block. +/// With SJLJ based exceptions, any function that has a catch clause or needs to +/// do any clean up when an exception propagates through it, needs to call +/// \c _Unwind_SjLj_Register at the start of the function and +/// \c _Unwind_SjLj_Unregister at the end. The register function is called with +/// the address of a block of memory in the function's stack frame. The runtime +/// keeps a linked list (stack) of these blocks - one per thread. The calling +/// function also sets the personality and lsda fields of the block. -#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) +#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) struct _Unwind_FunctionContext { // next function in stack of handlers @@ -44,14 +44,14 @@ struct _Unwind_FunctionContext { uint64_t resumeParameters[4]; #else // set by calling function before registering to be the landing pad - uint32_t resumeLocation; + uint32_t resumeLocation; // set by personality handler to be parameters passed to landing pad function - uint32_t resumeParameters[4]; + uint32_t resumeParameters[4]; #endif // set by calling function before registering - _Unwind_Personality_Fn personality; // arm offset=24 + _Unwind_Personality_Fn personality; // arm offset=24 uintptr_t lsda; // arm offset=28 // variable length array, contains registers to restore @@ -59,49 +59,49 @@ struct _Unwind_FunctionContext { void *jbuf[]; }; -#if defined(_LIBUNWIND_HAS_NO_THREADS) -# define _LIBUNWIND_THREAD_LOCAL -#else -# if __STDC_VERSION__ >= 201112L -# define _LIBUNWIND_THREAD_LOCAL _Thread_local -# elif defined(_MSC_VER) -# define _LIBUNWIND_THREAD_LOCAL __declspec(thread) -# elif defined(__GNUC__) || defined(__clang__) -# define _LIBUNWIND_THREAD_LOCAL __thread -# else -# error Unable to create thread local storage -# endif -#endif - - -#if !defined(FOR_DYLD) - -#if defined(__APPLE__) -#include <System/pthread_machdep.h> -#else -static _LIBUNWIND_THREAD_LOCAL struct _Unwind_FunctionContext *stack = NULL; -#endif - -static struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() { -#if defined(__APPLE__) - return _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key); -#else - return stack; -#endif -} - -static void -__Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) { -#if defined(__APPLE__) - _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc); -#else - stack = fc; -#endif -} - -#endif - - +#if defined(_LIBUNWIND_HAS_NO_THREADS) +# define _LIBUNWIND_THREAD_LOCAL +#else +# if __STDC_VERSION__ >= 201112L +# define _LIBUNWIND_THREAD_LOCAL _Thread_local +# elif defined(_MSC_VER) +# define _LIBUNWIND_THREAD_LOCAL __declspec(thread) +# elif defined(__GNUC__) || defined(__clang__) +# define _LIBUNWIND_THREAD_LOCAL __thread +# else +# error Unable to create thread local storage +# endif +#endif + + +#if !defined(FOR_DYLD) + +#if defined(__APPLE__) +#include <System/pthread_machdep.h> +#else +static _LIBUNWIND_THREAD_LOCAL struct _Unwind_FunctionContext *stack = NULL; +#endif + +static struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() { +#if defined(__APPLE__) + return _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key); +#else + return stack; +#endif +} + +static void +__Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) { +#if defined(__APPLE__) + _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc); +#else + stack = fc; +#endif +} + +#endif + + /// Called at start of each function that catches exceptions _LIBUNWIND_EXPORT void _Unwind_SjLj_Register(struct _Unwind_FunctionContext *fc) { @@ -120,8 +120,8 @@ _Unwind_SjLj_Unregister(struct _Unwind_FunctionContext *fc) { static _Unwind_Reason_Code unwind_phase1(struct _Unwind_Exception *exception_object) { _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack(); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p", - (void *)c); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p", + (void *)c); // walk each frame looking for a place to stop for (bool handlerNotFound = true; handlerNotFound; c = c->prev) { @@ -129,19 +129,19 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { // check for no more frames if (c == NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): reached " - "bottom => _URC_END_OF_STACK", - (void *)exception_object); + "bottom => _URC_END_OF_STACK", + (void *)exception_object); return _URC_END_OF_STACK; } - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", (void *)c); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", (void *)c); // if there is a personality routine, ask it if it will want to stop at this // frame if (c->personality != NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): calling " - "personality function %p", - (void *)exception_object, - (void *)c->personality); + "personality function %p", + (void *)exception_object, + (void *)c->personality); _Unwind_Reason_Code personalityResult = (*c->personality)( 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, (struct _Unwind_Context *)c); @@ -152,22 +152,22 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { handlerNotFound = false; exception_object->private_2 = (uintptr_t) c; _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_HANDLER_FOUND", - (void *)exception_object); + "_URC_HANDLER_FOUND", + (void *)exception_object); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_CONTINUE_UNWIND", - (void *)exception_object); + "_URC_CONTINUE_UNWIND", + (void *)exception_object); // continue unwinding break; default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", - (void *)exception_object); + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", + (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } } @@ -178,21 +178,21 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { static _Unwind_Reason_Code unwind_phase2(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", + (void *)exception_object); // walk each frame until we reach where search phase said to stop _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack(); while (true) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p", - (void *)exception_object, (void *)c); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p", + (void *)exception_object, (void *)c); // check for no more frames if (c == NULL) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step() reached " - "bottom => _URC_END_OF_STACK", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_step() reached " + "bottom => _URC_END_OF_STACK", + (void *)exception_object); return _URC_END_OF_STACK; } @@ -211,8 +211,8 @@ unwind_phase2(struct _Unwind_Exception *exception_object) { case _URC_CONTINUE_UNWIND: // continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", - (void *)exception_object); + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", + (void *)exception_object); if ((uintptr_t) c == exception_object->private_2) { // phase 1 said we would stop at this frame, but we did not... _LIBUNWIND_ABORT("during phase1 personality function said it would " @@ -221,14 +221,14 @@ unwind_phase2(struct _Unwind_Exception *exception_object) { break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): " - "_URC_INSTALL_CONTEXT, will resume at " - "landing pad %p", - (void *)exception_object, c->jbuf[1]); + "_URC_INSTALL_CONTEXT, will resume at " + "landing pad %p", + (void *)exception_object, c->jbuf[1]); // personality routine says to transfer control to landing pad // we may get control back if landing pad calls _Unwind_Resume() __Unwind_SjLj_SetTopOfFunctionStack(c); __builtin_longjmp(c->jbuf, 1); - // __unw_resume() only returns if there was an error + // __unw_resume() only returns if there was an error return _URC_FATAL_PHASE2_ERROR; default: // something went wrong @@ -255,10 +255,10 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // get next frame (skip over first which is _Unwind_RaiseException) if (c == NULL) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step() reached " - "bottom => _URC_END_OF_STACK", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_step() reached " + "bottom => _URC_END_OF_STACK", + (void *)exception_object); return _URC_END_OF_STACK; } @@ -269,35 +269,35 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, (*stop)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)c, stop_parameter); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "stop function returned %d", - (void *)exception_object, stopResult); + "stop function returned %d", + (void *)exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "stopped by stop function", - (void *)exception_object); + "stopped by stop function", + (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } // if there is a personality routine, tell it we are unwinding if (c->personality != NULL) { - _Unwind_Personality_Fn p = (_Unwind_Personality_Fn)c->personality; + _Unwind_Personality_Fn p = (_Unwind_Personality_Fn)c->personality; _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "calling personality function %p", - (void *)exception_object, (void *)p); + "calling personality function %p", + (void *)exception_object, (void *)p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)c); switch (personalityResult) { case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned _URC_CONTINUE_UNWIND", - (void *)exception_object); + "personality returned _URC_CONTINUE_UNWIND", + (void *)exception_object); // destructors called, continue unwinding break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned _URC_INSTALL_CONTEXT", - (void *)exception_object); + "personality returned _URC_INSTALL_CONTEXT", + (void *)exception_object); // we may get control back if landing pad calls _Unwind_Resume() __Unwind_SjLj_SetTopOfFunctionStack(c); __builtin_longjmp(c->jbuf, 1); @@ -306,8 +306,8 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // something went wrong _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR", - (void *)exception_object, personalityResult); + "_URC_FATAL_PHASE2_ERROR", + (void *)exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } } @@ -317,8 +317,8 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // call stop function one last time and tell it we've reached the end of the // stack _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " - "function with _UA_END_OF_STACK", - (void *)exception_object); + "function with _UA_END_OF_STACK", + (void *)exception_object); _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); (*stop)(1, lastAction, exception_object->exception_class, exception_object, @@ -333,8 +333,8 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, /// Called by __cxa_throw. Only returns if there is a fatal error _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)", - (void *)exception_object); + _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)", + (void *)exception_object); // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right // thing @@ -364,8 +364,8 @@ _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) { /// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow() _LIBUNWIND_EXPORT void _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)", - (void *)exception_object); + _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)", + (void *)exception_object); if (exception_object->private_1 != 0) unwind_phase2_forced(exception_object, @@ -383,8 +383,8 @@ _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) { _LIBUNWIND_TRACE_API("__Unwind_SjLj_Resume_or_Rethrow(ex_obj=%p), " - "private_1=%" PRIuPTR, - (void *)exception_object, exception_object->private_1); + "private_1=%" PRIuPTR, + (void *)exception_object, exception_object->private_1); // If this is non-forced and a stopping place was found, then this is a // re-throw. // Call _Unwind_RaiseException() as if this was a new exception. @@ -407,8 +407,8 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) " - "=> 0x%" PRIuPTR, - (void *)context, ufc->lsda); + "=> 0x%" PRIuPTR, + (void *)context, ufc->lsda); return ufc->lsda; } @@ -416,8 +416,8 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { /// Called by personality handler during phase 2 to get register values. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { - _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)", (void *)context, - index); + _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)", (void *)context, + index); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; return ufc->resumeParameters[index]; } @@ -426,9 +426,9 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, /// Called by personality handler during phase 2 to alter register values. _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, uintptr_t new_value) { - _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%" PRIuPTR - ")", - (void *)context, index, new_value); + _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%" PRIuPTR + ")", + (void *)context, index, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; ufc->resumeParameters[index] = new_value; } @@ -437,8 +437,8 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, /// Called by personality handler during phase 2 to get instruction pointer. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIu32, - (void *)context, ufc->resumeLocation + 1); + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIu32, + (void *)context, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -450,9 +450,9 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, int *ipBefore) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; *ipBefore = 0; - _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%" PRIu32, - (void *)context, (void *)ipBefore, - ufc->resumeLocation + 1); + _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%" PRIu32, + (void *)context, (void *)ipBefore, + ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -460,8 +460,8 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, /// Called by personality handler during phase 2 to alter instruction pointer. _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t new_value) { - _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%" PRIuPTR ")", - (void *)context, new_value); + _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%" PRIuPTR ")", + (void *)context, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; ufc->resumeLocation = new_value - 1; } @@ -473,7 +473,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", (void *)context); return 0; } @@ -482,8 +482,8 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { /// is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", - (void *)exception_object); + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", + (void *)exception_object); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object); @@ -497,7 +497,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); } @@ -508,14 +508,14 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented"); } /// Called by personality handler to get "Call Frame Area" for current frame. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { - _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)", (void *)context); if (context != NULL) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; // Setjmp/longjmp based exceptions don't have a true CFA. @@ -525,4 +525,4 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { return 0; } -#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) +#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) diff --git a/contrib/libs/libunwind/src/UnwindCursor.hpp b/contrib/libs/libunwind/src/UnwindCursor.hpp index 1ca842f33a..e8cabba0ea 100644 --- a/contrib/libs/libunwind/src/UnwindCursor.hpp +++ b/contrib/libs/libunwind/src/UnwindCursor.hpp @@ -1,11 +1,11 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -// C++ interface to lower levels of libunwind +// C++ interface to lower levels of libunwind //===----------------------------------------------------------------------===// #ifndef __UNWINDCURSOR_HPP__ @@ -17,51 +17,51 @@ #include <stdlib.h> #include <unwind.h> -#ifdef _WIN32 - #include <windows.h> - #include <ntverp.h> -#endif +#ifdef _WIN32 + #include <windows.h> + #include <ntverp.h> +#endif #ifdef __APPLE__ #include <mach-o/dyld.h> #endif -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) -// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and -// earlier) SDKs. -// MinGW-w64 has always provided this struct. - #if defined(_WIN32) && defined(_LIBUNWIND_TARGET_X86_64) && \ - !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 -struct _DISPATCHER_CONTEXT { - ULONG64 ControlPc; - ULONG64 ImageBase; - PRUNTIME_FUNCTION FunctionEntry; - ULONG64 EstablisherFrame; - ULONG64 TargetIp; - PCONTEXT ContextRecord; - PEXCEPTION_ROUTINE LanguageHandler; - PVOID HandlerData; - PUNWIND_HISTORY_TABLE HistoryTable; - ULONG ScopeIndex; - ULONG Fill0; -}; - #endif - -struct UNWIND_INFO { - uint8_t Version : 3; - uint8_t Flags : 5; - uint8_t SizeOfProlog; - uint8_t CountOfCodes; - uint8_t FrameRegister : 4; - uint8_t FrameOffset : 4; - uint16_t UnwindCodes[2]; -}; - -extern "C" _Unwind_Reason_Code __libunwind_seh_personality( - int, _Unwind_Action, uint64_t, _Unwind_Exception *, - struct _Unwind_Context *); - -#endif - +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) +// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and +// earlier) SDKs. +// MinGW-w64 has always provided this struct. + #if defined(_WIN32) && defined(_LIBUNWIND_TARGET_X86_64) && \ + !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 +struct _DISPATCHER_CONTEXT { + ULONG64 ControlPc; + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + ULONG64 EstablisherFrame; + ULONG64 TargetIp; + PCONTEXT ContextRecord; + PEXCEPTION_ROUTINE LanguageHandler; + PVOID HandlerData; + PUNWIND_HISTORY_TABLE HistoryTable; + ULONG ScopeIndex; + ULONG Fill0; +}; + #endif + +struct UNWIND_INFO { + uint8_t Version : 3; + uint8_t Flags : 5; + uint8_t SizeOfProlog; + uint8_t CountOfCodes; + uint8_t FrameRegister : 4; + uint8_t FrameOffset : 4; + uint16_t UnwindCodes[2]; +}; + +extern "C" _Unwind_Reason_Code __libunwind_seh_personality( + int, _Unwind_Action, uint64_t, _Unwind_Exception *, + struct _Unwind_Context *); + +#endif + #include "config.h" #include "AddressSpace.hpp" @@ -71,18 +71,18 @@ extern "C" _Unwind_Reason_Code __libunwind_seh_personality( #include "EHHeaderParser.hpp" #include "libunwind.h" #include "Registers.hpp" -#include "RWMutex.hpp" +#include "RWMutex.hpp" #include "Unwind-EHABI.h" namespace libunwind { -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) /// Cache of recently found FDEs. template <typename A> class _LIBUNWIND_HIDDEN DwarfFDECache { typedef typename A::pint_t pint_t; public: - static constexpr pint_t kSearchAll = static_cast<pint_t>(-1); + static constexpr pint_t kSearchAll = static_cast<pint_t>(-1); static pint_t findFDE(pint_t mh, pint_t pc); static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde); static void removeAllIn(pint_t mh); @@ -101,7 +101,7 @@ private: // These fields are all static to avoid needing an initializer. // There is only one instance of this class per process. - static RWMutex _lock; + static RWMutex _lock; #ifdef __APPLE__ static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); static bool _registeredForDyldUnloads; @@ -128,7 +128,7 @@ template <typename A> typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64]; template <typename A> -RWMutex DwarfFDECache<A>::_lock; +RWMutex DwarfFDECache<A>::_lock; #ifdef __APPLE__ template <typename A> @@ -138,16 +138,16 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false; template <typename A> typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) { pint_t result = 0; - _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared()); + _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared()); for (entry *p = _buffer; p < _bufferUsed; ++p) { - if ((mh == p->mh) || (mh == kSearchAll)) { + if ((mh == p->mh) || (mh == kSearchAll)) { if ((p->ip_start <= pc) && (pc < p->ip_end)) { result = p->fde; break; } } } - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock_shared()); + _LIBUNWIND_LOG_IF_FALSE(_lock.unlock_shared()); return result; } @@ -155,7 +155,7 @@ template <typename A> void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde) { #if !defined(_LIBUNWIND_NO_HEAP) - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); if (_bufferUsed >= _bufferEnd) { size_t oldSize = (size_t)(_bufferEnd - _buffer); size_t newSize = oldSize * 4; @@ -179,13 +179,13 @@ void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, _registeredForDyldUnloads = true; } #endif - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); #endif } template <typename A> void DwarfFDECache<A>::removeAllIn(pint_t mh) { - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); entry *d = _buffer; for (const entry *s = _buffer; s < _bufferUsed; ++s) { if (s->mh != mh) { @@ -195,7 +195,7 @@ void DwarfFDECache<A>::removeAllIn(pint_t mh) { } } _bufferUsed = d; - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); } #ifdef __APPLE__ @@ -208,18 +208,18 @@ void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) { template <typename A> void DwarfFDECache<A>::iterateCacheEntries(void (*func)( unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); for (entry *p = _buffer; p < _bufferUsed; ++p) { (*func)(p->ip_start, p->ip_end, p->fde, p->mh); } - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); + _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); } -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field)) -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) template <typename A> class UnwindSectionHeader { public: UnwindSectionHeader(A &addressSpace, typename A::pint_t addr) @@ -407,7 +407,7 @@ private: A &_addressSpace; typename A::pint_t _addr; }; -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) class _LIBUNWIND_HIDDEN AbstractUnwindCursor { public: @@ -458,306 +458,306 @@ public: #endif }; -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32) - -/// \c UnwindCursor contains all state (including all register values) during -/// an unwind. This is normally stack-allocated inside a unw_cursor_t. -template <typename A, typename R> -class UnwindCursor : public AbstractUnwindCursor { - typedef typename A::pint_t pint_t; -public: - UnwindCursor(unw_context_t *context, A &as); - UnwindCursor(CONTEXT *context, A &as); - UnwindCursor(A &as, void *threadArg); - virtual ~UnwindCursor() {} - virtual bool validReg(int); - virtual unw_word_t getReg(int); - virtual void setReg(int, unw_word_t); - virtual bool validFloatReg(int); - virtual unw_fpreg_t getFloatReg(int); - virtual void setFloatReg(int, unw_fpreg_t); - virtual int step(); - virtual void getInfo(unw_proc_info_t *); - virtual void jumpto(); - virtual bool isSignalFrame(); - virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); - virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); - virtual const char *getRegisterName(int num); -#ifdef __arm__ - virtual void saveVFPAsX(); -#endif - - DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; } - void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; } - - // libunwind does not and should not depend on C++ library which means that we - // need our own defition of inline placement new. - static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } - -private: - - pint_t getLastPC() const { return _dispContext.ControlPc; } - void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; } - RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) { - _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc, - &_dispContext.ImageBase, - _dispContext.HistoryTable); - *base = _dispContext.ImageBase; - return _dispContext.FunctionEntry; - } - bool getInfoFromSEH(pint_t pc); - int stepWithSEHData() { - _dispContext.LanguageHandler = RtlVirtualUnwind(UNW_FLAG_UHANDLER, - _dispContext.ImageBase, - _dispContext.ControlPc, - _dispContext.FunctionEntry, - _dispContext.ContextRecord, - &_dispContext.HandlerData, - &_dispContext.EstablisherFrame, - NULL); - // Update some fields of the unwind info now, since we have them. - _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData); - if (_dispContext.LanguageHandler) { - _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); - } else - _info.handler = 0; - return UNW_STEP_SUCCESS; - } - - A &_addressSpace; - unw_proc_info_t _info; - DISPATCHER_CONTEXT _dispContext; - CONTEXT _msContext; - UNWIND_HISTORY_TABLE _histTable; - bool _unwindInfoMissing; -}; - - -template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) - : _addressSpace(as), _unwindInfoMissing(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); - static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), - "UnwindCursor<> requires more alignment than unw_cursor_t"); - memset(&_info, 0, sizeof(_info)); - memset(&_histTable, 0, sizeof(_histTable)); - _dispContext.ContextRecord = &_msContext; - _dispContext.HistoryTable = &_histTable; - // Initialize MS context from ours. - R r(context); - _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; -#if defined(_LIBUNWIND_TARGET_X86_64) - _msContext.Rax = r.getRegister(UNW_X86_64_RAX); - _msContext.Rcx = r.getRegister(UNW_X86_64_RCX); - _msContext.Rdx = r.getRegister(UNW_X86_64_RDX); - _msContext.Rbx = r.getRegister(UNW_X86_64_RBX); - _msContext.Rsp = r.getRegister(UNW_X86_64_RSP); - _msContext.Rbp = r.getRegister(UNW_X86_64_RBP); - _msContext.Rsi = r.getRegister(UNW_X86_64_RSI); - _msContext.Rdi = r.getRegister(UNW_X86_64_RDI); - _msContext.R8 = r.getRegister(UNW_X86_64_R8); - _msContext.R9 = r.getRegister(UNW_X86_64_R9); - _msContext.R10 = r.getRegister(UNW_X86_64_R10); - _msContext.R11 = r.getRegister(UNW_X86_64_R11); - _msContext.R12 = r.getRegister(UNW_X86_64_R12); - _msContext.R13 = r.getRegister(UNW_X86_64_R13); - _msContext.R14 = r.getRegister(UNW_X86_64_R14); - _msContext.R15 = r.getRegister(UNW_X86_64_R15); - _msContext.Rip = r.getRegister(UNW_REG_IP); - union { - v128 v; - M128A m; - } t; - t.v = r.getVectorRegister(UNW_X86_64_XMM0); - _msContext.Xmm0 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM1); - _msContext.Xmm1 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM2); - _msContext.Xmm2 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM3); - _msContext.Xmm3 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM4); - _msContext.Xmm4 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM5); - _msContext.Xmm5 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM6); - _msContext.Xmm6 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM7); - _msContext.Xmm7 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM8); - _msContext.Xmm8 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM9); - _msContext.Xmm9 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM10); - _msContext.Xmm10 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM11); - _msContext.Xmm11 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM12); - _msContext.Xmm12 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM13); - _msContext.Xmm13 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM14); - _msContext.Xmm14 = t.m; - t.v = r.getVectorRegister(UNW_X86_64_XMM15); - _msContext.Xmm15 = t.m; -#elif defined(_LIBUNWIND_TARGET_ARM) - _msContext.R0 = r.getRegister(UNW_ARM_R0); - _msContext.R1 = r.getRegister(UNW_ARM_R1); - _msContext.R2 = r.getRegister(UNW_ARM_R2); - _msContext.R3 = r.getRegister(UNW_ARM_R3); - _msContext.R4 = r.getRegister(UNW_ARM_R4); - _msContext.R5 = r.getRegister(UNW_ARM_R5); - _msContext.R6 = r.getRegister(UNW_ARM_R6); - _msContext.R7 = r.getRegister(UNW_ARM_R7); - _msContext.R8 = r.getRegister(UNW_ARM_R8); - _msContext.R9 = r.getRegister(UNW_ARM_R9); - _msContext.R10 = r.getRegister(UNW_ARM_R10); - _msContext.R11 = r.getRegister(UNW_ARM_R11); - _msContext.R12 = r.getRegister(UNW_ARM_R12); - _msContext.Sp = r.getRegister(UNW_ARM_SP); - _msContext.Lr = r.getRegister(UNW_ARM_LR); - _msContext.Pc = r.getRegister(UNW_ARM_IP); - for (int i = UNW_ARM_D0; i <= UNW_ARM_D31; ++i) { - union { - uint64_t w; - double d; - } d; - d.d = r.getFloatRegister(i); - _msContext.D[i - UNW_ARM_D0] = d.w; - } -#elif defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32) + +/// \c UnwindCursor contains all state (including all register values) during +/// an unwind. This is normally stack-allocated inside a unw_cursor_t. +template <typename A, typename R> +class UnwindCursor : public AbstractUnwindCursor { + typedef typename A::pint_t pint_t; +public: + UnwindCursor(unw_context_t *context, A &as); + UnwindCursor(CONTEXT *context, A &as); + UnwindCursor(A &as, void *threadArg); + virtual ~UnwindCursor() {} + virtual bool validReg(int); + virtual unw_word_t getReg(int); + virtual void setReg(int, unw_word_t); + virtual bool validFloatReg(int); + virtual unw_fpreg_t getFloatReg(int); + virtual void setFloatReg(int, unw_fpreg_t); + virtual int step(); + virtual void getInfo(unw_proc_info_t *); + virtual void jumpto(); + virtual bool isSignalFrame(); + virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); + virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); + virtual const char *getRegisterName(int num); +#ifdef __arm__ + virtual void saveVFPAsX(); +#endif + + DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; } + void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; } + + // libunwind does not and should not depend on C++ library which means that we + // need our own defition of inline placement new. + static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } + +private: + + pint_t getLastPC() const { return _dispContext.ControlPc; } + void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; } + RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) { + _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc, + &_dispContext.ImageBase, + _dispContext.HistoryTable); + *base = _dispContext.ImageBase; + return _dispContext.FunctionEntry; + } + bool getInfoFromSEH(pint_t pc); + int stepWithSEHData() { + _dispContext.LanguageHandler = RtlVirtualUnwind(UNW_FLAG_UHANDLER, + _dispContext.ImageBase, + _dispContext.ControlPc, + _dispContext.FunctionEntry, + _dispContext.ContextRecord, + &_dispContext.HandlerData, + &_dispContext.EstablisherFrame, + NULL); + // Update some fields of the unwind info now, since we have them. + _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData); + if (_dispContext.LanguageHandler) { + _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); + } else + _info.handler = 0; + return UNW_STEP_SUCCESS; + } + + A &_addressSpace; + unw_proc_info_t _info; + DISPATCHER_CONTEXT _dispContext; + CONTEXT _msContext; + UNWIND_HISTORY_TABLE _histTable; + bool _unwindInfoMissing; +}; + + +template <typename A, typename R> +UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) + : _addressSpace(as), _unwindInfoMissing(false) { + static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), + "UnwindCursor<> does not fit in unw_cursor_t"); + static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), + "UnwindCursor<> requires more alignment than unw_cursor_t"); + memset(&_info, 0, sizeof(_info)); + memset(&_histTable, 0, sizeof(_histTable)); + _dispContext.ContextRecord = &_msContext; + _dispContext.HistoryTable = &_histTable; + // Initialize MS context from ours. + R r(context); + _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; +#if defined(_LIBUNWIND_TARGET_X86_64) + _msContext.Rax = r.getRegister(UNW_X86_64_RAX); + _msContext.Rcx = r.getRegister(UNW_X86_64_RCX); + _msContext.Rdx = r.getRegister(UNW_X86_64_RDX); + _msContext.Rbx = r.getRegister(UNW_X86_64_RBX); + _msContext.Rsp = r.getRegister(UNW_X86_64_RSP); + _msContext.Rbp = r.getRegister(UNW_X86_64_RBP); + _msContext.Rsi = r.getRegister(UNW_X86_64_RSI); + _msContext.Rdi = r.getRegister(UNW_X86_64_RDI); + _msContext.R8 = r.getRegister(UNW_X86_64_R8); + _msContext.R9 = r.getRegister(UNW_X86_64_R9); + _msContext.R10 = r.getRegister(UNW_X86_64_R10); + _msContext.R11 = r.getRegister(UNW_X86_64_R11); + _msContext.R12 = r.getRegister(UNW_X86_64_R12); + _msContext.R13 = r.getRegister(UNW_X86_64_R13); + _msContext.R14 = r.getRegister(UNW_X86_64_R14); + _msContext.R15 = r.getRegister(UNW_X86_64_R15); + _msContext.Rip = r.getRegister(UNW_REG_IP); + union { + v128 v; + M128A m; + } t; + t.v = r.getVectorRegister(UNW_X86_64_XMM0); + _msContext.Xmm0 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM1); + _msContext.Xmm1 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM2); + _msContext.Xmm2 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM3); + _msContext.Xmm3 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM4); + _msContext.Xmm4 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM5); + _msContext.Xmm5 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM6); + _msContext.Xmm6 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM7); + _msContext.Xmm7 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM8); + _msContext.Xmm8 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM9); + _msContext.Xmm9 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM10); + _msContext.Xmm10 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM11); + _msContext.Xmm11 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM12); + _msContext.Xmm12 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM13); + _msContext.Xmm13 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM14); + _msContext.Xmm14 = t.m; + t.v = r.getVectorRegister(UNW_X86_64_XMM15); + _msContext.Xmm15 = t.m; +#elif defined(_LIBUNWIND_TARGET_ARM) + _msContext.R0 = r.getRegister(UNW_ARM_R0); + _msContext.R1 = r.getRegister(UNW_ARM_R1); + _msContext.R2 = r.getRegister(UNW_ARM_R2); + _msContext.R3 = r.getRegister(UNW_ARM_R3); + _msContext.R4 = r.getRegister(UNW_ARM_R4); + _msContext.R5 = r.getRegister(UNW_ARM_R5); + _msContext.R6 = r.getRegister(UNW_ARM_R6); + _msContext.R7 = r.getRegister(UNW_ARM_R7); + _msContext.R8 = r.getRegister(UNW_ARM_R8); + _msContext.R9 = r.getRegister(UNW_ARM_R9); + _msContext.R10 = r.getRegister(UNW_ARM_R10); + _msContext.R11 = r.getRegister(UNW_ARM_R11); + _msContext.R12 = r.getRegister(UNW_ARM_R12); + _msContext.Sp = r.getRegister(UNW_ARM_SP); + _msContext.Lr = r.getRegister(UNW_ARM_LR); + _msContext.Pc = r.getRegister(UNW_ARM_IP); + for (int i = UNW_ARM_D0; i <= UNW_ARM_D31; ++i) { + union { + uint64_t w; + double d; + } d; + d.d = r.getFloatRegister(i); + _msContext.D[i - UNW_ARM_D0] = d.w; + } +#elif defined(_LIBUNWIND_TARGET_AARCH64) for (int i = UNW_AARCH64_X0; i <= UNW_ARM64_X30; ++i) _msContext.X[i - UNW_AARCH64_X0] = r.getRegister(i); - _msContext.Sp = r.getRegister(UNW_REG_SP); - _msContext.Pc = r.getRegister(UNW_REG_IP); + _msContext.Sp = r.getRegister(UNW_REG_SP); + _msContext.Pc = r.getRegister(UNW_REG_IP); for (int i = UNW_AARCH64_V0; i <= UNW_ARM64_D31; ++i) _msContext.V[i - UNW_AARCH64_V0].D[0] = r.getFloatRegister(i); -#endif -} - -template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) - : _addressSpace(as), _unwindInfoMissing(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); - memset(&_info, 0, sizeof(_info)); - memset(&_histTable, 0, sizeof(_histTable)); - _dispContext.ContextRecord = &_msContext; - _dispContext.HistoryTable = &_histTable; - _msContext = *context; -} - - -template <typename A, typename R> -bool UnwindCursor<A, R>::validReg(int regNum) { - if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; -#if defined(_LIBUNWIND_TARGET_X86_64) - if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true; -#elif defined(_LIBUNWIND_TARGET_ARM) +#endif +} + +template <typename A, typename R> +UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) + : _addressSpace(as), _unwindInfoMissing(false) { + static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), + "UnwindCursor<> does not fit in unw_cursor_t"); + memset(&_info, 0, sizeof(_info)); + memset(&_histTable, 0, sizeof(_histTable)); + _dispContext.ContextRecord = &_msContext; + _dispContext.HistoryTable = &_histTable; + _msContext = *context; +} + + +template <typename A, typename R> +bool UnwindCursor<A, R>::validReg(int regNum) { + if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; +#if defined(_LIBUNWIND_TARGET_X86_64) + if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true; +#elif defined(_LIBUNWIND_TARGET_ARM) if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) || regNum == UNW_ARM_RA_AUTH_CODE) return true; -#elif defined(_LIBUNWIND_TARGET_AARCH64) +#elif defined(_LIBUNWIND_TARGET_AARCH64) if (regNum >= UNW_AARCH64_X0 && regNum <= UNW_ARM64_X30) return true; -#endif - return false; -} - -template <typename A, typename R> -unw_word_t UnwindCursor<A, R>::getReg(int regNum) { - switch (regNum) { -#if defined(_LIBUNWIND_TARGET_X86_64) - case UNW_REG_IP: return _msContext.Rip; - case UNW_X86_64_RAX: return _msContext.Rax; - case UNW_X86_64_RDX: return _msContext.Rdx; - case UNW_X86_64_RCX: return _msContext.Rcx; - case UNW_X86_64_RBX: return _msContext.Rbx; - case UNW_REG_SP: - case UNW_X86_64_RSP: return _msContext.Rsp; - case UNW_X86_64_RBP: return _msContext.Rbp; - case UNW_X86_64_RSI: return _msContext.Rsi; - case UNW_X86_64_RDI: return _msContext.Rdi; - case UNW_X86_64_R8: return _msContext.R8; - case UNW_X86_64_R9: return _msContext.R9; - case UNW_X86_64_R10: return _msContext.R10; - case UNW_X86_64_R11: return _msContext.R11; - case UNW_X86_64_R12: return _msContext.R12; - case UNW_X86_64_R13: return _msContext.R13; - case UNW_X86_64_R14: return _msContext.R14; - case UNW_X86_64_R15: return _msContext.R15; -#elif defined(_LIBUNWIND_TARGET_ARM) - case UNW_ARM_R0: return _msContext.R0; - case UNW_ARM_R1: return _msContext.R1; - case UNW_ARM_R2: return _msContext.R2; - case UNW_ARM_R3: return _msContext.R3; - case UNW_ARM_R4: return _msContext.R4; - case UNW_ARM_R5: return _msContext.R5; - case UNW_ARM_R6: return _msContext.R6; - case UNW_ARM_R7: return _msContext.R7; - case UNW_ARM_R8: return _msContext.R8; - case UNW_ARM_R9: return _msContext.R9; - case UNW_ARM_R10: return _msContext.R10; - case UNW_ARM_R11: return _msContext.R11; - case UNW_ARM_R12: return _msContext.R12; - case UNW_REG_SP: - case UNW_ARM_SP: return _msContext.Sp; - case UNW_ARM_LR: return _msContext.Lr; - case UNW_REG_IP: - case UNW_ARM_IP: return _msContext.Pc; -#elif defined(_LIBUNWIND_TARGET_AARCH64) - case UNW_REG_SP: return _msContext.Sp; - case UNW_REG_IP: return _msContext.Pc; +#endif + return false; +} + +template <typename A, typename R> +unw_word_t UnwindCursor<A, R>::getReg(int regNum) { + switch (regNum) { +#if defined(_LIBUNWIND_TARGET_X86_64) + case UNW_REG_IP: return _msContext.Rip; + case UNW_X86_64_RAX: return _msContext.Rax; + case UNW_X86_64_RDX: return _msContext.Rdx; + case UNW_X86_64_RCX: return _msContext.Rcx; + case UNW_X86_64_RBX: return _msContext.Rbx; + case UNW_REG_SP: + case UNW_X86_64_RSP: return _msContext.Rsp; + case UNW_X86_64_RBP: return _msContext.Rbp; + case UNW_X86_64_RSI: return _msContext.Rsi; + case UNW_X86_64_RDI: return _msContext.Rdi; + case UNW_X86_64_R8: return _msContext.R8; + case UNW_X86_64_R9: return _msContext.R9; + case UNW_X86_64_R10: return _msContext.R10; + case UNW_X86_64_R11: return _msContext.R11; + case UNW_X86_64_R12: return _msContext.R12; + case UNW_X86_64_R13: return _msContext.R13; + case UNW_X86_64_R14: return _msContext.R14; + case UNW_X86_64_R15: return _msContext.R15; +#elif defined(_LIBUNWIND_TARGET_ARM) + case UNW_ARM_R0: return _msContext.R0; + case UNW_ARM_R1: return _msContext.R1; + case UNW_ARM_R2: return _msContext.R2; + case UNW_ARM_R3: return _msContext.R3; + case UNW_ARM_R4: return _msContext.R4; + case UNW_ARM_R5: return _msContext.R5; + case UNW_ARM_R6: return _msContext.R6; + case UNW_ARM_R7: return _msContext.R7; + case UNW_ARM_R8: return _msContext.R8; + case UNW_ARM_R9: return _msContext.R9; + case UNW_ARM_R10: return _msContext.R10; + case UNW_ARM_R11: return _msContext.R11; + case UNW_ARM_R12: return _msContext.R12; + case UNW_REG_SP: + case UNW_ARM_SP: return _msContext.Sp; + case UNW_ARM_LR: return _msContext.Lr; + case UNW_REG_IP: + case UNW_ARM_IP: return _msContext.Pc; +#elif defined(_LIBUNWIND_TARGET_AARCH64) + case UNW_REG_SP: return _msContext.Sp; + case UNW_REG_IP: return _msContext.Pc; default: return _msContext.X[regNum - UNW_AARCH64_X0]; -#endif - } - _LIBUNWIND_ABORT("unsupported register"); -} - -template <typename A, typename R> -void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { - switch (regNum) { -#if defined(_LIBUNWIND_TARGET_X86_64) - case UNW_REG_IP: _msContext.Rip = value; break; - case UNW_X86_64_RAX: _msContext.Rax = value; break; - case UNW_X86_64_RDX: _msContext.Rdx = value; break; - case UNW_X86_64_RCX: _msContext.Rcx = value; break; - case UNW_X86_64_RBX: _msContext.Rbx = value; break; - case UNW_REG_SP: - case UNW_X86_64_RSP: _msContext.Rsp = value; break; - case UNW_X86_64_RBP: _msContext.Rbp = value; break; - case UNW_X86_64_RSI: _msContext.Rsi = value; break; - case UNW_X86_64_RDI: _msContext.Rdi = value; break; - case UNW_X86_64_R8: _msContext.R8 = value; break; - case UNW_X86_64_R9: _msContext.R9 = value; break; - case UNW_X86_64_R10: _msContext.R10 = value; break; - case UNW_X86_64_R11: _msContext.R11 = value; break; - case UNW_X86_64_R12: _msContext.R12 = value; break; - case UNW_X86_64_R13: _msContext.R13 = value; break; - case UNW_X86_64_R14: _msContext.R14 = value; break; - case UNW_X86_64_R15: _msContext.R15 = value; break; -#elif defined(_LIBUNWIND_TARGET_ARM) - case UNW_ARM_R0: _msContext.R0 = value; break; - case UNW_ARM_R1: _msContext.R1 = value; break; - case UNW_ARM_R2: _msContext.R2 = value; break; - case UNW_ARM_R3: _msContext.R3 = value; break; - case UNW_ARM_R4: _msContext.R4 = value; break; - case UNW_ARM_R5: _msContext.R5 = value; break; - case UNW_ARM_R6: _msContext.R6 = value; break; - case UNW_ARM_R7: _msContext.R7 = value; break; - case UNW_ARM_R8: _msContext.R8 = value; break; - case UNW_ARM_R9: _msContext.R9 = value; break; - case UNW_ARM_R10: _msContext.R10 = value; break; - case UNW_ARM_R11: _msContext.R11 = value; break; - case UNW_ARM_R12: _msContext.R12 = value; break; - case UNW_REG_SP: - case UNW_ARM_SP: _msContext.Sp = value; break; - case UNW_ARM_LR: _msContext.Lr = value; break; - case UNW_REG_IP: - case UNW_ARM_IP: _msContext.Pc = value; break; -#elif defined(_LIBUNWIND_TARGET_AARCH64) - case UNW_REG_SP: _msContext.Sp = value; break; - case UNW_REG_IP: _msContext.Pc = value; break; +#endif + } + _LIBUNWIND_ABORT("unsupported register"); +} + +template <typename A, typename R> +void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { + switch (regNum) { +#if defined(_LIBUNWIND_TARGET_X86_64) + case UNW_REG_IP: _msContext.Rip = value; break; + case UNW_X86_64_RAX: _msContext.Rax = value; break; + case UNW_X86_64_RDX: _msContext.Rdx = value; break; + case UNW_X86_64_RCX: _msContext.Rcx = value; break; + case UNW_X86_64_RBX: _msContext.Rbx = value; break; + case UNW_REG_SP: + case UNW_X86_64_RSP: _msContext.Rsp = value; break; + case UNW_X86_64_RBP: _msContext.Rbp = value; break; + case UNW_X86_64_RSI: _msContext.Rsi = value; break; + case UNW_X86_64_RDI: _msContext.Rdi = value; break; + case UNW_X86_64_R8: _msContext.R8 = value; break; + case UNW_X86_64_R9: _msContext.R9 = value; break; + case UNW_X86_64_R10: _msContext.R10 = value; break; + case UNW_X86_64_R11: _msContext.R11 = value; break; + case UNW_X86_64_R12: _msContext.R12 = value; break; + case UNW_X86_64_R13: _msContext.R13 = value; break; + case UNW_X86_64_R14: _msContext.R14 = value; break; + case UNW_X86_64_R15: _msContext.R15 = value; break; +#elif defined(_LIBUNWIND_TARGET_ARM) + case UNW_ARM_R0: _msContext.R0 = value; break; + case UNW_ARM_R1: _msContext.R1 = value; break; + case UNW_ARM_R2: _msContext.R2 = value; break; + case UNW_ARM_R3: _msContext.R3 = value; break; + case UNW_ARM_R4: _msContext.R4 = value; break; + case UNW_ARM_R5: _msContext.R5 = value; break; + case UNW_ARM_R6: _msContext.R6 = value; break; + case UNW_ARM_R7: _msContext.R7 = value; break; + case UNW_ARM_R8: _msContext.R8 = value; break; + case UNW_ARM_R9: _msContext.R9 = value; break; + case UNW_ARM_R10: _msContext.R10 = value; break; + case UNW_ARM_R11: _msContext.R11 = value; break; + case UNW_ARM_R12: _msContext.R12 = value; break; + case UNW_REG_SP: + case UNW_ARM_SP: _msContext.Sp = value; break; + case UNW_ARM_LR: _msContext.Lr = value; break; + case UNW_REG_IP: + case UNW_ARM_IP: _msContext.Pc = value; break; +#elif defined(_LIBUNWIND_TARGET_AARCH64) + case UNW_REG_SP: _msContext.Sp = value; break; + case UNW_REG_IP: _msContext.Pc = value; break; case UNW_AARCH64_X0: case UNW_AARCH64_X1: case UNW_AARCH64_X2: @@ -789,101 +789,101 @@ void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { case UNW_AARCH64_X28: case UNW_AARCH64_FP: case UNW_AARCH64_LR: _msContext.X[regNum - UNW_ARM64_X0] = value; break; -#endif - default: - _LIBUNWIND_ABORT("unsupported register"); - } -} - -template <typename A, typename R> -bool UnwindCursor<A, R>::validFloatReg(int regNum) { -#if defined(_LIBUNWIND_TARGET_ARM) - if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true; - if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true; -#elif defined(_LIBUNWIND_TARGET_AARCH64) +#endif + default: + _LIBUNWIND_ABORT("unsupported register"); + } +} + +template <typename A, typename R> +bool UnwindCursor<A, R>::validFloatReg(int regNum) { +#if defined(_LIBUNWIND_TARGET_ARM) + if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true; + if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true; +#elif defined(_LIBUNWIND_TARGET_AARCH64) if (regNum >= UNW_AARCH64_V0 && regNum <= UNW_ARM64_D31) return true; -#else - (void)regNum; -#endif - return false; -} - -template <typename A, typename R> -unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { -#if defined(_LIBUNWIND_TARGET_ARM) - if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { - union { - uint32_t w; - float f; - } d; - d.w = _msContext.S[regNum - UNW_ARM_S0]; - return d.f; - } - if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) { - union { - uint64_t w; - double d; - } d; - d.w = _msContext.D[regNum - UNW_ARM_D0]; - return d.d; - } - _LIBUNWIND_ABORT("unsupported float register"); -#elif defined(_LIBUNWIND_TARGET_AARCH64) +#else + (void)regNum; +#endif + return false; +} + +template <typename A, typename R> +unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { +#if defined(_LIBUNWIND_TARGET_ARM) + if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { + union { + uint32_t w; + float f; + } d; + d.w = _msContext.S[regNum - UNW_ARM_S0]; + return d.f; + } + if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) { + union { + uint64_t w; + double d; + } d; + d.w = _msContext.D[regNum - UNW_ARM_D0]; + return d.d; + } + _LIBUNWIND_ABORT("unsupported float register"); +#elif defined(_LIBUNWIND_TARGET_AARCH64) return _msContext.V[regNum - UNW_AARCH64_V0].D[0]; -#else - (void)regNum; - _LIBUNWIND_ABORT("float registers unimplemented"); -#endif -} - -template <typename A, typename R> -void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { -#if defined(_LIBUNWIND_TARGET_ARM) - if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { - union { - uint32_t w; - float f; - } d; - d.f = value; - _msContext.S[regNum - UNW_ARM_S0] = d.w; - } - if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) { - union { - uint64_t w; - double d; - } d; - d.d = value; - _msContext.D[regNum - UNW_ARM_D0] = d.w; - } - _LIBUNWIND_ABORT("unsupported float register"); -#elif defined(_LIBUNWIND_TARGET_AARCH64) +#else + (void)regNum; + _LIBUNWIND_ABORT("float registers unimplemented"); +#endif +} + +template <typename A, typename R> +void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { +#if defined(_LIBUNWIND_TARGET_ARM) + if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { + union { + uint32_t w; + float f; + } d; + d.f = value; + _msContext.S[regNum - UNW_ARM_S0] = d.w; + } + if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) { + union { + uint64_t w; + double d; + } d; + d.d = value; + _msContext.D[regNum - UNW_ARM_D0] = d.w; + } + _LIBUNWIND_ABORT("unsupported float register"); +#elif defined(_LIBUNWIND_TARGET_AARCH64) _msContext.V[regNum - UNW_AARCH64_V0].D[0] = value; -#else - (void)regNum; - (void)value; - _LIBUNWIND_ABORT("float registers unimplemented"); -#endif -} - -template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { - RtlRestoreContext(&_msContext, nullptr); -} - -#ifdef __arm__ -template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {} -#endif - -template <typename A, typename R> -const char *UnwindCursor<A, R>::getRegisterName(int regNum) { - return R::getRegisterName(regNum); -} - -template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { - return false; -} - -#else // !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) || !defined(_WIN32) - +#else + (void)regNum; + (void)value; + _LIBUNWIND_ABORT("float registers unimplemented"); +#endif +} + +template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { + RtlRestoreContext(&_msContext, nullptr); +} + +#ifdef __arm__ +template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {} +#endif + +template <typename A, typename R> +const char *UnwindCursor<A, R>::getRegisterName(int regNum) { + return R::getRegisterName(regNum); +} + +template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { + return false; +} + +#else // !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) || !defined(_WIN32) + /// UnwindCursor contains all state (including all register values) during /// an unwind. This is normally stack allocated inside a unw_cursor_t. template <typename A, typename R> @@ -913,13 +913,13 @@ public: #if defined(_LIBUNWIND_USE_CET) virtual void *get_registers() { return &_registers; } #endif - // libunwind does not and should not depend on C++ library which means that we - // need our own defition of inline placement new. - static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } - + // libunwind does not and should not depend on C++ library which means that we + // need our own defition of inline placement new. + static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } + private: -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); int stepWithEHABI() { @@ -956,25 +956,25 @@ private: } #endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo, - const typename CFI_Parser<A>::CIE_Info &cieInfo, - pint_t pc, uintptr_t dso_base); +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo, + const typename CFI_Parser<A>::CIE_Info &cieInfo, + pint_t pc, uintptr_t dso_base); bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint=0); int stepWithDwarfFDE() { return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace, (pint_t)this->getReg(UNW_REG_IP), (pint_t)_info.unwind_info, - _registers, _isSignalFrame); + _registers, _isSignalFrame); } #endif -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) bool getInfoFromCompactEncodingSection(pint_t pc, const UnwindInfoSections §s); int stepWithCompactEncoding() { - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) if ( compactSaysUseDwarf() ) return stepWithDwarfFDE(); #endif @@ -982,72 +982,72 @@ private: return stepWithCompactEncoding(dummy); } -#if defined(_LIBUNWIND_TARGET_X86_64) +#if defined(_LIBUNWIND_TARGET_X86_64) int stepWithCompactEncoding(Registers_x86_64 &) { return CompactUnwinder_x86_64<A>::stepWithCompactEncoding( _info.format, _info.start_ip, _addressSpace, _registers); } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_I386) +#if defined(_LIBUNWIND_TARGET_I386) int stepWithCompactEncoding(Registers_x86 &) { return CompactUnwinder_x86<A>::stepWithCompactEncoding( _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers); } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_PPC) +#if defined(_LIBUNWIND_TARGET_PPC) int stepWithCompactEncoding(Registers_ppc &) { return UNW_EINVAL; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_PPC64) - int stepWithCompactEncoding(Registers_ppc64 &) { - return UNW_EINVAL; - } -#endif - - -#if defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_TARGET_PPC64) + int stepWithCompactEncoding(Registers_ppc64 &) { + return UNW_EINVAL; + } +#endif + + +#if defined(_LIBUNWIND_TARGET_AARCH64) int stepWithCompactEncoding(Registers_arm64 &) { return CompactUnwinder_arm64<A>::stepWithCompactEncoding( _info.format, _info.start_ip, _addressSpace, _registers); } -#endif - -#if defined(_LIBUNWIND_TARGET_MIPS_O32) - int stepWithCompactEncoding(Registers_mips_o32 &) { - return UNW_EINVAL; - } -#endif - -#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) - int stepWithCompactEncoding(Registers_mips_newabi &) { - return UNW_EINVAL; - } -#endif - -#if defined(_LIBUNWIND_TARGET_SPARC) - int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } -#endif - +#endif + +#if defined(_LIBUNWIND_TARGET_MIPS_O32) + int stepWithCompactEncoding(Registers_mips_o32 &) { + return UNW_EINVAL; + } +#endif + +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { + return UNW_EINVAL; + } +#endif + +#if defined(_LIBUNWIND_TARGET_SPARC) + int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC64) int stepWithCompactEncoding(Registers_sparc64 &) { return UNW_EINVAL; } #endif -#if defined (_LIBUNWIND_TARGET_RISCV) - int stepWithCompactEncoding(Registers_riscv &) { - return UNW_EINVAL; - } -#endif - +#if defined (_LIBUNWIND_TARGET_RISCV) + int stepWithCompactEncoding(Registers_riscv &) { + return UNW_EINVAL; + } +#endif + bool compactSaysUseDwarf(uint32_t *offset=NULL) const { R dummy; return compactSaysUseDwarf(dummy, offset); } -#if defined(_LIBUNWIND_TARGET_X86_64) +#if defined(_LIBUNWIND_TARGET_X86_64) bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const { if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) { if (offset) @@ -1056,9 +1056,9 @@ private: } return false; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_I386) +#if defined(_LIBUNWIND_TARGET_I386) bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const { if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) { if (offset) @@ -1067,21 +1067,21 @@ private: } return false; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_PPC) +#if defined(_LIBUNWIND_TARGET_PPC) bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const { return true; } -#endif - -#if defined(_LIBUNWIND_TARGET_PPC64) - bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const { - return true; - } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_TARGET_PPC64) + bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const { + return true; + } +#endif + +#if defined(_LIBUNWIND_TARGET_AARCH64) bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const { if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) { if (offset) @@ -1090,137 +1090,137 @@ private: } return false; } -#endif - -#if defined(_LIBUNWIND_TARGET_MIPS_O32) - bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const { - return true; - } -#endif - -#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) - bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { - return true; - } -#endif - -#if defined(_LIBUNWIND_TARGET_SPARC) - bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } -#endif - +#endif + +#if defined(_LIBUNWIND_TARGET_MIPS_O32) + bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const { + return true; + } +#endif + +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { + return true; + } +#endif + +#if defined(_LIBUNWIND_TARGET_SPARC) + bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC64) bool compactSaysUseDwarf(Registers_sparc64 &, uint32_t *) const { return true; } #endif -#if defined (_LIBUNWIND_TARGET_RISCV) - bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const { - return true; - } -#endif - -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#if defined (_LIBUNWIND_TARGET_RISCV) + bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const { + return true; + } +#endif + +#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) + +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) compact_unwind_encoding_t dwarfEncoding() const { R dummy; return dwarfEncoding(dummy); } -#if defined(_LIBUNWIND_TARGET_X86_64) +#if defined(_LIBUNWIND_TARGET_X86_64) compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const { return UNWIND_X86_64_MODE_DWARF; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_I386) +#if defined(_LIBUNWIND_TARGET_I386) compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const { return UNWIND_X86_MODE_DWARF; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_PPC) +#if defined(_LIBUNWIND_TARGET_PPC) compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const { return 0; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_PPC64) - compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const { - return 0; - } -#endif - -#if defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_TARGET_PPC64) + compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const { + return 0; + } +#endif + +#if defined(_LIBUNWIND_TARGET_AARCH64) compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const { return UNWIND_ARM64_MODE_DWARF; } -#endif +#endif -#if defined(_LIBUNWIND_TARGET_ARM) - compact_unwind_encoding_t dwarfEncoding(Registers_arm &) const { - return 0; - } -#endif - -#if defined (_LIBUNWIND_TARGET_OR1K) +#if defined(_LIBUNWIND_TARGET_ARM) + compact_unwind_encoding_t dwarfEncoding(Registers_arm &) const { + return 0; + } +#endif + +#if defined (_LIBUNWIND_TARGET_OR1K) compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const { return 0; } -#endif - -#if defined (_LIBUNWIND_TARGET_HEXAGON) - compact_unwind_encoding_t dwarfEncoding(Registers_hexagon &) const { - return 0; - } -#endif - -#if defined (_LIBUNWIND_TARGET_MIPS_O32) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const { - return 0; - } -#endif - -#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { - return 0; - } -#endif - -#if defined(_LIBUNWIND_TARGET_SPARC) - compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } -#endif - +#endif + +#if defined (_LIBUNWIND_TARGET_HEXAGON) + compact_unwind_encoding_t dwarfEncoding(Registers_hexagon &) const { + return 0; + } +#endif + +#if defined (_LIBUNWIND_TARGET_MIPS_O32) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const { + return 0; + } +#endif + +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { + return 0; + } +#endif + +#if defined(_LIBUNWIND_TARGET_SPARC) + compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC64) compact_unwind_encoding_t dwarfEncoding(Registers_sparc64 &) const { return 0; } #endif -#if defined (_LIBUNWIND_TARGET_RISCV) - compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const { - return 0; - } -#endif - -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) - // For runtime environments using SEH unwind data without Windows runtime - // support. - pint_t getLastPC() const { /* FIXME: Implement */ return 0; } - void setLastPC(pint_t pc) { /* FIXME: Implement */ } - RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) { - /* FIXME: Implement */ - *base = 0; - return nullptr; - } - bool getInfoFromSEH(pint_t pc); - int stepWithSEHData() { /* FIXME: Implement */ return 0; } -#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) - - +#if defined (_LIBUNWIND_TARGET_RISCV) + compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const { + return 0; + } +#endif + +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + // For runtime environments using SEH unwind data without Windows runtime + // support. + pint_t getLastPC() const { /* FIXME: Implement */ return 0; } + void setLastPC(pint_t pc) { /* FIXME: Implement */ } + RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) { + /* FIXME: Implement */ + *base = 0; + return nullptr; + } + bool getInfoFromSEH(pint_t pc); + int stepWithSEHData() { /* FIXME: Implement */ return 0; } +#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + + A &_addressSpace; R _registers; unw_proc_info_t _info; @@ -1236,10 +1236,10 @@ template <typename A, typename R> UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) : _addressSpace(as), _registers(context), _unwindInfoMissing(false), _isSignalFrame(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), + static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), "UnwindCursor<> does not fit in unw_cursor_t"); - static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), - "UnwindCursor<> requires more alignment than unw_cursor_t"); + static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), + "UnwindCursor<> requires more alignment than unw_cursor_t"); memset(&_info, 0, sizeof(_info)); } @@ -1301,9 +1301,9 @@ template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { return _isSignalFrame; } -#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) - -#if defined(_LIBUNWIND_ARM_EHABI) +#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + +#if defined(_LIBUNWIND_ARM_EHABI) template<typename A> struct EHABISectionIterator { typedef EHABISectionIterator _Self; @@ -1318,8 +1318,8 @@ struct EHABISectionIterator { return _Self(addressSpace, sects, 0); } static _Self end(A& addressSpace, const UnwindInfoSections& sects) { - return _Self(addressSpace, sects, - sects.arm_section_length / sizeof(EHABIIndexEntry)); + return _Self(addressSpace, sects, + sects.arm_section_length / sizeof(EHABIIndexEntry)); } EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i) @@ -1333,7 +1333,7 @@ struct EHABISectionIterator { _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; } _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; } - size_t operator-(const _Self& other) const { return _i - other._i; } + size_t operator-(const _Self& other) const { return _i - other._i; } bool operator==(const _Self& other) const { assert(_addressSpace == other._addressSpace); @@ -1341,12 +1341,12 @@ struct EHABISectionIterator { return _i == other._i; } - bool operator!=(const _Self& other) const { - assert(_addressSpace == other._addressSpace); - assert(_sects == other._sects); - return _i != other._i; - } - + bool operator!=(const _Self& other) const { + assert(_addressSpace == other._addressSpace); + assert(_sects == other._sects); + return _i != other._i; + } + typename A::pint_t operator*() const { return functionAddress(); } typename A::pint_t functionAddress() const { @@ -1367,29 +1367,29 @@ struct EHABISectionIterator { const UnwindInfoSections* _sects; }; -namespace { - -template <typename A> -EHABISectionIterator<A> EHABISectionUpperBound( - EHABISectionIterator<A> first, - EHABISectionIterator<A> last, - typename A::pint_t value) { - size_t len = last - first; - while (len > 0) { - size_t l2 = len / 2; - EHABISectionIterator<A> m = first + l2; - if (value < *m) { - len = l2; - } else { - first = ++m; - len -= l2 + 1; - } - } - return first; -} - -} - +namespace { + +template <typename A> +EHABISectionIterator<A> EHABISectionUpperBound( + EHABISectionIterator<A> first, + EHABISectionIterator<A> last, + typename A::pint_t value) { + size_t len = last - first; + while (len > 0) { + size_t l2 = len / 2; + EHABISectionIterator<A> m = first + l2; + if (value < *m) { + len = l2; + } else { + first = ++m; + len -= l2 + 1; + } + } + return first; +} + +} + template <typename A, typename R> bool UnwindCursor<A, R>::getInfoFromEHABISection( pint_t pc, @@ -1398,20 +1398,20 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( EHABISectionIterator<A>::begin(_addressSpace, sects); EHABISectionIterator<A> end = EHABISectionIterator<A>::end(_addressSpace, sects); - if (begin == end) - return false; + if (begin == end) + return false; - EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc); - if (itNextPC == begin) + EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc); + if (itNextPC == begin) return false; EHABISectionIterator<A> itThisPC = itNextPC - 1; pint_t thisPC = itThisPC.functionAddress(); - // If an exception is thrown from a function, corresponding to the last entry - // in the table, we don't really know the function extent and have to choose a - // value for nextPC. Choosing max() will allow the range check during trace to - // succeed. - pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress(); + // If an exception is thrown from a function, corresponding to the last entry + // in the table, we don't really know the function extent and have to choose a + // value for nextPC. Choosing max() will allow the range check during trace to + // succeed. + pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress(); pint_t indexDataAddr = itThisPC.dataAddress(); if (indexDataAddr == 0) @@ -1423,8 +1423,8 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( // If the high bit is set, the exception handling table entry is inline inside // the index table entry on the second word (aka |indexDataAddr|). Otherwise, - // the table points at an offset in the exception handling table (section 5 - // EHABI). + // the table points at an offset in the exception handling table (section 5 + // EHABI). pint_t exceptionTableAddr; uint32_t exceptionTableData; bool isSingleWordEHT; @@ -1523,40 +1523,40 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( _info.unwind_info = exceptionTableAddr; _info.lsda = lsda; // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0. - _info.flags = (isSingleWordEHT ? 1 : 0) | (scope32 ? 0x2 : 0); // Use enum? + _info.flags = (isSingleWordEHT ? 1 : 0) | (scope32 ? 0x2 : 0); // Use enum? return true; } #endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromFdeCie( - const typename CFI_Parser<A>::FDE_Info &fdeInfo, - const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc, - uintptr_t dso_base) { - typename CFI_Parser<A>::PrologInfo prolog; - if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc, - R::getArch(), &prolog)) { - // Save off parsed FDE info - _info.start_ip = fdeInfo.pcStart; - _info.end_ip = fdeInfo.pcEnd; - _info.lsda = fdeInfo.lsda; - _info.handler = cieInfo.personality; - // Some frameless functions need SP altered when resuming in function, so - // propagate spExtraArgSize. - _info.gp = prolog.spExtraArgSize; - _info.flags = 0; - _info.format = dwarfEncoding(); - _info.unwind_info = fdeInfo.fdeStart; - _info.unwind_info_size = static_cast<uint32_t>(fdeInfo.fdeLength); - _info.extra = static_cast<unw_word_t>(dso_base); - return true; - } - return false; -} - +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) template <typename A, typename R> +bool UnwindCursor<A, R>::getInfoFromFdeCie( + const typename CFI_Parser<A>::FDE_Info &fdeInfo, + const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc, + uintptr_t dso_base) { + typename CFI_Parser<A>::PrologInfo prolog; + if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc, + R::getArch(), &prolog)) { + // Save off parsed FDE info + _info.start_ip = fdeInfo.pcStart; + _info.end_ip = fdeInfo.pcEnd; + _info.lsda = fdeInfo.lsda; + _info.handler = cieInfo.personality; + // Some frameless functions need SP altered when resuming in function, so + // propagate spExtraArgSize. + _info.gp = prolog.spExtraArgSize; + _info.flags = 0; + _info.format = dwarfEncoding(); + _info.unwind_info = fdeInfo.fdeStart; + _info.unwind_info_size = static_cast<uint32_t>(fdeInfo.fdeLength); + _info.extra = static_cast<unw_word_t>(dso_base); + return true; + } + return false; +} + +template <typename A, typename R> bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint) { @@ -1567,11 +1567,11 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, // If compact encoding table gave offset into dwarf section, go directly there if (fdeSectionOffsetHint != 0) { foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - sects.dwarf_section_length, + sects.dwarf_section_length, sects.dwarf_section + fdeSectionOffsetHint, &fdeInfo, &cieInfo); } -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) if (!foundFDE && (sects.dwarf_index_section != 0)) { foundFDE = EHHeaderParser<A>::findFDE( _addressSpace, pc, sects.dwarf_index_section, @@ -1584,7 +1584,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, if (cachedFDE != 0) { foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - sects.dwarf_section_length, + sects.dwarf_section_length, cachedFDE, &fdeInfo, &cieInfo); foundInCache = foundFDE; } @@ -1592,15 +1592,15 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, if (!foundFDE) { // Still not found, do full scan of __eh_frame section. foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - sects.dwarf_section_length, 0, + sects.dwarf_section_length, 0, &fdeInfo, &cieInfo); } if (foundFDE) { - if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) { + if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) { // Add to cache (to make next lookup faster) if we had no hint // and there was no index. if (!foundInCache && (fdeSectionOffsetHint == 0)) { - #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) if (sects.dwarf_index_section == 0) #endif DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd, @@ -1609,13 +1609,13 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, return true; } } - //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc); + //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc); return false; } -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) template <typename A, typename R> bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, const UnwindInfoSections §s) { @@ -1825,20 +1825,20 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, } if (lsda == 0) { _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for " - "pc=0x%0llX, but lsda table has no entry", + "pc=0x%0llX, but lsda table has no entry", encoding, (uint64_t) pc); return false; } } - // extract personality routine, if encoding says function has one + // extract personality routine, if encoding says function has one uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >> (__builtin_ctz(UNWIND_PERSONALITY_MASK)); if (personalityIndex != 0) { --personalityIndex; // change 1-based to zero-based index - if (personalityIndex >= sectionHeader.personalityArrayCount()) { + if (personalityIndex >= sectionHeader.personalityArrayCount()) { _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, " - "but personality table has only %d entries", + "but personality table has only %d entries", encoding, personalityIndex, sectionHeader.personalityArrayCount()); return false; @@ -1871,77 +1871,77 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, _info.extra = sects.dso_base; return true; } -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - - -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) -template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { - pint_t base; - RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base); - if (!unwindEntry) { - _LIBUNWIND_DEBUG_LOG("\tpc not in table, pc=0x%llX", (uint64_t) pc); - return false; - } - _info.gp = 0; - _info.flags = 0; - _info.format = 0; - _info.unwind_info_size = sizeof(RUNTIME_FUNCTION); - _info.unwind_info = reinterpret_cast<unw_word_t>(unwindEntry); - _info.extra = base; - _info.start_ip = base + unwindEntry->BeginAddress; -#ifdef _LIBUNWIND_TARGET_X86_64 - _info.end_ip = base + unwindEntry->EndAddress; - // Only fill in the handler and LSDA if they're stale. - if (pc != getLastPC()) { - UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData); - if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) { - // The personality is given in the UNWIND_INFO itself. The LSDA immediately - // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit - // these structures.) - // N.B. UNWIND_INFO structs are DWORD-aligned. - uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; - const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); - _info.lsda = reinterpret_cast<unw_word_t>(handler+1); - if (*handler) { - _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); - } else - _info.handler = 0; - } else { - _info.lsda = 0; - _info.handler = 0; - } - } -#elif defined(_LIBUNWIND_TARGET_ARM) - _info.end_ip = _info.start_ip + unwindEntry->FunctionLength; - _info.lsda = 0; // FIXME - _info.handler = 0; // FIXME -#endif - setLastPC(pc); - return true; -} -#endif +#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) template <typename A, typename R> +bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { + pint_t base; + RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base); + if (!unwindEntry) { + _LIBUNWIND_DEBUG_LOG("\tpc not in table, pc=0x%llX", (uint64_t) pc); + return false; + } + _info.gp = 0; + _info.flags = 0; + _info.format = 0; + _info.unwind_info_size = sizeof(RUNTIME_FUNCTION); + _info.unwind_info = reinterpret_cast<unw_word_t>(unwindEntry); + _info.extra = base; + _info.start_ip = base + unwindEntry->BeginAddress; +#ifdef _LIBUNWIND_TARGET_X86_64 + _info.end_ip = base + unwindEntry->EndAddress; + // Only fill in the handler and LSDA if they're stale. + if (pc != getLastPC()) { + UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData); + if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) { + // The personality is given in the UNWIND_INFO itself. The LSDA immediately + // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit + // these structures.) + // N.B. UNWIND_INFO structs are DWORD-aligned. + uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; + const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); + _info.lsda = reinterpret_cast<unw_word_t>(handler+1); + if (*handler) { + _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); + } else + _info.handler = 0; + } else { + _info.lsda = 0; + _info.handler = 0; + } + } +#elif defined(_LIBUNWIND_TARGET_ARM) + _info.end_ip = _info.start_ip + unwindEntry->FunctionLength; + _info.lsda = 0; // FIXME + _info.handler = 0; // FIXME +#endif + setLastPC(pc); + return true; +} +#endif + + +template <typename A, typename R> void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64) _isSigReturn = false; #endif pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) // Remove the thumb bit so the IP represents the actual instruction address. // This matches the behaviour of _Unwind_GetIP on arm. pc &= (pint_t)~0x1; #endif - // Exit early if at the top of the stack. - if (pc == 0) { - _unwindInfoMissing = true; - return; - } - + // Exit early if at the top of the stack. + if (pc == 0) { + _unwindInfoMissing = true; + return; + } + // If the last line of a function is a "throw" the compiler sometimes // emits no instructions after the call to __cxa_throw. This means // the return address is actually the start of the next function. @@ -1953,11 +1953,11 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { // Ask address space object to find unwind sections for this pc. UnwindInfoSections sects; if (_addressSpace.findUnwindSections(pc, sects)) { -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) // If there is a compact unwind encoding table, look there first. if (sects.compact_unwind_section != 0) { if (this->getInfoFromCompactEncodingSection(pc, sects)) { - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) // Found info in table, done unless encoding says to use dwarf. uint32_t dwarfOffset; if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) { @@ -1974,15 +1974,15 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { return; } } -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) - // If there is SEH unwind info, look there next. - if (this->getInfoFromSEH(pc)) - return; -#endif - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) + +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + // If there is SEH unwind info, look there next. + if (this->getInfoFromSEH(pc)) + return; +#endif + +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) // If there is dwarf unwind info, look there next. if (sects.dwarf_section != 0) { if (this->getInfoFromDwarfSection(pc, sects)) { @@ -1992,23 +1992,23 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { } #endif -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) // If there is ARM EHABI unwind info, look there next. if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects)) return; #endif } -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) // There is no static unwind info for this pc. Look to see if an FDE was // dynamically registered for it. - pint_t cachedFDE = DwarfFDECache<A>::findFDE(DwarfFDECache<A>::kSearchAll, - pc); + pint_t cachedFDE = DwarfFDECache<A>::findFDE(DwarfFDECache<A>::kSearchAll, + pc); if (cachedFDE != 0) { - typename CFI_Parser<A>::FDE_Info fdeInfo; - typename CFI_Parser<A>::CIE_Info cieInfo; - if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo)) - if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0)) + typename CFI_Parser<A>::FDE_Info fdeInfo; + typename CFI_Parser<A>::CIE_Info cieInfo; + if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo)) + if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0)) return; } @@ -2016,16 +2016,16 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { // other FDEs. pint_t fde; if (_addressSpace.findOtherFDE(pc, fde)) { - typename CFI_Parser<A>::FDE_Info fdeInfo; - typename CFI_Parser<A>::CIE_Info cieInfo; + typename CFI_Parser<A>::FDE_Info fdeInfo; + typename CFI_Parser<A>::CIE_Info cieInfo; if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) { // Double check this FDE is for a function that includes the pc. - if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) - if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0)) + if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) + if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0)) return; } } -#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64) if (setInfoForSigReturn()) @@ -2112,17 +2112,17 @@ int UnwindCursor<A, R>::step() { } else #endif { -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) result = this->stepWithCompactEncoding(); -#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) +#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) result = this->stepWithSEHData(); -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) result = this->stepWithDwarfFDE(); -#elif defined(_LIBUNWIND_ARM_EHABI) +#elif defined(_LIBUNWIND_ARM_EHABI) result = this->stepWithEHABI(); #else #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \ - _LIBUNWIND_SUPPORT_SEH_UNWIND or \ + _LIBUNWIND_SUPPORT_SEH_UNWIND or \ _LIBUNWIND_SUPPORT_DWARF_UNWIND or \ _LIBUNWIND_ARM_EHABI #endif @@ -2140,10 +2140,10 @@ int UnwindCursor<A, R>::step() { template <typename A, typename R> void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) { - if (_unwindInfoMissing) - memset(info, 0, sizeof(*info)); - else - *info = _info; + if (_unwindInfoMissing) + memset(info, 0, sizeof(*info)); + else + *info = _info; } template <typename A, typename R> diff --git a/contrib/libs/libunwind/src/UnwindLevel1-gcc-ext.c b/contrib/libs/libunwind/src/UnwindLevel1-gcc-ext.c index 951d5d219a..8959f8ed66 100644 --- a/contrib/libs/libunwind/src/UnwindLevel1-gcc-ext.c +++ b/contrib/libs/libunwind/src/UnwindLevel1-gcc-ext.c @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Implements gcc extensions to the C++ ABI Exception Handling Level 1. @@ -22,16 +22,16 @@ #include "Unwind-EHABI.h" #include "unwind.h" -#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) +#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) -#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) #define PRIVATE_1 private_[0] #elif defined(_LIBUNWIND_ARM_EHABI) #define PRIVATE_1 unwinder_cache.reserved1 #else #define PRIVATE_1 private_1 -#endif - +#endif + /// Called by __cxa_rethrow(). _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) { @@ -60,7 +60,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) { (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); } @@ -70,7 +70,7 @@ _Unwind_GetDataRelBase(struct _Unwind_Context *context) { _LIBUNWIND_EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) { (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented"); } @@ -78,17 +78,17 @@ _Unwind_GetTextRelBase(struct _Unwind_Context *context) { /// Scans unwind information to find the function that contains the /// specified code address "pc". _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) { - _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc); + _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc); // This is slow, but works. // We create an unwind cursor then alter the IP to be pc unw_cursor_t cursor; unw_context_t uc; unw_proc_info_t info; - __unw_getcontext(&uc); - __unw_init_local(&cursor, &uc); - __unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t)pc); - if (__unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) - return (void *)(intptr_t) info.start_ip; + __unw_getcontext(&uc); + __unw_init_local(&cursor, &uc); + __unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t)pc); + if (__unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) + return (void *)(intptr_t) info.start_ip; else return NULL; } @@ -99,13 +99,13 @@ _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { unw_cursor_t cursor; unw_context_t uc; - __unw_getcontext(&uc); - __unw_init_local(&cursor, &uc); + __unw_getcontext(&uc); + __unw_init_local(&cursor, &uc); - _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)", + _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)", (void *)(uintptr_t)callback); -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) // Create a mock exception object for force unwinding. _Unwind_Exception ex; memset(&ex, '\0', sizeof(ex)); @@ -116,19 +116,19 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { while (true) { _Unwind_Reason_Code result; -#if !defined(_LIBUNWIND_ARM_EHABI) - // ask libunwind to get next frame (skip over first frame which is +#if !defined(_LIBUNWIND_ARM_EHABI) + // ask libunwind to get next frame (skip over first frame which is // _Unwind_Backtrace()) - if (__unw_step(&cursor) <= 0) { + if (__unw_step(&cursor) <= 0) { _LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because cursor reached " - "bottom of stack, returning %d", + "bottom of stack, returning %d", _URC_END_OF_STACK); return _URC_END_OF_STACK; } #else // Get the information for this frame. unw_proc_info_t frameInfo; - if (__unw_get_proc_info(&cursor, &frameInfo) != UNW_ESUCCESS) { + if (__unw_get_proc_info(&cursor, &frameInfo) != UNW_ESUCCESS) { return _URC_END_OF_STACK; } @@ -140,7 +140,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { struct _Unwind_Context *context = (struct _Unwind_Context *)&cursor; // Get and call the personality function to unwind the frame. - _Unwind_Personality_Fn handler = (_Unwind_Personality_Fn)frameInfo.handler; + _Unwind_Personality_Fn handler = (_Unwind_Personality_Fn)frameInfo.handler; if (handler == NULL) { return _URC_END_OF_STACK; } @@ -148,18 +148,18 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { _URC_CONTINUE_UNWIND) { return _URC_END_OF_STACK; } -#endif // defined(_LIBUNWIND_ARM_EHABI) +#endif // defined(_LIBUNWIND_ARM_EHABI) // debugging if (_LIBUNWIND_TRACING_UNWINDING) { char functionName[512]; unw_proc_info_t frame; unw_word_t offset; - __unw_get_proc_name(&cursor, functionName, 512, &offset); - __unw_get_proc_info(&cursor, &frame); + __unw_get_proc_name(&cursor, functionName, 512, &offset); + __unw_get_proc_info(&cursor, &frame); _LIBUNWIND_TRACE_UNWINDING( - " _backtrace: start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", context=%p", - frame.start_ip, functionName, frame.lsda, + " _backtrace: start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", context=%p", + frame.start_ip, functionName, frame.lsda, (void *)&cursor); } @@ -167,14 +167,14 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { result = (*callback)((struct _Unwind_Context *)(&cursor), ref); if (result != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING( - " _backtrace: ended because callback returned %d", result); + " _backtrace: ended because callback returned %d", result); return result; } } } -/// Find DWARF unwind info for an address 'pc' in some function. +/// Find DWARF unwind info for an address 'pc' in some function. _LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *bases) { // This is slow, but works. @@ -182,16 +182,16 @@ _LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc, unw_cursor_t cursor; unw_context_t uc; unw_proc_info_t info; - __unw_getcontext(&uc); - __unw_init_local(&cursor, &uc); - __unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t)pc); - __unw_get_proc_info(&cursor, &info); + __unw_getcontext(&uc); + __unw_init_local(&cursor, &uc); + __unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t)pc); + __unw_get_proc_info(&cursor, &info); bases->tbase = (uintptr_t)info.extra; bases->dbase = 0; // dbase not used on Mac OS X bases->func = (uintptr_t)info.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc, - (void *)(intptr_t) info.unwind_info); - return (void *)(intptr_t) info.unwind_info; + _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc, + (void *)(intptr_t) info.unwind_info); + return (void *)(intptr_t) info.unwind_info; } /// Returns the CFA (call frame area, or stack pointer at start of function) @@ -199,9 +199,9 @@ _LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc, _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; - __unw_get_reg(cursor, UNW_REG_SP, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIxPTR, - (void *)context, result); + __unw_get_reg(cursor, UNW_REG_SP, &result); + _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIxPTR, + (void *)context, result); return (uintptr_t)result; } @@ -211,27 +211,27 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { /// site address. Normally IP is the return address. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, int *ipBefore) { - _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); - int isSignalFrame = __unw_is_signal_frame((unw_cursor_t *)context); - // Negative means some kind of error (probably UNW_ENOINFO), but we have no - // good way to report that, and this maintains backward compatibility with the - // implementation that hard-coded zero in every case, even signal frames. - if (isSignalFrame <= 0) - *ipBefore = 0; - else - *ipBefore = 1; + _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); + int isSignalFrame = __unw_is_signal_frame((unw_cursor_t *)context); + // Negative means some kind of error (probably UNW_ENOINFO), but we have no + // good way to report that, and this maintains backward compatibility with the + // implementation that hard-coded zero in every case, even signal frames. + if (isSignalFrame <= 0) + *ipBefore = 0; + else + *ipBefore = 1; return _Unwind_GetIP(context); } -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) /// Called by programs with dynamic code generators that want /// to register a dynamically generated FDE. /// This function has existed on Mac OS X since 10.4, but /// was broken until 10.6. _LIBUNWIND_EXPORT void __register_frame(const void *fde) { - _LIBUNWIND_TRACE_API("__register_frame(%p)", fde); - __unw_add_dynamic_fde((unw_word_t)(uintptr_t)fde); + _LIBUNWIND_TRACE_API("__register_frame(%p)", fde); + __unw_add_dynamic_fde((unw_word_t)(uintptr_t)fde); } @@ -240,8 +240,8 @@ _LIBUNWIND_EXPORT void __register_frame(const void *fde) { /// This function has existed on Mac OS X since 10.4, but /// was broken until 10.6. _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) { - _LIBUNWIND_TRACE_API("__deregister_frame(%p)", fde); - __unw_remove_dynamic_fde((unw_word_t)(uintptr_t)fde); + _LIBUNWIND_TRACE_API("__deregister_frame(%p)", fde); + __unw_remove_dynamic_fde((unw_word_t)(uintptr_t)fde); } @@ -253,14 +253,14 @@ _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) { // applications working. We also add the not in 10.6 symbol so that nwe // application won't be able to use them. -#if defined(_LIBUNWIND_SUPPORT_FRAME_APIS) +#if defined(_LIBUNWIND_SUPPORT_FRAME_APIS) _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob, void *tb, void *db) { (void)fde; (void)ob; (void)tb; (void)db; - _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)", + _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)", fde, ob, tb, db); // do nothing, this function never worked in Mac OS X } @@ -268,7 +268,7 @@ _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob, _LIBUNWIND_EXPORT void __register_frame_info(const void *fde, void *ob) { (void)fde; (void)ob; - _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)", fde, ob); + _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)", fde, ob); // do nothing, this function never worked in Mac OS X } @@ -280,38 +280,38 @@ _LIBUNWIND_EXPORT void __register_frame_info_table_bases(const void *fde, (void)tb; (void)db; _LIBUNWIND_TRACE_API("__register_frame_info_table_bases" - "(%p,%p, %p, %p)", fde, ob, tb, db); + "(%p,%p, %p, %p)", fde, ob, tb, db); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void __register_frame_info_table(const void *fde, void *ob) { (void)fde; (void)ob; - _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)", fde, ob); + _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)", fde, ob); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void __register_frame_table(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__register_frame_table(%p)", fde); + _LIBUNWIND_TRACE_API("__register_frame_table(%p)", fde); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void *__deregister_frame_info(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)", fde); + _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)", fde); // do nothing, this function never worked in Mac OS X return NULL; } _LIBUNWIND_EXPORT void *__deregister_frame_info_bases(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)", fde); + _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)", fde); // do nothing, this function never worked in Mac OS X return NULL; } -#endif // defined(_LIBUNWIND_SUPPORT_FRAME_APIS) +#endif // defined(_LIBUNWIND_SUPPORT_FRAME_APIS) -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) +#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) diff --git a/contrib/libs/libunwind/src/UnwindLevel1.c b/contrib/libs/libunwind/src/UnwindLevel1.c index 13ca17cc6a..a014ed9f4e 100644 --- a/contrib/libs/libunwind/src/UnwindLevel1.c +++ b/contrib/libs/libunwind/src/UnwindLevel1.c @@ -1,12 +1,12 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Implements C++ ABI Exception Handling Level 1 as documented at: -// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html +// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html // using libunwind // //===----------------------------------------------------------------------===// @@ -26,15 +26,15 @@ #include <string.h> #include "cet_unwind.h" -#include "config.h" +#include "config.h" #include "libunwind.h" -#include "libunwind_ext.h" +#include "libunwind_ext.h" #include "unwind.h" -#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) - -#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND +#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) +#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND + // When CET is enabled, each "call" instruction will push return address to // CET shadow stack, each "ret" instruction will pop current CET shadow stack // top and compare it with target address which program will return. @@ -68,8 +68,8 @@ #endif static _Unwind_Reason_Code -unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { - __unw_init_local(cursor, uc); +unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { + __unw_init_local(cursor, uc); #ifdef _YNDX_LIBUNWIND_ENABLE_EXCEPTION_BACKTRACE _Unwind_Backtrace_Buffer* backtrace_buffer = @@ -81,21 +81,21 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except #endif // Walk each frame looking for a place to stop. - while (true) { - // Ask libunwind to get next frame (skip over first which is + while (true) { + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException). - int stepResult = __unw_step(cursor); + int stepResult = __unw_step(cursor); if (stepResult == 0) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_step() reached " - "bottom => _URC_END_OF_STACK", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase1(ex_ojb=%p): __unw_step() reached " + "bottom => _URC_END_OF_STACK", + (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_step failed => " - "_URC_FATAL_PHASE1_ERROR", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase1(ex_ojb=%p): __unw_step failed => " + "_URC_FATAL_PHASE1_ERROR", + (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -110,11 +110,11 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // See if frame has code to run (has personality routine). unw_proc_info_t frameInfo; unw_word_t sp; - if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR", - (void *)exception_object); + if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase1(ex_ojb=%p): __unw_get_proc_info " + "failed => _URC_FATAL_PHASE1_ERROR", + (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -124,15 +124,15 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; unw_word_t pc; - __unw_get_reg(cursor, UNW_REG_IP, &pc); + __unw_get_reg(cursor, UNW_REG_IP, &pc); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR - ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "", + "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR + ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "", (void *)exception_object, pc, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); } @@ -141,28 +141,28 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // If there is a personality routine, ask it if it will want to stop at // this frame. if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = - (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler); + _Unwind_Personality_Fn p = + (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): calling personality function %p", + "unwind_phase1(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class, - exception_object, (struct _Unwind_Context *)(cursor)); + exception_object, (struct _Unwind_Context *)(cursor)); switch (personalityResult) { case _URC_HANDLER_FOUND: // found a catch clause or locals that need destructing in this frame // stop search and remember stack pointer at the frame - __unw_get_reg(cursor, UNW_REG_SP, &sp); + __unw_get_reg(cursor, UNW_REG_SP, &sp); exception_object->private_2 = (uintptr_t)sp; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", + "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", (void *)exception_object); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); // continue unwinding break; @@ -170,7 +170,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -181,10 +181,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except static _Unwind_Reason_Code -unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { - __unw_init_local(cursor, uc); +unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { + __unw_init_local(cursor, uc); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", (void *)exception_object); // uc is initialized by __unw_getcontext in the parent frame. The first stack @@ -193,32 +193,32 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // Walk each frame until we reach where search phase said to stop. while (true) { - // Ask libunwind to get next frame (skip over first which is + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException). - int stepResult = __unw_step(cursor); + int stepResult = __unw_step(cursor); if (stepResult == 0) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step() reached " - "bottom => _URC_END_OF_STACK", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_step() reached " + "bottom => _URC_END_OF_STACK", + (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step failed => " - "_URC_FATAL_PHASE1_ERROR", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_step failed => " + "_URC_FATAL_PHASE1_ERROR", + (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } // Get info about this frame. unw_word_t sp; unw_proc_info_t frameInfo; - __unw_get_reg(cursor, UNW_REG_SP, &sp); - if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR", - (void *)exception_object); + __unw_get_reg(cursor, UNW_REG_SP, &sp); + if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2(ex_ojb=%p): __unw_get_proc_info " + "failed => _URC_FATAL_PHASE1_ERROR", + (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -228,13 +228,13 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR - ", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR - ", personality=0x%" PRIxPTR, + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR + ", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR + ", personality=0x%" PRIxPTR, (void *)exception_object, frameInfo.start_ip, functionName, sp, frameInfo.lsda, frameInfo.handler); @@ -244,8 +244,8 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except ++framesWalked; // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = - (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler); + _Unwind_Personality_Fn p = + (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler); _Unwind_Action action = _UA_CLEANUP_PHASE; if (sp == exception_object->private_2) { // Tell personality this was the frame it marked in phase 1. @@ -253,12 +253,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except } _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(cursor)); + (struct _Unwind_Context *)(cursor)); switch (personalityResult) { case _URC_CONTINUE_UNWIND: // Continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); if (sp == exception_object->private_2) { // Phase 1 said we would stop at this frame, but we did not... @@ -268,17 +268,17 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", + "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", (void *)exception_object); // Personality routine says to transfer control to landing pad. // We may get control back if landing pad calls _Unwind_Resume(). if (_LIBUNWIND_TRACING_UNWINDING) { unw_word_t pc; - __unw_get_reg(cursor, UNW_REG_IP, &pc); - __unw_get_reg(cursor, UNW_REG_SP, &sp); + __unw_get_reg(cursor, UNW_REG_IP, &pc); + __unw_get_reg(cursor, UNW_REG_SP, &sp); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering " - "user code with ip=0x%" PRIxPTR - ", sp=0x%" PRIxPTR, + "user code with ip=0x%" PRIxPTR + ", sp=0x%" PRIxPTR, (void *)exception_object, pc, sp); } @@ -300,22 +300,22 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except } static _Unwind_Reason_Code -unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, +unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, void *stop_parameter) { - __unw_init_local(cursor, uc); + __unw_init_local(cursor, uc); // uc is initialized by __unw_getcontext in the parent frame. The first stack // frame walked is unwind_phase2_forced. unsigned framesWalked = 1; // Walk each frame until we reach where search phase said to stop - while (__unw_step(cursor) > 0) { + while (__unw_step(cursor) > 0) { // Update info about this frame. unw_proc_info_t frameInfo; - if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " - "failed => _URC_END_OF_STACK", + if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " + "failed => _URC_END_OF_STACK", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -326,13 +326,13 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR - ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, + "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR + ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, (void *)exception_object, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); } @@ -343,13 +343,13 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); _Unwind_Reason_Code stopResult = (*stop)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(cursor), stop_parameter); + (struct _Unwind_Context *)(cursor), stop_parameter); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", + "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", (void *)exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", + "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -357,26 +357,26 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, ++framesWalked; // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { - _Unwind_Personality_Fn p = - (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); + _Unwind_Personality_Fn p = + (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", + "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(cursor)); + (struct _Unwind_Context *)(cursor)); switch (personalityResult) { case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned " - "_URC_CONTINUE_UNWIND", + "_URC_CONTINUE_UNWIND", (void *)exception_object); // Destructors called, continue unwinding break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned " - "_URC_INSTALL_CONTEXT", + "_URC_INSTALL_CONTEXT", (void *)exception_object); // We may get control back if landing pad calls _Unwind_Resume(). __unw_phase2_resume(cursor, framesWalked); @@ -385,7 +385,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // Personality routine returned an unknown result code. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR", + "_URC_FATAL_PHASE2_ERROR", (void *)exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } @@ -395,12 +395,12 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // Call stop function one last time and tell it we've reached the end // of the stack. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " - "function with _UA_END_OF_STACK", + "function with _UA_END_OF_STACK", (void *)exception_object); _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); (*stop)(1, lastAction, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(cursor), stop_parameter); + (struct _Unwind_Context *)(cursor), stop_parameter); // Clean up phase did not resume at the frame that the search phase said it // would. @@ -411,11 +411,11 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, /// Called by __cxa_throw. Only returns if there is a fatal error. _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", (void *)exception_object); unw_context_t uc; - unw_cursor_t cursor; - __unw_getcontext(&uc); + unw_cursor_t cursor; + __unw_getcontext(&uc); // Mark that this is a non-forced unwind, so _Unwind_Resume() // can do the right thing. @@ -423,12 +423,12 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { exception_object->private_2 = 0; // phase 1: the search phase - _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); + _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); if (phase1 != _URC_NO_REASON) return phase1; // phase 2: the clean up phase - return unwind_phase2(&uc, &cursor, exception_object); + return unwind_phase2(&uc, &cursor, exception_object); } @@ -446,17 +446,17 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { /// in turn calls _Unwind_Resume_or_Rethrow(). _LIBUNWIND_EXPORT void _Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); + _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); unw_context_t uc; - unw_cursor_t cursor; - __unw_getcontext(&uc); + unw_cursor_t cursor; + __unw_getcontext(&uc); if (exception_object->private_1 != 0) - unwind_phase2_forced(&uc, &cursor, exception_object, + unwind_phase2_forced(&uc, &cursor, exception_object, (_Unwind_Stop_Fn) exception_object->private_1, (void *)exception_object->private_2); else - unwind_phase2(&uc, &cursor, exception_object); + unwind_phase2(&uc, &cursor, exception_object); // Clients assume _Unwind_Resume() does not return, so all we can do is abort. _LIBUNWIND_ABORT("_Unwind_Resume() can't return"); @@ -470,11 +470,11 @@ _Unwind_Resume(_Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, void *stop_parameter) { - _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", + _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", (void *)exception_object, (void *)(uintptr_t)stop); unw_context_t uc; - unw_cursor_t cursor; - __unw_getcontext(&uc); + unw_cursor_t cursor; + __unw_getcontext(&uc); // Mark that this is a forced unwind, so _Unwind_Resume() can do // the right thing. @@ -482,7 +482,7 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, exception_object->private_2 = (uintptr_t) stop_parameter; // do it - return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter); + return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter); } @@ -492,14 +492,14 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_proc_info_t frameInfo; uintptr_t result = 0; - if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) + if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.lsda; _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR, + "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR, (void *)context, result); if (result != 0) { if (*((uint8_t *)result) != 0xFF) - _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF", + _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF", result); } return result; @@ -513,20 +513,20 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_proc_info_t frameInfo; uintptr_t result = 0; - if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) + if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR, + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR, (void *)context, result); return result; } -#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND +#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND /// Called by personality handler during phase 2 if a foreign exception // is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", (void *)exception_object); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, @@ -538,29 +538,29 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; - __unw_get_reg(cursor, index, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIxPTR, - (void *)context, index, result); + __unw_get_reg(cursor, index, &result); + _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIxPTR, + (void *)context, index, result); return (uintptr_t)result; } /// Called by personality handler during phase 2 to alter register values. _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, uintptr_t value) { - _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIxPTR - ")", - (void *)context, index, value); + _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIxPTR + ")", + (void *)context, index, value); unw_cursor_t *cursor = (unw_cursor_t *)context; - __unw_set_reg(cursor, index, value); + __unw_set_reg(cursor, index, value); } /// Called by personality handler during phase 2 to get instruction pointer. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; - __unw_get_reg(cursor, UNW_REG_IP, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, - (void *)context, result); + __unw_get_reg(cursor, UNW_REG_IP, &result); + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, + (void *)context, result); return (uintptr_t)result; } @@ -569,10 +569,10 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { /// start executing in the landing pad. _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) { - _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")", - (void *)context, value); + _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")", + (void *)context, value); unw_cursor_t *cursor = (unw_cursor_t *)context; - __unw_set_reg(cursor, UNW_REG_IP, value); + __unw_set_reg(cursor, UNW_REG_IP, value); } -#endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) +#endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) diff --git a/contrib/libs/libunwind/src/UnwindRegistersRestore.S b/contrib/libs/libunwind/src/UnwindRegistersRestore.S index 1df97f5fc4..41aaf4c3fc 100644 --- a/contrib/libs/libunwind/src/UnwindRegistersRestore.S +++ b/contrib/libs/libunwind/src/UnwindRegistersRestore.S @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -10,12 +10,12 @@ .text -#if !defined(__USING_SJLJ_EXCEPTIONS__) - +#if !defined(__USING_SJLJ_EXCEPTIONS__) + #if defined(__i386__) -DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto) +DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto) # -# extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *); +# extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *); # # On entry: # + + @@ -58,20 +58,20 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto) #elif defined(__x86_64__) -DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto) +DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto) # -# extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *); +# extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *); # -#if defined(_WIN64) -# On entry, thread_state pointer is in rcx; move it into rdi -# to share restore code below. Since this routine restores and -# overwrites all registers, we can use the same registers for -# pointers and temporaries as on unix even though win64 normally -# mustn't clobber some of them. - movq %rcx, %rdi -#else +#if defined(_WIN64) +# On entry, thread_state pointer is in rcx; move it into rdi +# to share restore code below. Since this routine restores and +# overwrites all registers, we can use the same registers for +# pointers and temporaries as on unix even though win64 normally +# mustn't clobber some of them. + movq %rcx, %rdi +#else # On entry, thread_state pointer is in rdi -#endif +#endif _LIBUNWIND_CET_ENDBR movq 56(%rdi), %rax # rax holds new stack pointer @@ -102,315 +102,315 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto) # skip cs # skip fs # skip gs - -#if defined(_WIN64) - movdqu 176(%rdi),%xmm0 - movdqu 192(%rdi),%xmm1 - movdqu 208(%rdi),%xmm2 - movdqu 224(%rdi),%xmm3 - movdqu 240(%rdi),%xmm4 - movdqu 256(%rdi),%xmm5 - movdqu 272(%rdi),%xmm6 - movdqu 288(%rdi),%xmm7 - movdqu 304(%rdi),%xmm8 - movdqu 320(%rdi),%xmm9 - movdqu 336(%rdi),%xmm10 - movdqu 352(%rdi),%xmm11 - movdqu 368(%rdi),%xmm12 - movdqu 384(%rdi),%xmm13 - movdqu 400(%rdi),%xmm14 - movdqu 416(%rdi),%xmm15 -#endif + +#if defined(_WIN64) + movdqu 176(%rdi),%xmm0 + movdqu 192(%rdi),%xmm1 + movdqu 208(%rdi),%xmm2 + movdqu 224(%rdi),%xmm3 + movdqu 240(%rdi),%xmm4 + movdqu 256(%rdi),%xmm5 + movdqu 272(%rdi),%xmm6 + movdqu 288(%rdi),%xmm7 + movdqu 304(%rdi),%xmm8 + movdqu 320(%rdi),%xmm9 + movdqu 336(%rdi),%xmm10 + movdqu 352(%rdi),%xmm11 + movdqu 368(%rdi),%xmm12 + movdqu 384(%rdi),%xmm13 + movdqu 400(%rdi),%xmm14 + movdqu 416(%rdi),%xmm15 +#endif movq 56(%rdi), %rsp # cut back rsp to new location pop %rdi # rdi was saved here earlier pop %rcx jmpq *%rcx -#elif defined(__powerpc64__) - -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) -// -// void libunwind::Registers_ppc64::jumpto() -// -// On entry: -// thread_state pointer is in r3 -// - -// load register (GPR) -#define PPC64_LR(n) \ +#elif defined(__powerpc64__) + +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) +// +// void libunwind::Registers_ppc64::jumpto() +// +// On entry: +// thread_state pointer is in r3 +// + +// load register (GPR) +#define PPC64_LR(n) \ ld n, (8 * (n + 2))(3) - - // restore integral registers - // skip r0 for now - // skip r1 for now - PPC64_LR(2) - // skip r3 for now - // skip r4 for now - // skip r5 for now - PPC64_LR(6) - PPC64_LR(7) - PPC64_LR(8) - PPC64_LR(9) - PPC64_LR(10) - PPC64_LR(11) - PPC64_LR(12) - PPC64_LR(13) - PPC64_LR(14) - PPC64_LR(15) - PPC64_LR(16) - PPC64_LR(17) - PPC64_LR(18) - PPC64_LR(19) - PPC64_LR(20) - PPC64_LR(21) - PPC64_LR(22) - PPC64_LR(23) - PPC64_LR(24) - PPC64_LR(25) - PPC64_LR(26) - PPC64_LR(27) - PPC64_LR(28) - PPC64_LR(29) - PPC64_LR(30) - PPC64_LR(31) - -#if defined(__VSX__) - - // restore VS registers - // (note that this also restores floating point registers and V registers, - // because part of VS is mapped to these registers) - + + // restore integral registers + // skip r0 for now + // skip r1 for now + PPC64_LR(2) + // skip r3 for now + // skip r4 for now + // skip r5 for now + PPC64_LR(6) + PPC64_LR(7) + PPC64_LR(8) + PPC64_LR(9) + PPC64_LR(10) + PPC64_LR(11) + PPC64_LR(12) + PPC64_LR(13) + PPC64_LR(14) + PPC64_LR(15) + PPC64_LR(16) + PPC64_LR(17) + PPC64_LR(18) + PPC64_LR(19) + PPC64_LR(20) + PPC64_LR(21) + PPC64_LR(22) + PPC64_LR(23) + PPC64_LR(24) + PPC64_LR(25) + PPC64_LR(26) + PPC64_LR(27) + PPC64_LR(28) + PPC64_LR(29) + PPC64_LR(30) + PPC64_LR(31) + +#if defined(__VSX__) + + // restore VS registers + // (note that this also restores floating point registers and V registers, + // because part of VS is mapped to these registers) + addi 4, 3, PPC64_OFFS_FP - -// load VS register -#define PPC64_LVS(n) \ + +// load VS register +#define PPC64_LVS(n) \ lxvd2x n, 0, 4 ;\ addi 4, 4, 16 - - // restore the first 32 VS regs (and also all floating point regs) - PPC64_LVS(0) - PPC64_LVS(1) - PPC64_LVS(2) - PPC64_LVS(3) - PPC64_LVS(4) - PPC64_LVS(5) - PPC64_LVS(6) - PPC64_LVS(7) - PPC64_LVS(8) - PPC64_LVS(9) - PPC64_LVS(10) - PPC64_LVS(11) - PPC64_LVS(12) - PPC64_LVS(13) - PPC64_LVS(14) - PPC64_LVS(15) - PPC64_LVS(16) - PPC64_LVS(17) - PPC64_LVS(18) - PPC64_LVS(19) - PPC64_LVS(20) - PPC64_LVS(21) - PPC64_LVS(22) - PPC64_LVS(23) - PPC64_LVS(24) - PPC64_LVS(25) - PPC64_LVS(26) - PPC64_LVS(27) - PPC64_LVS(28) - PPC64_LVS(29) - PPC64_LVS(30) - PPC64_LVS(31) - - // use VRSAVE to conditionally restore the remaining VS regs, - // that are where the V regs are mapped - + + // restore the first 32 VS regs (and also all floating point regs) + PPC64_LVS(0) + PPC64_LVS(1) + PPC64_LVS(2) + PPC64_LVS(3) + PPC64_LVS(4) + PPC64_LVS(5) + PPC64_LVS(6) + PPC64_LVS(7) + PPC64_LVS(8) + PPC64_LVS(9) + PPC64_LVS(10) + PPC64_LVS(11) + PPC64_LVS(12) + PPC64_LVS(13) + PPC64_LVS(14) + PPC64_LVS(15) + PPC64_LVS(16) + PPC64_LVS(17) + PPC64_LVS(18) + PPC64_LVS(19) + PPC64_LVS(20) + PPC64_LVS(21) + PPC64_LVS(22) + PPC64_LVS(23) + PPC64_LVS(24) + PPC64_LVS(25) + PPC64_LVS(26) + PPC64_LVS(27) + PPC64_LVS(28) + PPC64_LVS(29) + PPC64_LVS(30) + PPC64_LVS(31) + + // use VRSAVE to conditionally restore the remaining VS regs, + // that are where the V regs are mapped + ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave cmpwi 5, 0 - beq Lnovec - -// conditionally load VS -#define PPC64_CLVS_BOTTOM(n) \ - beq Ldone##n ;\ + beq Lnovec + +// conditionally load VS +#define PPC64_CLVS_BOTTOM(n) \ + beq Ldone##n ;\ addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ lxvd2x n, 0, 4 ;\ -Ldone##n: - +Ldone##n: + #define PPC64_CLVSl(n) \ andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\ -PPC64_CLVS_BOTTOM(n) - +PPC64_CLVS_BOTTOM(n) + #define PPC64_CLVSh(n) \ andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\ -PPC64_CLVS_BOTTOM(n) - - PPC64_CLVSl(32) - PPC64_CLVSl(33) - PPC64_CLVSl(34) - PPC64_CLVSl(35) - PPC64_CLVSl(36) - PPC64_CLVSl(37) - PPC64_CLVSl(38) - PPC64_CLVSl(39) - PPC64_CLVSl(40) - PPC64_CLVSl(41) - PPC64_CLVSl(42) - PPC64_CLVSl(43) - PPC64_CLVSl(44) - PPC64_CLVSl(45) - PPC64_CLVSl(46) - PPC64_CLVSl(47) - PPC64_CLVSh(48) - PPC64_CLVSh(49) - PPC64_CLVSh(50) - PPC64_CLVSh(51) - PPC64_CLVSh(52) - PPC64_CLVSh(53) - PPC64_CLVSh(54) - PPC64_CLVSh(55) - PPC64_CLVSh(56) - PPC64_CLVSh(57) - PPC64_CLVSh(58) - PPC64_CLVSh(59) - PPC64_CLVSh(60) - PPC64_CLVSh(61) - PPC64_CLVSh(62) - PPC64_CLVSh(63) - -#else - -// load FP register -#define PPC64_LF(n) \ +PPC64_CLVS_BOTTOM(n) + + PPC64_CLVSl(32) + PPC64_CLVSl(33) + PPC64_CLVSl(34) + PPC64_CLVSl(35) + PPC64_CLVSl(36) + PPC64_CLVSl(37) + PPC64_CLVSl(38) + PPC64_CLVSl(39) + PPC64_CLVSl(40) + PPC64_CLVSl(41) + PPC64_CLVSl(42) + PPC64_CLVSl(43) + PPC64_CLVSl(44) + PPC64_CLVSl(45) + PPC64_CLVSl(46) + PPC64_CLVSl(47) + PPC64_CLVSh(48) + PPC64_CLVSh(49) + PPC64_CLVSh(50) + PPC64_CLVSh(51) + PPC64_CLVSh(52) + PPC64_CLVSh(53) + PPC64_CLVSh(54) + PPC64_CLVSh(55) + PPC64_CLVSh(56) + PPC64_CLVSh(57) + PPC64_CLVSh(58) + PPC64_CLVSh(59) + PPC64_CLVSh(60) + PPC64_CLVSh(61) + PPC64_CLVSh(62) + PPC64_CLVSh(63) + +#else + +// load FP register +#define PPC64_LF(n) \ lfd n, (PPC64_OFFS_FP + n * 16)(3) - - // restore float registers - PPC64_LF(0) - PPC64_LF(1) - PPC64_LF(2) - PPC64_LF(3) - PPC64_LF(4) - PPC64_LF(5) - PPC64_LF(6) - PPC64_LF(7) - PPC64_LF(8) - PPC64_LF(9) - PPC64_LF(10) - PPC64_LF(11) - PPC64_LF(12) - PPC64_LF(13) - PPC64_LF(14) - PPC64_LF(15) - PPC64_LF(16) - PPC64_LF(17) - PPC64_LF(18) - PPC64_LF(19) - PPC64_LF(20) - PPC64_LF(21) - PPC64_LF(22) - PPC64_LF(23) - PPC64_LF(24) - PPC64_LF(25) - PPC64_LF(26) - PPC64_LF(27) - PPC64_LF(28) - PPC64_LF(29) - PPC64_LF(30) - PPC64_LF(31) - -#if defined(__ALTIVEC__) - // restore vector registers if any are in use + + // restore float registers + PPC64_LF(0) + PPC64_LF(1) + PPC64_LF(2) + PPC64_LF(3) + PPC64_LF(4) + PPC64_LF(5) + PPC64_LF(6) + PPC64_LF(7) + PPC64_LF(8) + PPC64_LF(9) + PPC64_LF(10) + PPC64_LF(11) + PPC64_LF(12) + PPC64_LF(13) + PPC64_LF(14) + PPC64_LF(15) + PPC64_LF(16) + PPC64_LF(17) + PPC64_LF(18) + PPC64_LF(19) + PPC64_LF(20) + PPC64_LF(21) + PPC64_LF(22) + PPC64_LF(23) + PPC64_LF(24) + PPC64_LF(25) + PPC64_LF(26) + PPC64_LF(27) + PPC64_LF(28) + PPC64_LF(29) + PPC64_LF(30) + PPC64_LF(31) + +#if defined(__ALTIVEC__) + // restore vector registers if any are in use ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave cmpwi 5, 0 - beq Lnovec - + beq Lnovec + subi 4, 1, 16 - // r4 is now a 16-byte aligned pointer into the red zone - // the _vectorScalarRegisters may not be 16-byte aligned - // so copy via red zone temp buffer - -#define PPC64_CLV_UNALIGNED_BOTTOM(n) \ - beq Ldone##n ;\ + // r4 is now a 16-byte aligned pointer into the red zone + // the _vectorScalarRegisters may not be 16-byte aligned + // so copy via red zone temp buffer + +#define PPC64_CLV_UNALIGNED_BOTTOM(n) \ + beq Ldone##n ;\ ld 0, (PPC64_OFFS_V + n * 16)(3) ;\ std 0, 0(4) ;\ ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\ std 0, 8(4) ;\ lvx n, 0, 4 ;\ -Ldone ## n: - +Ldone ## n: + #define PPC64_CLV_UNALIGNEDl(n) \ andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\ -PPC64_CLV_UNALIGNED_BOTTOM(n) - +PPC64_CLV_UNALIGNED_BOTTOM(n) + #define PPC64_CLV_UNALIGNEDh(n) \ andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\ -PPC64_CLV_UNALIGNED_BOTTOM(n) - - PPC64_CLV_UNALIGNEDl(0) - PPC64_CLV_UNALIGNEDl(1) - PPC64_CLV_UNALIGNEDl(2) - PPC64_CLV_UNALIGNEDl(3) - PPC64_CLV_UNALIGNEDl(4) - PPC64_CLV_UNALIGNEDl(5) - PPC64_CLV_UNALIGNEDl(6) - PPC64_CLV_UNALIGNEDl(7) - PPC64_CLV_UNALIGNEDl(8) - PPC64_CLV_UNALIGNEDl(9) - PPC64_CLV_UNALIGNEDl(10) - PPC64_CLV_UNALIGNEDl(11) - PPC64_CLV_UNALIGNEDl(12) - PPC64_CLV_UNALIGNEDl(13) - PPC64_CLV_UNALIGNEDl(14) - PPC64_CLV_UNALIGNEDl(15) - PPC64_CLV_UNALIGNEDh(16) - PPC64_CLV_UNALIGNEDh(17) - PPC64_CLV_UNALIGNEDh(18) - PPC64_CLV_UNALIGNEDh(19) - PPC64_CLV_UNALIGNEDh(20) - PPC64_CLV_UNALIGNEDh(21) - PPC64_CLV_UNALIGNEDh(22) - PPC64_CLV_UNALIGNEDh(23) - PPC64_CLV_UNALIGNEDh(24) - PPC64_CLV_UNALIGNEDh(25) - PPC64_CLV_UNALIGNEDh(26) - PPC64_CLV_UNALIGNEDh(27) - PPC64_CLV_UNALIGNEDh(28) - PPC64_CLV_UNALIGNEDh(29) - PPC64_CLV_UNALIGNEDh(30) - PPC64_CLV_UNALIGNEDh(31) - -#endif -#endif - -Lnovec: +PPC64_CLV_UNALIGNED_BOTTOM(n) + + PPC64_CLV_UNALIGNEDl(0) + PPC64_CLV_UNALIGNEDl(1) + PPC64_CLV_UNALIGNEDl(2) + PPC64_CLV_UNALIGNEDl(3) + PPC64_CLV_UNALIGNEDl(4) + PPC64_CLV_UNALIGNEDl(5) + PPC64_CLV_UNALIGNEDl(6) + PPC64_CLV_UNALIGNEDl(7) + PPC64_CLV_UNALIGNEDl(8) + PPC64_CLV_UNALIGNEDl(9) + PPC64_CLV_UNALIGNEDl(10) + PPC64_CLV_UNALIGNEDl(11) + PPC64_CLV_UNALIGNEDl(12) + PPC64_CLV_UNALIGNEDl(13) + PPC64_CLV_UNALIGNEDl(14) + PPC64_CLV_UNALIGNEDl(15) + PPC64_CLV_UNALIGNEDh(16) + PPC64_CLV_UNALIGNEDh(17) + PPC64_CLV_UNALIGNEDh(18) + PPC64_CLV_UNALIGNEDh(19) + PPC64_CLV_UNALIGNEDh(20) + PPC64_CLV_UNALIGNEDh(21) + PPC64_CLV_UNALIGNEDh(22) + PPC64_CLV_UNALIGNEDh(23) + PPC64_CLV_UNALIGNEDh(24) + PPC64_CLV_UNALIGNEDh(25) + PPC64_CLV_UNALIGNEDh(26) + PPC64_CLV_UNALIGNEDh(27) + PPC64_CLV_UNALIGNEDh(28) + PPC64_CLV_UNALIGNEDh(29) + PPC64_CLV_UNALIGNEDh(30) + PPC64_CLV_UNALIGNEDh(31) + +#endif +#endif + +Lnovec: ld 0, PPC64_OFFS_CR(3) mtcr 0 ld 0, PPC64_OFFS_SRR0(3) mtctr 0 - - PPC64_LR(0) - PPC64_LR(5) - PPC64_LR(4) - PPC64_LR(1) - PPC64_LR(3) - bctr - + + PPC64_LR(0) + PPC64_LR(5) + PPC64_LR(4) + PPC64_LR(1) + PPC64_LR(3) + bctr + #elif defined(__powerpc__) -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) -// -// void libunwind::Registers_ppc::jumpto() -// -// On entry: -// thread_state pointer is in r3 -// - - // restore integral registerrs - // skip r0 for now - // skip r1 for now +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) +// +// void libunwind::Registers_ppc::jumpto() +// +// On entry: +// thread_state pointer is in r3 +// + + // restore integral registerrs + // skip r0 for now + // skip r1 for now lwz 2, 16(3) - // skip r3 for now - // skip r4 for now - // skip r5 for now + // skip r3 for now + // skip r4 for now + // skip r5 for now lwz 6, 32(3) lwz 7, 36(3) lwz 8, 40(3) @@ -438,8 +438,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) lwz 30,128(3) lwz 31,132(3) -#ifndef __NO_FPRS__ - // restore float registers +#ifndef __NO_FPRS__ + // restore float registers lfd 0, 160(3) lfd 1, 168(3) lfd 2, 176(3) @@ -472,23 +472,23 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) lfd 29,392(3) lfd 30,400(3) lfd 31,408(3) -#endif +#endif -#if defined(__ALTIVEC__) - // restore vector registers if any are in use +#if defined(__ALTIVEC__) + // restore vector registers if any are in use lwz 5, 156(3) // test VRsave cmpwi 5, 0 - beq Lnovec + beq Lnovec subi 4, 1, 16 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits - // r4 is now a 16-byte aligned pointer into the red zone - // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer + // r4 is now a 16-byte aligned pointer into the red zone + // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer #define LOAD_VECTOR_UNALIGNEDl(_index) \ andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \ - beq Ldone ## _index SEPARATOR \ + beq Ldone ## _index SEPARATOR \ lwz 0, 424+_index*16(3) SEPARATOR \ stw 0, 0(%r4) SEPARATOR \ lwz 0, 424+_index*16+4(%r3) SEPARATOR \ @@ -498,11 +498,11 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) lwz 0, 424+_index*16+12(%r3) SEPARATOR \ stw 0, 12(%r4) SEPARATOR \ lvx _index, 0, 4 SEPARATOR \ - Ldone ## _index: + Ldone ## _index: #define LOAD_VECTOR_UNALIGNEDh(_index) \ andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \ - beq Ldone ## _index SEPARATOR \ + beq Ldone ## _index SEPARATOR \ lwz 0, 424+_index*16(3) SEPARATOR \ stw 0, 0(4) SEPARATOR \ lwz 0, 424+_index*16+4(3) SEPARATOR \ @@ -512,7 +512,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) lwz 0, 424+_index*16+12(3) SEPARATOR \ stw 0, 12(4) SEPARATOR \ lvx _index, 0, 4 SEPARATOR \ - Ldone ## _index: + Ldone ## _index: LOAD_VECTOR_UNALIGNEDl(0) @@ -547,7 +547,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) LOAD_VECTOR_UNALIGNEDh(29) LOAD_VECTOR_UNALIGNEDh(30) LOAD_VECTOR_UNALIGNEDh(31) -#endif +#endif Lnovec: lwz 0, 136(3) // __cr @@ -563,16 +563,16 @@ Lnovec: lwz 3, 20(3) // do r3 last bctr -#elif defined(__aarch64__) +#elif defined(__aarch64__) // -// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); +// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); // // On entry: // thread_state pointer is in x0 // .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) +DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) // skip restore of x0,x1 for now ldp x2, x3, [x0, #0x010] ldp x4, x5, [x0, #0x020] @@ -581,15 +581,15 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldp x10,x11, [x0, #0x050] ldp x12,x13, [x0, #0x060] ldp x14,x15, [x0, #0x070] - // x16 and x17 were clobbered by the call into the unwinder, so no point in - // restoring them. + // x16 and x17 were clobbered by the call into the unwinder, so no point in + // restoring them. ldp x18,x19, [x0, #0x090] ldp x20,x21, [x0, #0x0A0] ldp x22,x23, [x0, #0x0B0] ldp x24,x25, [x0, #0x0C0] ldp x26,x27, [x0, #0x0D0] - ldp x28,x29, [x0, #0x0E0] - ldr x30, [x0, #0x100] // restore pc into lr + ldp x28,x29, [x0, #0x0E0] + ldr x30, [x0, #0x100] // restore pc into lr ldp d0, d1, [x0, #0x110] ldp d2, d3, [x0, #0x120] @@ -609,21 +609,21 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldr d30, [x0, #0x200] ldr d31, [x0, #0x208] - // Finally, restore sp. This must be done after the the last read from the - // context struct, because it is allocated on the stack, and an exception - // could clobber the de-allocated portion of the stack after sp has been - // restored. - ldr x16, [x0, #0x0F8] + // Finally, restore sp. This must be done after the the last read from the + // context struct, because it is allocated on the stack, and an exception + // could clobber the de-allocated portion of the stack after sp has been + // restored. + ldr x16, [x0, #0x0F8] ldp x0, x1, [x0, #0x000] // restore x0,x1 - mov sp,x16 // restore sp - ret x30 // jump to pc + mov sp,x16 // restore sp + ret x30 // jump to pc #elif defined(__arm__) && !defined(__APPLE__) #if !defined(__ARM_ARCH_ISA_ARM) -#if (__ARM_ARCH_ISA_THUMB == 2) - .syntax unified -#endif +#if (__ARM_ARCH_ISA_THUMB == 2) + .syntax unified +#endif .thumb #endif @@ -634,19 +634,19 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) @ thread_state pointer is in r0 @ .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) -#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 - @ r8-r11: ldm into r1-r4, then mov to r8-r11 - adds r0, #0x20 - ldm r0!, {r1-r4} - subs r0, #0x30 - mov r8, r1 - mov r9, r2 - mov r10, r3 - mov r11, r4 - @ r12 does not need loading, it it the intra-procedure-call scratch register - ldr r2, [r0, #0x34] - ldr r3, [r0, #0x3c] +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) +#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 + @ r8-r11: ldm into r1-r4, then mov to r8-r11 + adds r0, #0x20 + ldm r0!, {r1-r4} + subs r0, #0x30 + mov r8, r1 + mov r9, r2 + mov r10, r3 + mov r11, r4 + @ r12 does not need loading, it it the intra-procedure-call scratch register + ldr r2, [r0, #0x34] + ldr r3, [r0, #0x3c] mov sp, r2 mov lr, r3 @ restore pc into lr ldm r0, {r0-r7} @@ -675,10 +675,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3-d16 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPv) @ VFP and iwMMX instructions are only available when compiling with the flags @ that enable them. We do not want to do that in the library (because we do not @ want the compiler to generate instructions that access those) but this is @@ -696,10 +696,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3-d16 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPv) vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia JMP(lr) @@ -710,15 +710,15 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPv) vldmia r0, {d16-d31} JMP(lr) -#if defined(__ARM_WMMX) - +#if defined(__ARM_WMMX) + @ @ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values) @ @@ -726,10 +726,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) - .arch armv5te -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPv) +#if defined(__ELF__) + .arch armv5te +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPv) ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8 ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8 ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8 @@ -755,21 +755,21 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) - .arch armv5te -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) +#if defined(__ELF__) + .arch armv5te +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4 ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4 ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4 ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4 JMP(lr) -#endif - +#endif + #elif defined(__or1k__) -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # # void libunwind::Registers_or1k::jumpto() # @@ -777,7 +777,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # thread_state pointer is in r3 # - # restore integral registers + # restore integral registers l.lwz r0, 0(r3) l.lwz r1, 4(r3) l.lwz r2, 8(r3) @@ -787,7 +787,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) l.lwz r6, 24(r3) l.lwz r7, 28(r3) l.lwz r8, 32(r3) - # skip r9 + # skip r9 l.lwz r10, 40(r3) l.lwz r11, 44(r3) l.lwz r12, 48(r3) @@ -821,247 +821,247 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) l.jr r9 l.nop -#elif defined(__hexagon__) -# On entry: -# thread_state pointer is in r2 -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv) -# -# void libunwind::Registers_hexagon::jumpto() -# - r8 = memw(r0+#32) - r9 = memw(r0+#36) - r10 = memw(r0+#40) - r11 = memw(r0+#44) - - r12 = memw(r0+#48) - r13 = memw(r0+#52) - r14 = memw(r0+#56) - r15 = memw(r0+#60) - - r16 = memw(r0+#64) - r17 = memw(r0+#68) - r18 = memw(r0+#72) - r19 = memw(r0+#76) - - r20 = memw(r0+#80) - r21 = memw(r0+#84) - r22 = memw(r0+#88) - r23 = memw(r0+#92) - - r24 = memw(r0+#96) - r25 = memw(r0+#100) - r26 = memw(r0+#104) - r27 = memw(r0+#108) - - r28 = memw(r0+#112) - r29 = memw(r0+#116) - r30 = memw(r0+#120) - r31 = memw(r0+#132) - - r1 = memw(r0+#128) - c4 = r1 // Predicate register - r1 = memw(r0+#4) - r0 = memw(r0) - jumpr r31 -#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 - -// -// void libunwind::Registers_mips_o32::jumpto() -// -// On entry: -// thread state pointer is in a0 ($4) -// -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) - .set push - .set noat - .set noreorder - .set nomacro -#ifdef __mips_hard_float -#if __mips_fpr != 64 - ldc1 $f0, (4 * 36 + 8 * 0)($4) - ldc1 $f2, (4 * 36 + 8 * 2)($4) - ldc1 $f4, (4 * 36 + 8 * 4)($4) - ldc1 $f6, (4 * 36 + 8 * 6)($4) - ldc1 $f8, (4 * 36 + 8 * 8)($4) - ldc1 $f10, (4 * 36 + 8 * 10)($4) - ldc1 $f12, (4 * 36 + 8 * 12)($4) - ldc1 $f14, (4 * 36 + 8 * 14)($4) - ldc1 $f16, (4 * 36 + 8 * 16)($4) - ldc1 $f18, (4 * 36 + 8 * 18)($4) - ldc1 $f20, (4 * 36 + 8 * 20)($4) - ldc1 $f22, (4 * 36 + 8 * 22)($4) - ldc1 $f24, (4 * 36 + 8 * 24)($4) - ldc1 $f26, (4 * 36 + 8 * 26)($4) - ldc1 $f28, (4 * 36 + 8 * 28)($4) - ldc1 $f30, (4 * 36 + 8 * 30)($4) -#else - ldc1 $f0, (4 * 36 + 8 * 0)($4) - ldc1 $f1, (4 * 36 + 8 * 1)($4) - ldc1 $f2, (4 * 36 + 8 * 2)($4) - ldc1 $f3, (4 * 36 + 8 * 3)($4) - ldc1 $f4, (4 * 36 + 8 * 4)($4) - ldc1 $f5, (4 * 36 + 8 * 5)($4) - ldc1 $f6, (4 * 36 + 8 * 6)($4) - ldc1 $f7, (4 * 36 + 8 * 7)($4) - ldc1 $f8, (4 * 36 + 8 * 8)($4) - ldc1 $f9, (4 * 36 + 8 * 9)($4) - ldc1 $f10, (4 * 36 + 8 * 10)($4) - ldc1 $f11, (4 * 36 + 8 * 11)($4) - ldc1 $f12, (4 * 36 + 8 * 12)($4) - ldc1 $f13, (4 * 36 + 8 * 13)($4) - ldc1 $f14, (4 * 36 + 8 * 14)($4) - ldc1 $f15, (4 * 36 + 8 * 15)($4) - ldc1 $f16, (4 * 36 + 8 * 16)($4) - ldc1 $f17, (4 * 36 + 8 * 17)($4) - ldc1 $f18, (4 * 36 + 8 * 18)($4) - ldc1 $f19, (4 * 36 + 8 * 19)($4) - ldc1 $f20, (4 * 36 + 8 * 20)($4) - ldc1 $f21, (4 * 36 + 8 * 21)($4) - ldc1 $f22, (4 * 36 + 8 * 22)($4) - ldc1 $f23, (4 * 36 + 8 * 23)($4) - ldc1 $f24, (4 * 36 + 8 * 24)($4) - ldc1 $f25, (4 * 36 + 8 * 25)($4) - ldc1 $f26, (4 * 36 + 8 * 26)($4) - ldc1 $f27, (4 * 36 + 8 * 27)($4) - ldc1 $f28, (4 * 36 + 8 * 28)($4) - ldc1 $f29, (4 * 36 + 8 * 29)($4) - ldc1 $f30, (4 * 36 + 8 * 30)($4) - ldc1 $f31, (4 * 36 + 8 * 31)($4) -#endif -#endif - // restore hi and lo - lw $8, (4 * 33)($4) - mthi $8 - lw $8, (4 * 34)($4) - mtlo $8 - // r0 is zero - lw $1, (4 * 1)($4) - lw $2, (4 * 2)($4) - lw $3, (4 * 3)($4) - // skip a0 for now - lw $5, (4 * 5)($4) - lw $6, (4 * 6)($4) - lw $7, (4 * 7)($4) - lw $8, (4 * 8)($4) - lw $9, (4 * 9)($4) - lw $10, (4 * 10)($4) - lw $11, (4 * 11)($4) - lw $12, (4 * 12)($4) - lw $13, (4 * 13)($4) - lw $14, (4 * 14)($4) - lw $15, (4 * 15)($4) - lw $16, (4 * 16)($4) - lw $17, (4 * 17)($4) - lw $18, (4 * 18)($4) - lw $19, (4 * 19)($4) - lw $20, (4 * 20)($4) - lw $21, (4 * 21)($4) - lw $22, (4 * 22)($4) - lw $23, (4 * 23)($4) - lw $24, (4 * 24)($4) - lw $25, (4 * 25)($4) - lw $26, (4 * 26)($4) - lw $27, (4 * 27)($4) - lw $28, (4 * 28)($4) - lw $29, (4 * 29)($4) - lw $30, (4 * 30)($4) - // load new pc into ra - lw $31, (4 * 32)($4) - // jump to ra, load a0 in the delay slot - jr $31 - lw $4, (4 * 4)($4) - .set pop - -#elif defined(__mips64) - -// -// void libunwind::Registers_mips_newabi::jumpto() -// -// On entry: -// thread state pointer is in a0 ($4) -// -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) - .set push - .set noat - .set noreorder - .set nomacro -#ifdef __mips_hard_float - ldc1 $f0, (8 * 35)($4) - ldc1 $f1, (8 * 36)($4) - ldc1 $f2, (8 * 37)($4) - ldc1 $f3, (8 * 38)($4) - ldc1 $f4, (8 * 39)($4) - ldc1 $f5, (8 * 40)($4) - ldc1 $f6, (8 * 41)($4) - ldc1 $f7, (8 * 42)($4) - ldc1 $f8, (8 * 43)($4) - ldc1 $f9, (8 * 44)($4) - ldc1 $f10, (8 * 45)($4) - ldc1 $f11, (8 * 46)($4) - ldc1 $f12, (8 * 47)($4) - ldc1 $f13, (8 * 48)($4) - ldc1 $f14, (8 * 49)($4) - ldc1 $f15, (8 * 50)($4) - ldc1 $f16, (8 * 51)($4) - ldc1 $f17, (8 * 52)($4) - ldc1 $f18, (8 * 53)($4) - ldc1 $f19, (8 * 54)($4) - ldc1 $f20, (8 * 55)($4) - ldc1 $f21, (8 * 56)($4) - ldc1 $f22, (8 * 57)($4) - ldc1 $f23, (8 * 58)($4) - ldc1 $f24, (8 * 59)($4) - ldc1 $f25, (8 * 60)($4) - ldc1 $f26, (8 * 61)($4) - ldc1 $f27, (8 * 62)($4) - ldc1 $f28, (8 * 63)($4) - ldc1 $f29, (8 * 64)($4) - ldc1 $f30, (8 * 65)($4) - ldc1 $f31, (8 * 66)($4) +#elif defined(__hexagon__) +# On entry: +# thread_state pointer is in r2 +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv) +# +# void libunwind::Registers_hexagon::jumpto() +# + r8 = memw(r0+#32) + r9 = memw(r0+#36) + r10 = memw(r0+#40) + r11 = memw(r0+#44) + + r12 = memw(r0+#48) + r13 = memw(r0+#52) + r14 = memw(r0+#56) + r15 = memw(r0+#60) + + r16 = memw(r0+#64) + r17 = memw(r0+#68) + r18 = memw(r0+#72) + r19 = memw(r0+#76) + + r20 = memw(r0+#80) + r21 = memw(r0+#84) + r22 = memw(r0+#88) + r23 = memw(r0+#92) + + r24 = memw(r0+#96) + r25 = memw(r0+#100) + r26 = memw(r0+#104) + r27 = memw(r0+#108) + + r28 = memw(r0+#112) + r29 = memw(r0+#116) + r30 = memw(r0+#120) + r31 = memw(r0+#132) + + r1 = memw(r0+#128) + c4 = r1 // Predicate register + r1 = memw(r0+#4) + r0 = memw(r0) + jumpr r31 +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 + +// +// void libunwind::Registers_mips_o32::jumpto() +// +// On entry: +// thread state pointer is in a0 ($4) +// +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) + .set push + .set noat + .set noreorder + .set nomacro +#ifdef __mips_hard_float +#if __mips_fpr != 64 + ldc1 $f0, (4 * 36 + 8 * 0)($4) + ldc1 $f2, (4 * 36 + 8 * 2)($4) + ldc1 $f4, (4 * 36 + 8 * 4)($4) + ldc1 $f6, (4 * 36 + 8 * 6)($4) + ldc1 $f8, (4 * 36 + 8 * 8)($4) + ldc1 $f10, (4 * 36 + 8 * 10)($4) + ldc1 $f12, (4 * 36 + 8 * 12)($4) + ldc1 $f14, (4 * 36 + 8 * 14)($4) + ldc1 $f16, (4 * 36 + 8 * 16)($4) + ldc1 $f18, (4 * 36 + 8 * 18)($4) + ldc1 $f20, (4 * 36 + 8 * 20)($4) + ldc1 $f22, (4 * 36 + 8 * 22)($4) + ldc1 $f24, (4 * 36 + 8 * 24)($4) + ldc1 $f26, (4 * 36 + 8 * 26)($4) + ldc1 $f28, (4 * 36 + 8 * 28)($4) + ldc1 $f30, (4 * 36 + 8 * 30)($4) +#else + ldc1 $f0, (4 * 36 + 8 * 0)($4) + ldc1 $f1, (4 * 36 + 8 * 1)($4) + ldc1 $f2, (4 * 36 + 8 * 2)($4) + ldc1 $f3, (4 * 36 + 8 * 3)($4) + ldc1 $f4, (4 * 36 + 8 * 4)($4) + ldc1 $f5, (4 * 36 + 8 * 5)($4) + ldc1 $f6, (4 * 36 + 8 * 6)($4) + ldc1 $f7, (4 * 36 + 8 * 7)($4) + ldc1 $f8, (4 * 36 + 8 * 8)($4) + ldc1 $f9, (4 * 36 + 8 * 9)($4) + ldc1 $f10, (4 * 36 + 8 * 10)($4) + ldc1 $f11, (4 * 36 + 8 * 11)($4) + ldc1 $f12, (4 * 36 + 8 * 12)($4) + ldc1 $f13, (4 * 36 + 8 * 13)($4) + ldc1 $f14, (4 * 36 + 8 * 14)($4) + ldc1 $f15, (4 * 36 + 8 * 15)($4) + ldc1 $f16, (4 * 36 + 8 * 16)($4) + ldc1 $f17, (4 * 36 + 8 * 17)($4) + ldc1 $f18, (4 * 36 + 8 * 18)($4) + ldc1 $f19, (4 * 36 + 8 * 19)($4) + ldc1 $f20, (4 * 36 + 8 * 20)($4) + ldc1 $f21, (4 * 36 + 8 * 21)($4) + ldc1 $f22, (4 * 36 + 8 * 22)($4) + ldc1 $f23, (4 * 36 + 8 * 23)($4) + ldc1 $f24, (4 * 36 + 8 * 24)($4) + ldc1 $f25, (4 * 36 + 8 * 25)($4) + ldc1 $f26, (4 * 36 + 8 * 26)($4) + ldc1 $f27, (4 * 36 + 8 * 27)($4) + ldc1 $f28, (4 * 36 + 8 * 28)($4) + ldc1 $f29, (4 * 36 + 8 * 29)($4) + ldc1 $f30, (4 * 36 + 8 * 30)($4) + ldc1 $f31, (4 * 36 + 8 * 31)($4) #endif - // restore hi and lo - ld $8, (8 * 33)($4) - mthi $8 - ld $8, (8 * 34)($4) - mtlo $8 - // r0 is zero - ld $1, (8 * 1)($4) - ld $2, (8 * 2)($4) - ld $3, (8 * 3)($4) - // skip a0 for now - ld $5, (8 * 5)($4) - ld $6, (8 * 6)($4) - ld $7, (8 * 7)($4) - ld $8, (8 * 8)($4) - ld $9, (8 * 9)($4) - ld $10, (8 * 10)($4) - ld $11, (8 * 11)($4) - ld $12, (8 * 12)($4) - ld $13, (8 * 13)($4) - ld $14, (8 * 14)($4) - ld $15, (8 * 15)($4) - ld $16, (8 * 16)($4) - ld $17, (8 * 17)($4) - ld $18, (8 * 18)($4) - ld $19, (8 * 19)($4) - ld $20, (8 * 20)($4) - ld $21, (8 * 21)($4) - ld $22, (8 * 22)($4) - ld $23, (8 * 23)($4) - ld $24, (8 * 24)($4) - ld $25, (8 * 25)($4) - ld $26, (8 * 26)($4) - ld $27, (8 * 27)($4) - ld $28, (8 * 28)($4) - ld $29, (8 * 29)($4) - ld $30, (8 * 30)($4) - // load new pc into ra - ld $31, (8 * 32)($4) - // jump to ra, load a0 in the delay slot - jr $31 - ld $4, (8 * 4)($4) - .set pop - +#endif + // restore hi and lo + lw $8, (4 * 33)($4) + mthi $8 + lw $8, (4 * 34)($4) + mtlo $8 + // r0 is zero + lw $1, (4 * 1)($4) + lw $2, (4 * 2)($4) + lw $3, (4 * 3)($4) + // skip a0 for now + lw $5, (4 * 5)($4) + lw $6, (4 * 6)($4) + lw $7, (4 * 7)($4) + lw $8, (4 * 8)($4) + lw $9, (4 * 9)($4) + lw $10, (4 * 10)($4) + lw $11, (4 * 11)($4) + lw $12, (4 * 12)($4) + lw $13, (4 * 13)($4) + lw $14, (4 * 14)($4) + lw $15, (4 * 15)($4) + lw $16, (4 * 16)($4) + lw $17, (4 * 17)($4) + lw $18, (4 * 18)($4) + lw $19, (4 * 19)($4) + lw $20, (4 * 20)($4) + lw $21, (4 * 21)($4) + lw $22, (4 * 22)($4) + lw $23, (4 * 23)($4) + lw $24, (4 * 24)($4) + lw $25, (4 * 25)($4) + lw $26, (4 * 26)($4) + lw $27, (4 * 27)($4) + lw $28, (4 * 28)($4) + lw $29, (4 * 29)($4) + lw $30, (4 * 30)($4) + // load new pc into ra + lw $31, (4 * 32)($4) + // jump to ra, load a0 in the delay slot + jr $31 + lw $4, (4 * 4)($4) + .set pop + +#elif defined(__mips64) + +// +// void libunwind::Registers_mips_newabi::jumpto() +// +// On entry: +// thread state pointer is in a0 ($4) +// +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) + .set push + .set noat + .set noreorder + .set nomacro +#ifdef __mips_hard_float + ldc1 $f0, (8 * 35)($4) + ldc1 $f1, (8 * 36)($4) + ldc1 $f2, (8 * 37)($4) + ldc1 $f3, (8 * 38)($4) + ldc1 $f4, (8 * 39)($4) + ldc1 $f5, (8 * 40)($4) + ldc1 $f6, (8 * 41)($4) + ldc1 $f7, (8 * 42)($4) + ldc1 $f8, (8 * 43)($4) + ldc1 $f9, (8 * 44)($4) + ldc1 $f10, (8 * 45)($4) + ldc1 $f11, (8 * 46)($4) + ldc1 $f12, (8 * 47)($4) + ldc1 $f13, (8 * 48)($4) + ldc1 $f14, (8 * 49)($4) + ldc1 $f15, (8 * 50)($4) + ldc1 $f16, (8 * 51)($4) + ldc1 $f17, (8 * 52)($4) + ldc1 $f18, (8 * 53)($4) + ldc1 $f19, (8 * 54)($4) + ldc1 $f20, (8 * 55)($4) + ldc1 $f21, (8 * 56)($4) + ldc1 $f22, (8 * 57)($4) + ldc1 $f23, (8 * 58)($4) + ldc1 $f24, (8 * 59)($4) + ldc1 $f25, (8 * 60)($4) + ldc1 $f26, (8 * 61)($4) + ldc1 $f27, (8 * 62)($4) + ldc1 $f28, (8 * 63)($4) + ldc1 $f29, (8 * 64)($4) + ldc1 $f30, (8 * 65)($4) + ldc1 $f31, (8 * 66)($4) +#endif + // restore hi and lo + ld $8, (8 * 33)($4) + mthi $8 + ld $8, (8 * 34)($4) + mtlo $8 + // r0 is zero + ld $1, (8 * 1)($4) + ld $2, (8 * 2)($4) + ld $3, (8 * 3)($4) + // skip a0 for now + ld $5, (8 * 5)($4) + ld $6, (8 * 6)($4) + ld $7, (8 * 7)($4) + ld $8, (8 * 8)($4) + ld $9, (8 * 9)($4) + ld $10, (8 * 10)($4) + ld $11, (8 * 11)($4) + ld $12, (8 * 12)($4) + ld $13, (8 * 13)($4) + ld $14, (8 * 14)($4) + ld $15, (8 * 15)($4) + ld $16, (8 * 16)($4) + ld $17, (8 * 17)($4) + ld $18, (8 * 18)($4) + ld $19, (8 * 19)($4) + ld $20, (8 * 20)($4) + ld $21, (8 * 21)($4) + ld $22, (8 * 22)($4) + ld $23, (8 * 23)($4) + ld $24, (8 * 24)($4) + ld $25, (8 * 25)($4) + ld $26, (8 * 26)($4) + ld $27, (8 * 27)($4) + ld $28, (8 * 28)($4) + ld $29, (8 * 29)($4) + ld $30, (8 * 30)($4) + // load new pc into ra + ld $31, (8 * 32)($4) + // jump to ra, load a0 in the delay slot + jr $31 + ld $4, (8 * 4)($4) + .set pop + #elif defined(__sparc__) && defined(__arch64__) DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv) @@ -1109,38 +1109,38 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv) jmp %o7 ldx [%o0 + 0x40], %o0 -#elif defined(__sparc__) - -// -// void libunwind::Registers_sparc_o32::jumpto() -// -// On entry: -// thread_state pointer is in o0 -// -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) - ta 3 - ldd [%o0 + 64], %l0 - ldd [%o0 + 72], %l2 - ldd [%o0 + 80], %l4 - ldd [%o0 + 88], %l6 - ldd [%o0 + 96], %i0 - ldd [%o0 + 104], %i2 - ldd [%o0 + 112], %i4 - ldd [%o0 + 120], %i6 - ld [%o0 + 60], %o7 - jmp %o7 - nop - +#elif defined(__sparc__) + +// +// void libunwind::Registers_sparc_o32::jumpto() +// +// On entry: +// thread_state pointer is in o0 +// +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) + ta 3 + ldd [%o0 + 64], %l0 + ldd [%o0 + 72], %l2 + ldd [%o0 + 80], %l4 + ldd [%o0 + 88], %l6 + ldd [%o0 + 96], %i0 + ldd [%o0 + 104], %i2 + ldd [%o0 + 112], %i4 + ldd [%o0 + 120], %i6 + ld [%o0 + 60], %o7 + jmp %o7 + nop + #elif defined(__riscv) - -// -// void libunwind::Registers_riscv::jumpto() -// -// On entry: -// thread_state pointer is in a0 -// - .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) + +// +// void libunwind::Registers_riscv::jumpto() +// +// On entry: +// thread_state pointer is in a0 +// + .p2align 2 +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) # if defined(__riscv_flen) FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0) FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0) @@ -1175,8 +1175,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0) FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0) # endif - - // x0 is zero + + // x0 is zero ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra ILOAD x2, (RISCV_ISIZE * 2)(a0) ILOAD x3, (RISCV_ISIZE * 3)(a0) @@ -1186,7 +1186,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) ILOAD x7, (RISCV_ISIZE * 7)(a0) ILOAD x8, (RISCV_ISIZE * 8)(a0) ILOAD x9, (RISCV_ISIZE * 9)(a0) - // skip a0 for now + // skip a0 for now ILOAD x11, (RISCV_ISIZE * 11)(a0) ILOAD x12, (RISCV_ISIZE * 12)(a0) ILOAD x13, (RISCV_ISIZE * 13)(a0) @@ -1209,12 +1209,12 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) ILOAD x30, (RISCV_ISIZE * 30)(a0) ILOAD x31, (RISCV_ISIZE * 31)(a0) ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0 - - ret // jump to ra - -#endif - -#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ - -NO_EXEC_STACK_DIRECTIVE - + + ret // jump to ra + +#endif + +#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ + +NO_EXEC_STACK_DIRECTIVE + diff --git a/contrib/libs/libunwind/src/UnwindRegistersSave.S b/contrib/libs/libunwind/src/UnwindRegistersSave.S index 9566bb0335..3ad1c3022f 100644 --- a/contrib/libs/libunwind/src/UnwindRegistersSave.S +++ b/contrib/libs/libunwind/src/UnwindRegistersSave.S @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -10,12 +10,12 @@ .text -#if !defined(__USING_SJLJ_EXCEPTIONS__) - +#if !defined(__USING_SJLJ_EXCEPTIONS__) + #if defined(__i386__) # -# extern int __unw_getcontext(unw_context_t* thread_state) +# extern int __unw_getcontext(unw_context_t* thread_state) # # On entry: # + + @@ -26,7 +26,7 @@ # +-----------------------+ <-- SP # + + # -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) _LIBUNWIND_CET_ENDBR push %eax @@ -58,324 +58,324 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #elif defined(__x86_64__) # -# extern int __unw_getcontext(unw_context_t* thread_state) +# extern int __unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in rdi # -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) -#if defined(_WIN64) -#define PTR %rcx -#define TMP %rdx -#else -#define PTR %rdi -#define TMP %rsi -#endif - +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +#if defined(_WIN64) +#define PTR %rcx +#define TMP %rdx +#else +#define PTR %rdi +#define TMP %rsi +#endif + _LIBUNWIND_CET_ENDBR - movq %rax, (PTR) - movq %rbx, 8(PTR) - movq %rcx, 16(PTR) - movq %rdx, 24(PTR) - movq %rdi, 32(PTR) - movq %rsi, 40(PTR) - movq %rbp, 48(PTR) - movq %rsp, 56(PTR) - addq $8, 56(PTR) - movq %r8, 64(PTR) - movq %r9, 72(PTR) - movq %r10, 80(PTR) - movq %r11, 88(PTR) - movq %r12, 96(PTR) - movq %r13,104(PTR) - movq %r14,112(PTR) - movq %r15,120(PTR) - movq (%rsp),TMP - movq TMP,128(PTR) # store return address as rip + movq %rax, (PTR) + movq %rbx, 8(PTR) + movq %rcx, 16(PTR) + movq %rdx, 24(PTR) + movq %rdi, 32(PTR) + movq %rsi, 40(PTR) + movq %rbp, 48(PTR) + movq %rsp, 56(PTR) + addq $8, 56(PTR) + movq %r8, 64(PTR) + movq %r9, 72(PTR) + movq %r10, 80(PTR) + movq %r11, 88(PTR) + movq %r12, 96(PTR) + movq %r13,104(PTR) + movq %r14,112(PTR) + movq %r15,120(PTR) + movq (%rsp),TMP + movq TMP,128(PTR) # store return address as rip # skip rflags # skip cs # skip fs # skip gs - -#if defined(_WIN64) - movdqu %xmm0,176(PTR) - movdqu %xmm1,192(PTR) - movdqu %xmm2,208(PTR) - movdqu %xmm3,224(PTR) - movdqu %xmm4,240(PTR) - movdqu %xmm5,256(PTR) - movdqu %xmm6,272(PTR) - movdqu %xmm7,288(PTR) - movdqu %xmm8,304(PTR) - movdqu %xmm9,320(PTR) - movdqu %xmm10,336(PTR) - movdqu %xmm11,352(PTR) - movdqu %xmm12,368(PTR) - movdqu %xmm13,384(PTR) - movdqu %xmm14,400(PTR) - movdqu %xmm15,416(PTR) -#endif + +#if defined(_WIN64) + movdqu %xmm0,176(PTR) + movdqu %xmm1,192(PTR) + movdqu %xmm2,208(PTR) + movdqu %xmm3,224(PTR) + movdqu %xmm4,240(PTR) + movdqu %xmm5,256(PTR) + movdqu %xmm6,272(PTR) + movdqu %xmm7,288(PTR) + movdqu %xmm8,304(PTR) + movdqu %xmm9,320(PTR) + movdqu %xmm10,336(PTR) + movdqu %xmm11,352(PTR) + movdqu %xmm12,368(PTR) + movdqu %xmm13,384(PTR) + movdqu %xmm14,400(PTR) + movdqu %xmm15,416(PTR) +#endif xorl %eax, %eax # return UNW_ESUCCESS ret -#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 - -# -# extern int __unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in a0 ($4) -# -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - .set push - .set noat - .set noreorder - .set nomacro - sw $1, (4 * 1)($4) - sw $2, (4 * 2)($4) - sw $3, (4 * 3)($4) - sw $4, (4 * 4)($4) - sw $5, (4 * 5)($4) - sw $6, (4 * 6)($4) - sw $7, (4 * 7)($4) - sw $8, (4 * 8)($4) - sw $9, (4 * 9)($4) - sw $10, (4 * 10)($4) - sw $11, (4 * 11)($4) - sw $12, (4 * 12)($4) - sw $13, (4 * 13)($4) - sw $14, (4 * 14)($4) - sw $15, (4 * 15)($4) - sw $16, (4 * 16)($4) - sw $17, (4 * 17)($4) - sw $18, (4 * 18)($4) - sw $19, (4 * 19)($4) - sw $20, (4 * 20)($4) - sw $21, (4 * 21)($4) - sw $22, (4 * 22)($4) - sw $23, (4 * 23)($4) - sw $24, (4 * 24)($4) - sw $25, (4 * 25)($4) - sw $26, (4 * 26)($4) - sw $27, (4 * 27)($4) - sw $28, (4 * 28)($4) - sw $29, (4 * 29)($4) - sw $30, (4 * 30)($4) - sw $31, (4 * 31)($4) - # Store return address to pc - sw $31, (4 * 32)($4) - # hi and lo - mfhi $8 - sw $8, (4 * 33)($4) - mflo $8 - sw $8, (4 * 34)($4) -#ifdef __mips_hard_float -#if __mips_fpr != 64 - sdc1 $f0, (4 * 36 + 8 * 0)($4) - sdc1 $f2, (4 * 36 + 8 * 2)($4) - sdc1 $f4, (4 * 36 + 8 * 4)($4) - sdc1 $f6, (4 * 36 + 8 * 6)($4) - sdc1 $f8, (4 * 36 + 8 * 8)($4) - sdc1 $f10, (4 * 36 + 8 * 10)($4) - sdc1 $f12, (4 * 36 + 8 * 12)($4) - sdc1 $f14, (4 * 36 + 8 * 14)($4) - sdc1 $f16, (4 * 36 + 8 * 16)($4) - sdc1 $f18, (4 * 36 + 8 * 18)($4) - sdc1 $f20, (4 * 36 + 8 * 20)($4) - sdc1 $f22, (4 * 36 + 8 * 22)($4) - sdc1 $f24, (4 * 36 + 8 * 24)($4) - sdc1 $f26, (4 * 36 + 8 * 26)($4) - sdc1 $f28, (4 * 36 + 8 * 28)($4) - sdc1 $f30, (4 * 36 + 8 * 30)($4) -#else - sdc1 $f0, (4 * 36 + 8 * 0)($4) - sdc1 $f1, (4 * 36 + 8 * 1)($4) - sdc1 $f2, (4 * 36 + 8 * 2)($4) - sdc1 $f3, (4 * 36 + 8 * 3)($4) - sdc1 $f4, (4 * 36 + 8 * 4)($4) - sdc1 $f5, (4 * 36 + 8 * 5)($4) - sdc1 $f6, (4 * 36 + 8 * 6)($4) - sdc1 $f7, (4 * 36 + 8 * 7)($4) - sdc1 $f8, (4 * 36 + 8 * 8)($4) - sdc1 $f9, (4 * 36 + 8 * 9)($4) - sdc1 $f10, (4 * 36 + 8 * 10)($4) - sdc1 $f11, (4 * 36 + 8 * 11)($4) - sdc1 $f12, (4 * 36 + 8 * 12)($4) - sdc1 $f13, (4 * 36 + 8 * 13)($4) - sdc1 $f14, (4 * 36 + 8 * 14)($4) - sdc1 $f15, (4 * 36 + 8 * 15)($4) - sdc1 $f16, (4 * 36 + 8 * 16)($4) - sdc1 $f17, (4 * 36 + 8 * 17)($4) - sdc1 $f18, (4 * 36 + 8 * 18)($4) - sdc1 $f19, (4 * 36 + 8 * 19)($4) - sdc1 $f20, (4 * 36 + 8 * 20)($4) - sdc1 $f21, (4 * 36 + 8 * 21)($4) - sdc1 $f22, (4 * 36 + 8 * 22)($4) - sdc1 $f23, (4 * 36 + 8 * 23)($4) - sdc1 $f24, (4 * 36 + 8 * 24)($4) - sdc1 $f25, (4 * 36 + 8 * 25)($4) - sdc1 $f26, (4 * 36 + 8 * 26)($4) - sdc1 $f27, (4 * 36 + 8 * 27)($4) - sdc1 $f28, (4 * 36 + 8 * 28)($4) - sdc1 $f29, (4 * 36 + 8 * 29)($4) - sdc1 $f30, (4 * 36 + 8 * 30)($4) - sdc1 $f31, (4 * 36 + 8 * 31)($4) -#endif -#endif - jr $31 - # return UNW_ESUCCESS - or $2, $0, $0 - .set pop - -#elif defined(__mips64) - -# -# extern int __unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in a0 ($4) -# -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - .set push - .set noat - .set noreorder - .set nomacro - sd $1, (8 * 1)($4) - sd $2, (8 * 2)($4) - sd $3, (8 * 3)($4) - sd $4, (8 * 4)($4) - sd $5, (8 * 5)($4) - sd $6, (8 * 6)($4) - sd $7, (8 * 7)($4) - sd $8, (8 * 8)($4) - sd $9, (8 * 9)($4) - sd $10, (8 * 10)($4) - sd $11, (8 * 11)($4) - sd $12, (8 * 12)($4) - sd $13, (8 * 13)($4) - sd $14, (8 * 14)($4) - sd $15, (8 * 15)($4) - sd $16, (8 * 16)($4) - sd $17, (8 * 17)($4) - sd $18, (8 * 18)($4) - sd $19, (8 * 19)($4) - sd $20, (8 * 20)($4) - sd $21, (8 * 21)($4) - sd $22, (8 * 22)($4) - sd $23, (8 * 23)($4) - sd $24, (8 * 24)($4) - sd $25, (8 * 25)($4) - sd $26, (8 * 26)($4) - sd $27, (8 * 27)($4) - sd $28, (8 * 28)($4) - sd $29, (8 * 29)($4) - sd $30, (8 * 30)($4) - sd $31, (8 * 31)($4) - # Store return address to pc - sd $31, (8 * 32)($4) - # hi and lo - mfhi $8 - sd $8, (8 * 33)($4) - mflo $8 - sd $8, (8 * 34)($4) -#ifdef __mips_hard_float - sdc1 $f0, (8 * 35)($4) - sdc1 $f1, (8 * 36)($4) - sdc1 $f2, (8 * 37)($4) - sdc1 $f3, (8 * 38)($4) - sdc1 $f4, (8 * 39)($4) - sdc1 $f5, (8 * 40)($4) - sdc1 $f6, (8 * 41)($4) - sdc1 $f7, (8 * 42)($4) - sdc1 $f8, (8 * 43)($4) - sdc1 $f9, (8 * 44)($4) - sdc1 $f10, (8 * 45)($4) - sdc1 $f11, (8 * 46)($4) - sdc1 $f12, (8 * 47)($4) - sdc1 $f13, (8 * 48)($4) - sdc1 $f14, (8 * 49)($4) - sdc1 $f15, (8 * 50)($4) - sdc1 $f16, (8 * 51)($4) - sdc1 $f17, (8 * 52)($4) - sdc1 $f18, (8 * 53)($4) - sdc1 $f19, (8 * 54)($4) - sdc1 $f20, (8 * 55)($4) - sdc1 $f21, (8 * 56)($4) - sdc1 $f22, (8 * 57)($4) - sdc1 $f23, (8 * 58)($4) - sdc1 $f24, (8 * 59)($4) - sdc1 $f25, (8 * 60)($4) - sdc1 $f26, (8 * 61)($4) - sdc1 $f27, (8 * 62)($4) - sdc1 $f28, (8 * 63)($4) - sdc1 $f29, (8 * 64)($4) - sdc1 $f30, (8 * 65)($4) - sdc1 $f31, (8 * 66)($4) -#endif - jr $31 - # return UNW_ESUCCESS - or $2, $0, $0 - .set pop - +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in a0 ($4) +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + .set push + .set noat + .set noreorder + .set nomacro + sw $1, (4 * 1)($4) + sw $2, (4 * 2)($4) + sw $3, (4 * 3)($4) + sw $4, (4 * 4)($4) + sw $5, (4 * 5)($4) + sw $6, (4 * 6)($4) + sw $7, (4 * 7)($4) + sw $8, (4 * 8)($4) + sw $9, (4 * 9)($4) + sw $10, (4 * 10)($4) + sw $11, (4 * 11)($4) + sw $12, (4 * 12)($4) + sw $13, (4 * 13)($4) + sw $14, (4 * 14)($4) + sw $15, (4 * 15)($4) + sw $16, (4 * 16)($4) + sw $17, (4 * 17)($4) + sw $18, (4 * 18)($4) + sw $19, (4 * 19)($4) + sw $20, (4 * 20)($4) + sw $21, (4 * 21)($4) + sw $22, (4 * 22)($4) + sw $23, (4 * 23)($4) + sw $24, (4 * 24)($4) + sw $25, (4 * 25)($4) + sw $26, (4 * 26)($4) + sw $27, (4 * 27)($4) + sw $28, (4 * 28)($4) + sw $29, (4 * 29)($4) + sw $30, (4 * 30)($4) + sw $31, (4 * 31)($4) + # Store return address to pc + sw $31, (4 * 32)($4) + # hi and lo + mfhi $8 + sw $8, (4 * 33)($4) + mflo $8 + sw $8, (4 * 34)($4) +#ifdef __mips_hard_float +#if __mips_fpr != 64 + sdc1 $f0, (4 * 36 + 8 * 0)($4) + sdc1 $f2, (4 * 36 + 8 * 2)($4) + sdc1 $f4, (4 * 36 + 8 * 4)($4) + sdc1 $f6, (4 * 36 + 8 * 6)($4) + sdc1 $f8, (4 * 36 + 8 * 8)($4) + sdc1 $f10, (4 * 36 + 8 * 10)($4) + sdc1 $f12, (4 * 36 + 8 * 12)($4) + sdc1 $f14, (4 * 36 + 8 * 14)($4) + sdc1 $f16, (4 * 36 + 8 * 16)($4) + sdc1 $f18, (4 * 36 + 8 * 18)($4) + sdc1 $f20, (4 * 36 + 8 * 20)($4) + sdc1 $f22, (4 * 36 + 8 * 22)($4) + sdc1 $f24, (4 * 36 + 8 * 24)($4) + sdc1 $f26, (4 * 36 + 8 * 26)($4) + sdc1 $f28, (4 * 36 + 8 * 28)($4) + sdc1 $f30, (4 * 36 + 8 * 30)($4) +#else + sdc1 $f0, (4 * 36 + 8 * 0)($4) + sdc1 $f1, (4 * 36 + 8 * 1)($4) + sdc1 $f2, (4 * 36 + 8 * 2)($4) + sdc1 $f3, (4 * 36 + 8 * 3)($4) + sdc1 $f4, (4 * 36 + 8 * 4)($4) + sdc1 $f5, (4 * 36 + 8 * 5)($4) + sdc1 $f6, (4 * 36 + 8 * 6)($4) + sdc1 $f7, (4 * 36 + 8 * 7)($4) + sdc1 $f8, (4 * 36 + 8 * 8)($4) + sdc1 $f9, (4 * 36 + 8 * 9)($4) + sdc1 $f10, (4 * 36 + 8 * 10)($4) + sdc1 $f11, (4 * 36 + 8 * 11)($4) + sdc1 $f12, (4 * 36 + 8 * 12)($4) + sdc1 $f13, (4 * 36 + 8 * 13)($4) + sdc1 $f14, (4 * 36 + 8 * 14)($4) + sdc1 $f15, (4 * 36 + 8 * 15)($4) + sdc1 $f16, (4 * 36 + 8 * 16)($4) + sdc1 $f17, (4 * 36 + 8 * 17)($4) + sdc1 $f18, (4 * 36 + 8 * 18)($4) + sdc1 $f19, (4 * 36 + 8 * 19)($4) + sdc1 $f20, (4 * 36 + 8 * 20)($4) + sdc1 $f21, (4 * 36 + 8 * 21)($4) + sdc1 $f22, (4 * 36 + 8 * 22)($4) + sdc1 $f23, (4 * 36 + 8 * 23)($4) + sdc1 $f24, (4 * 36 + 8 * 24)($4) + sdc1 $f25, (4 * 36 + 8 * 25)($4) + sdc1 $f26, (4 * 36 + 8 * 26)($4) + sdc1 $f27, (4 * 36 + 8 * 27)($4) + sdc1 $f28, (4 * 36 + 8 * 28)($4) + sdc1 $f29, (4 * 36 + 8 * 29)($4) + sdc1 $f30, (4 * 36 + 8 * 30)($4) + sdc1 $f31, (4 * 36 + 8 * 31)($4) +#endif +#endif + jr $31 + # return UNW_ESUCCESS + or $2, $0, $0 + .set pop + +#elif defined(__mips64) + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in a0 ($4) +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + .set push + .set noat + .set noreorder + .set nomacro + sd $1, (8 * 1)($4) + sd $2, (8 * 2)($4) + sd $3, (8 * 3)($4) + sd $4, (8 * 4)($4) + sd $5, (8 * 5)($4) + sd $6, (8 * 6)($4) + sd $7, (8 * 7)($4) + sd $8, (8 * 8)($4) + sd $9, (8 * 9)($4) + sd $10, (8 * 10)($4) + sd $11, (8 * 11)($4) + sd $12, (8 * 12)($4) + sd $13, (8 * 13)($4) + sd $14, (8 * 14)($4) + sd $15, (8 * 15)($4) + sd $16, (8 * 16)($4) + sd $17, (8 * 17)($4) + sd $18, (8 * 18)($4) + sd $19, (8 * 19)($4) + sd $20, (8 * 20)($4) + sd $21, (8 * 21)($4) + sd $22, (8 * 22)($4) + sd $23, (8 * 23)($4) + sd $24, (8 * 24)($4) + sd $25, (8 * 25)($4) + sd $26, (8 * 26)($4) + sd $27, (8 * 27)($4) + sd $28, (8 * 28)($4) + sd $29, (8 * 29)($4) + sd $30, (8 * 30)($4) + sd $31, (8 * 31)($4) + # Store return address to pc + sd $31, (8 * 32)($4) + # hi and lo + mfhi $8 + sd $8, (8 * 33)($4) + mflo $8 + sd $8, (8 * 34)($4) +#ifdef __mips_hard_float + sdc1 $f0, (8 * 35)($4) + sdc1 $f1, (8 * 36)($4) + sdc1 $f2, (8 * 37)($4) + sdc1 $f3, (8 * 38)($4) + sdc1 $f4, (8 * 39)($4) + sdc1 $f5, (8 * 40)($4) + sdc1 $f6, (8 * 41)($4) + sdc1 $f7, (8 * 42)($4) + sdc1 $f8, (8 * 43)($4) + sdc1 $f9, (8 * 44)($4) + sdc1 $f10, (8 * 45)($4) + sdc1 $f11, (8 * 46)($4) + sdc1 $f12, (8 * 47)($4) + sdc1 $f13, (8 * 48)($4) + sdc1 $f14, (8 * 49)($4) + sdc1 $f15, (8 * 50)($4) + sdc1 $f16, (8 * 51)($4) + sdc1 $f17, (8 * 52)($4) + sdc1 $f18, (8 * 53)($4) + sdc1 $f19, (8 * 54)($4) + sdc1 $f20, (8 * 55)($4) + sdc1 $f21, (8 * 56)($4) + sdc1 $f22, (8 * 57)($4) + sdc1 $f23, (8 * 58)($4) + sdc1 $f24, (8 * 59)($4) + sdc1 $f25, (8 * 60)($4) + sdc1 $f26, (8 * 61)($4) + sdc1 $f27, (8 * 62)($4) + sdc1 $f28, (8 * 63)($4) + sdc1 $f29, (8 * 64)($4) + sdc1 $f30, (8 * 65)($4) + sdc1 $f31, (8 * 66)($4) +#endif + jr $31 + # return UNW_ESUCCESS + or $2, $0, $0 + .set pop + # elif defined(__mips__) # -# extern int __unw_getcontext(unw_context_t* thread_state) +# extern int __unw_getcontext(unw_context_t* thread_state) # # Just trap for the time being. -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) teq $0, $0 -#elif defined(__powerpc64__) - -// -// extern int __unw_getcontext(unw_context_t* thread_state) -// -// On entry: -// thread_state pointer is in r3 -// -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - -// store register (GPR) -#define PPC64_STR(n) \ +#elif defined(__powerpc64__) + +// +// extern int __unw_getcontext(unw_context_t* thread_state) +// +// On entry: +// thread_state pointer is in r3 +// +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + +// store register (GPR) +#define PPC64_STR(n) \ std n, (8 * (n + 2))(3) - - // save GPRs - PPC64_STR(0) + + // save GPRs + PPC64_STR(0) mflr 0 std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0 - PPC64_STR(1) - PPC64_STR(2) - PPC64_STR(3) - PPC64_STR(4) - PPC64_STR(5) - PPC64_STR(6) - PPC64_STR(7) - PPC64_STR(8) - PPC64_STR(9) - PPC64_STR(10) - PPC64_STR(11) - PPC64_STR(12) - PPC64_STR(13) - PPC64_STR(14) - PPC64_STR(15) - PPC64_STR(16) - PPC64_STR(17) - PPC64_STR(18) - PPC64_STR(19) - PPC64_STR(20) - PPC64_STR(21) - PPC64_STR(22) - PPC64_STR(23) - PPC64_STR(24) - PPC64_STR(25) - PPC64_STR(26) - PPC64_STR(27) - PPC64_STR(28) - PPC64_STR(29) - PPC64_STR(30) - PPC64_STR(31) - + PPC64_STR(1) + PPC64_STR(2) + PPC64_STR(3) + PPC64_STR(4) + PPC64_STR(5) + PPC64_STR(6) + PPC64_STR(7) + PPC64_STR(8) + PPC64_STR(9) + PPC64_STR(10) + PPC64_STR(11) + PPC64_STR(12) + PPC64_STR(13) + PPC64_STR(14) + PPC64_STR(15) + PPC64_STR(16) + PPC64_STR(17) + PPC64_STR(18) + PPC64_STR(19) + PPC64_STR(20) + PPC64_STR(21) + PPC64_STR(22) + PPC64_STR(23) + PPC64_STR(24) + PPC64_STR(25) + PPC64_STR(26) + PPC64_STR(27) + PPC64_STR(28) + PPC64_STR(29) + PPC64_STR(30) + PPC64_STR(31) + mfcr 0 std 0, PPC64_OFFS_CR(3) mfxer 0 @@ -386,188 +386,188 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) std 0, PPC64_OFFS_CTR(3) mfvrsave 0 std 0, PPC64_OFFS_VRSAVE(3) - -#if defined(__VSX__) - // save VS registers - // (note that this also saves floating point registers and V registers, - // because part of VS is mapped to these registers) - + +#if defined(__VSX__) + // save VS registers + // (note that this also saves floating point registers and V registers, + // because part of VS is mapped to these registers) + addi 4, 3, PPC64_OFFS_FP - -// store VS register -#define PPC64_STVS(n) \ + +// store VS register +#define PPC64_STVS(n) \ stxvd2x n, 0, 4 ;\ addi 4, 4, 16 - - PPC64_STVS(0) - PPC64_STVS(1) - PPC64_STVS(2) - PPC64_STVS(3) - PPC64_STVS(4) - PPC64_STVS(5) - PPC64_STVS(6) - PPC64_STVS(7) - PPC64_STVS(8) - PPC64_STVS(9) - PPC64_STVS(10) - PPC64_STVS(11) - PPC64_STVS(12) - PPC64_STVS(13) - PPC64_STVS(14) - PPC64_STVS(15) - PPC64_STVS(16) - PPC64_STVS(17) - PPC64_STVS(18) - PPC64_STVS(19) - PPC64_STVS(20) - PPC64_STVS(21) - PPC64_STVS(22) - PPC64_STVS(23) - PPC64_STVS(24) - PPC64_STVS(25) - PPC64_STVS(26) - PPC64_STVS(27) - PPC64_STVS(28) - PPC64_STVS(29) - PPC64_STVS(30) - PPC64_STVS(31) - PPC64_STVS(32) - PPC64_STVS(33) - PPC64_STVS(34) - PPC64_STVS(35) - PPC64_STVS(36) - PPC64_STVS(37) - PPC64_STVS(38) - PPC64_STVS(39) - PPC64_STVS(40) - PPC64_STVS(41) - PPC64_STVS(42) - PPC64_STVS(43) - PPC64_STVS(44) - PPC64_STVS(45) - PPC64_STVS(46) - PPC64_STVS(47) - PPC64_STVS(48) - PPC64_STVS(49) - PPC64_STVS(50) - PPC64_STVS(51) - PPC64_STVS(52) - PPC64_STVS(53) - PPC64_STVS(54) - PPC64_STVS(55) - PPC64_STVS(56) - PPC64_STVS(57) - PPC64_STVS(58) - PPC64_STVS(59) - PPC64_STVS(60) - PPC64_STVS(61) - PPC64_STVS(62) - PPC64_STVS(63) - -#else - -// store FP register -#define PPC64_STF(n) \ + + PPC64_STVS(0) + PPC64_STVS(1) + PPC64_STVS(2) + PPC64_STVS(3) + PPC64_STVS(4) + PPC64_STVS(5) + PPC64_STVS(6) + PPC64_STVS(7) + PPC64_STVS(8) + PPC64_STVS(9) + PPC64_STVS(10) + PPC64_STVS(11) + PPC64_STVS(12) + PPC64_STVS(13) + PPC64_STVS(14) + PPC64_STVS(15) + PPC64_STVS(16) + PPC64_STVS(17) + PPC64_STVS(18) + PPC64_STVS(19) + PPC64_STVS(20) + PPC64_STVS(21) + PPC64_STVS(22) + PPC64_STVS(23) + PPC64_STVS(24) + PPC64_STVS(25) + PPC64_STVS(26) + PPC64_STVS(27) + PPC64_STVS(28) + PPC64_STVS(29) + PPC64_STVS(30) + PPC64_STVS(31) + PPC64_STVS(32) + PPC64_STVS(33) + PPC64_STVS(34) + PPC64_STVS(35) + PPC64_STVS(36) + PPC64_STVS(37) + PPC64_STVS(38) + PPC64_STVS(39) + PPC64_STVS(40) + PPC64_STVS(41) + PPC64_STVS(42) + PPC64_STVS(43) + PPC64_STVS(44) + PPC64_STVS(45) + PPC64_STVS(46) + PPC64_STVS(47) + PPC64_STVS(48) + PPC64_STVS(49) + PPC64_STVS(50) + PPC64_STVS(51) + PPC64_STVS(52) + PPC64_STVS(53) + PPC64_STVS(54) + PPC64_STVS(55) + PPC64_STVS(56) + PPC64_STVS(57) + PPC64_STVS(58) + PPC64_STVS(59) + PPC64_STVS(60) + PPC64_STVS(61) + PPC64_STVS(62) + PPC64_STVS(63) + +#else + +// store FP register +#define PPC64_STF(n) \ stfd n, (PPC64_OFFS_FP + n * 16)(3) - - // save float registers - PPC64_STF(0) - PPC64_STF(1) - PPC64_STF(2) - PPC64_STF(3) - PPC64_STF(4) - PPC64_STF(5) - PPC64_STF(6) - PPC64_STF(7) - PPC64_STF(8) - PPC64_STF(9) - PPC64_STF(10) - PPC64_STF(11) - PPC64_STF(12) - PPC64_STF(13) - PPC64_STF(14) - PPC64_STF(15) - PPC64_STF(16) - PPC64_STF(17) - PPC64_STF(18) - PPC64_STF(19) - PPC64_STF(20) - PPC64_STF(21) - PPC64_STF(22) - PPC64_STF(23) - PPC64_STF(24) - PPC64_STF(25) - PPC64_STF(26) - PPC64_STF(27) - PPC64_STF(28) - PPC64_STF(29) - PPC64_STF(30) - PPC64_STF(31) - -#if defined(__ALTIVEC__) - // save vector registers - - // Use 16-bytes below the stack pointer as an - // aligned buffer to save each vector register. - // Note that the stack pointer is always 16-byte aligned. + + // save float registers + PPC64_STF(0) + PPC64_STF(1) + PPC64_STF(2) + PPC64_STF(3) + PPC64_STF(4) + PPC64_STF(5) + PPC64_STF(6) + PPC64_STF(7) + PPC64_STF(8) + PPC64_STF(9) + PPC64_STF(10) + PPC64_STF(11) + PPC64_STF(12) + PPC64_STF(13) + PPC64_STF(14) + PPC64_STF(15) + PPC64_STF(16) + PPC64_STF(17) + PPC64_STF(18) + PPC64_STF(19) + PPC64_STF(20) + PPC64_STF(21) + PPC64_STF(22) + PPC64_STF(23) + PPC64_STF(24) + PPC64_STF(25) + PPC64_STF(26) + PPC64_STF(27) + PPC64_STF(28) + PPC64_STF(29) + PPC64_STF(30) + PPC64_STF(31) + +#if defined(__ALTIVEC__) + // save vector registers + + // Use 16-bytes below the stack pointer as an + // aligned buffer to save each vector register. + // Note that the stack pointer is always 16-byte aligned. subi 4, 1, 16 - + #define PPC64_STV_UNALIGNED(n) \ stvx n, 0, 4 ;\ ld 5, 0(4) ;\ std 5, (PPC64_OFFS_V + n * 16)(3) ;\ ld 5, 8(4) ;\ std 5, (PPC64_OFFS_V + n * 16 + 8)(3) - - PPC64_STV_UNALIGNED(0) - PPC64_STV_UNALIGNED(1) - PPC64_STV_UNALIGNED(2) - PPC64_STV_UNALIGNED(3) - PPC64_STV_UNALIGNED(4) - PPC64_STV_UNALIGNED(5) - PPC64_STV_UNALIGNED(6) - PPC64_STV_UNALIGNED(7) - PPC64_STV_UNALIGNED(8) - PPC64_STV_UNALIGNED(9) - PPC64_STV_UNALIGNED(10) - PPC64_STV_UNALIGNED(11) - PPC64_STV_UNALIGNED(12) - PPC64_STV_UNALIGNED(13) - PPC64_STV_UNALIGNED(14) - PPC64_STV_UNALIGNED(15) - PPC64_STV_UNALIGNED(16) - PPC64_STV_UNALIGNED(17) - PPC64_STV_UNALIGNED(18) - PPC64_STV_UNALIGNED(19) - PPC64_STV_UNALIGNED(20) - PPC64_STV_UNALIGNED(21) - PPC64_STV_UNALIGNED(22) - PPC64_STV_UNALIGNED(23) - PPC64_STV_UNALIGNED(24) - PPC64_STV_UNALIGNED(25) - PPC64_STV_UNALIGNED(26) - PPC64_STV_UNALIGNED(27) - PPC64_STV_UNALIGNED(28) - PPC64_STV_UNALIGNED(29) - PPC64_STV_UNALIGNED(30) - PPC64_STV_UNALIGNED(31) - -#endif -#endif - + + PPC64_STV_UNALIGNED(0) + PPC64_STV_UNALIGNED(1) + PPC64_STV_UNALIGNED(2) + PPC64_STV_UNALIGNED(3) + PPC64_STV_UNALIGNED(4) + PPC64_STV_UNALIGNED(5) + PPC64_STV_UNALIGNED(6) + PPC64_STV_UNALIGNED(7) + PPC64_STV_UNALIGNED(8) + PPC64_STV_UNALIGNED(9) + PPC64_STV_UNALIGNED(10) + PPC64_STV_UNALIGNED(11) + PPC64_STV_UNALIGNED(12) + PPC64_STV_UNALIGNED(13) + PPC64_STV_UNALIGNED(14) + PPC64_STV_UNALIGNED(15) + PPC64_STV_UNALIGNED(16) + PPC64_STV_UNALIGNED(17) + PPC64_STV_UNALIGNED(18) + PPC64_STV_UNALIGNED(19) + PPC64_STV_UNALIGNED(20) + PPC64_STV_UNALIGNED(21) + PPC64_STV_UNALIGNED(22) + PPC64_STV_UNALIGNED(23) + PPC64_STV_UNALIGNED(24) + PPC64_STV_UNALIGNED(25) + PPC64_STV_UNALIGNED(26) + PPC64_STV_UNALIGNED(27) + PPC64_STV_UNALIGNED(28) + PPC64_STV_UNALIGNED(29) + PPC64_STV_UNALIGNED(30) + PPC64_STV_UNALIGNED(31) + +#endif +#endif + li 3, 0 // return UNW_ESUCCESS - blr - - + blr + + #elif defined(__powerpc__) -// -// extern int unw_getcontext(unw_context_t* thread_state) -// -// On entry: -// thread_state pointer is in r3 -// -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +// +// extern int unw_getcontext(unw_context_t* thread_state) +// +// On entry: +// thread_state pointer is in r3 +// +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stw 0, 8(3) mflr 0 stw 0, 0(3) // store lr as ssr0 @@ -603,18 +603,18 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stw 30,128(3) stw 31,132(3) - // save VRSave register + // save VRSave register mfspr 0, 256 stw 0, 156(3) - // save CR registers + // save CR registers mfcr 0 stw 0, 136(3) - // save CTR register + // save CTR register mfctr 0 stw 0, 148(3) -#if !defined(__NO_FPRS__) - // save float registers +#if !defined(__NO_FPRS__) + // save float registers stfd 0, 160(3) stfd 1, 168(3) stfd 2, 176(3) @@ -647,14 +647,14 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stfd 29,392(3) stfd 30,400(3) stfd 31,408(3) -#endif +#endif -#if defined(__ALTIVEC__) - // save vector registers +#if defined(__ALTIVEC__) + // save vector registers subi 4, 1, 16 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits - // r4 is now a 16-byte aligned pointer into the red zone + // r4 is now a 16-byte aligned pointer into the red zone #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ stvx _vec, 0, 4 SEPARATOR \ @@ -699,22 +699,22 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) SAVE_VECTOR_UNALIGNED(29, 424+0x1D0) SAVE_VECTOR_UNALIGNED(30, 424+0x1E0) SAVE_VECTOR_UNALIGNED(31, 424+0x1F0) -#endif +#endif li 3, 0 // return UNW_ESUCCESS blr -#elif defined(__aarch64__) +#elif defined(__aarch64__) // -// extern int __unw_getcontext(unw_context_t* thread_state) +// extern int __unw_getcontext(unw_context_t* thread_state) // // On entry: // thread_state pointer is in x0 // .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stp x0, x1, [x0, #0x000] stp x2, x3, [x0, #0x010] stp x4, x5, [x0, #0x020] @@ -729,11 +729,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stp x22,x23, [x0, #0x0B0] stp x24,x25, [x0, #0x0C0] stp x26,x27, [x0, #0x0D0] - stp x28,x29, [x0, #0x0E0] - str x30, [x0, #0x0F0] + stp x28,x29, [x0, #0x0E0] + str x30, [x0, #0x0F0] mov x1,sp str x1, [x0, #0x0F8] - str x30, [x0, #0x100] // store return address as pc + str x30, [x0, #0x100] // store return address as pc // skip cpsr stp d0, d1, [x0, #0x110] stp d2, d3, [x0, #0x120] @@ -758,14 +758,14 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #elif defined(__arm__) && !defined(__APPLE__) #if !defined(__ARM_ARCH_ISA_ARM) -#if (__ARM_ARCH_ISA_THUMB == 2) - .syntax unified -#endif +#if (__ARM_ARCH_ISA_THUMB == 2) + .syntax unified +#endif .thumb #endif @ -@ extern int __unw_getcontext(unw_context_t* thread_state) +@ extern int __unw_getcontext(unw_context_t* thread_state) @ @ On entry: @ thread_state pointer is in r0 @@ -774,28 +774,28 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) @ EHABI #7.4.5 notes that in general all VRS registers should be restored @ however this is very hard to do for VFP registers because it is unknown @ to the library how many registers are implemented by the architecture. -@ Instead, VFP registers are demand saved by logic external to __unw_getcontext. +@ Instead, VFP registers are demand saved by logic external to __unw_getcontext. @ .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) -#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 - stm r0!, {r0-r7} - mov r1, r8 - mov r2, r9 - mov r3, r10 - stm r0!, {r1-r3} - mov r1, r11 +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 + stm r0!, {r0-r7} + mov r1, r8 + mov r2, r9 + mov r3, r10 + stm r0!, {r1-r3} + mov r1, r11 mov r2, sp mov r3, lr - str r1, [r0, #0] @ r11 - @ r12 does not need storing, it it the intra-procedure-call scratch register - str r2, [r0, #8] @ sp - str r3, [r0, #12] @ lr - str r3, [r0, #16] @ store return address as pc - @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. - @ It is safe to use here though because we are about to return, and cpsr is - @ not expected to be preserved. - movs r0, #0 @ return UNW_ESUCCESS + str r1, [r0, #0] @ r11 + @ r12 does not need storing, it it the intra-procedure-call scratch register + str r2, [r0, #8] @ sp + str r3, [r0, #12] @ lr + str r3, [r0, #16] @ store return address as pc + @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. + @ It is safe to use here though because we are about to return, and cpsr is + @ not expected to be preserved. + movs r0, #0 @ return UNW_ESUCCESS #else @ 32bit thumb-2 restrictions for stm: @ . the sp (r13) cannot be in the list @@ -815,10 +815,10 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3-d16 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) vstmia r0, {d0-d15} JMP(lr) @@ -829,10 +829,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3-d16 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia JMP(lr) @@ -843,10 +843,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) +#if defined(__ELF__) .fpu vfpv3 -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) @ VFP and iwMMX instructions are only available when compiling with the flags @ that enable them. We do not want to do that in the library (because we do not @ want the compiler to generate instructions that access those) but this is @@ -857,8 +857,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) vstmia r0, {d16-d31} JMP(lr) -#if defined(_LIBUNWIND_ARM_WMMX) - +#if defined(_LIBUNWIND_ARM_WMMX) + @ @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) @ @@ -866,10 +866,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) - .arch armv5te -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) +#if defined(__ELF__) + .arch armv5te +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8 stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8 stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8 @@ -895,27 +895,27 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) @ values pointer is in r0 @ .p2align 2 -#if defined(__ELF__) - .arch armv5te -#endif -DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) +#if defined(__ELF__) + .arch armv5te +#endif +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4 stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4 stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4 stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 JMP(lr) -#endif - +#endif + #elif defined(__or1k__) # -# extern int __unw_getcontext(unw_context_t* thread_state) +# extern int __unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in r3 # -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) l.sw 0(r3), r0 l.sw 4(r3), r1 l.sw 8(r3), r2 @@ -948,57 +948,57 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) l.sw 116(r3), r29 l.sw 120(r3), r30 l.sw 124(r3), r31 - # store ra to pc - l.sw 128(r3), r9 - # zero epcr - l.sw 132(r3), r0 - -#elif defined(__hexagon__) -# -# extern int unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in r0 -# -#define OFFSET(offset) (offset/4) -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - memw(r0+#32) = r8 - memw(r0+#36) = r9 - memw(r0+#40) = r10 - memw(r0+#44) = r11 - - memw(r0+#48) = r12 - memw(r0+#52) = r13 - memw(r0+#56) = r14 - memw(r0+#60) = r15 - - memw(r0+#64) = r16 - memw(r0+#68) = r17 - memw(r0+#72) = r18 - memw(r0+#76) = r19 - - memw(r0+#80) = r20 - memw(r0+#84) = r21 - memw(r0+#88) = r22 - memw(r0+#92) = r23 - - memw(r0+#96) = r24 - memw(r0+#100) = r25 - memw(r0+#104) = r26 - memw(r0+#108) = r27 - - memw(r0+#112) = r28 - memw(r0+#116) = r29 - memw(r0+#120) = r30 - memw(r0+#124) = r31 - r1 = c4 // Predicate register - memw(r0+#128) = r1 - r1 = memw(r30) // *FP == Saved FP - r1 = r31 - memw(r0+#132) = r1 - - jumpr r31 - + # store ra to pc + l.sw 128(r3), r9 + # zero epcr + l.sw 132(r3), r0 + +#elif defined(__hexagon__) +# +# extern int unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in r0 +# +#define OFFSET(offset) (offset/4) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + memw(r0+#32) = r8 + memw(r0+#36) = r9 + memw(r0+#40) = r10 + memw(r0+#44) = r11 + + memw(r0+#48) = r12 + memw(r0+#52) = r13 + memw(r0+#56) = r14 + memw(r0+#60) = r15 + + memw(r0+#64) = r16 + memw(r0+#68) = r17 + memw(r0+#72) = r18 + memw(r0+#76) = r19 + + memw(r0+#80) = r20 + memw(r0+#84) = r21 + memw(r0+#88) = r22 + memw(r0+#92) = r23 + + memw(r0+#96) = r24 + memw(r0+#100) = r25 + memw(r0+#104) = r26 + memw(r0+#108) = r27 + + memw(r0+#112) = r28 + memw(r0+#116) = r29 + memw(r0+#120) = r30 + memw(r0+#124) = r31 + r1 = c4 // Predicate register + memw(r0+#128) = r1 + r1 = memw(r30) // *FP == Saved FP + r1 = r31 + memw(r0+#132) = r1 + + jumpr r31 + #elif defined(__sparc__) && defined(__arch64__) # @@ -1057,45 +1057,45 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) # return UNW_ESUCCESS clr %o0 -#elif defined(__sparc__) - -# -# extern int __unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in o0 -# -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - ta 3 - add %o7, 8, %o7 - std %g0, [%o0 + 0] - std %g2, [%o0 + 8] - std %g4, [%o0 + 16] - std %g6, [%o0 + 24] - std %o0, [%o0 + 32] - std %o2, [%o0 + 40] - std %o4, [%o0 + 48] - std %o6, [%o0 + 56] - std %l0, [%o0 + 64] - std %l2, [%o0 + 72] - std %l4, [%o0 + 80] - std %l6, [%o0 + 88] - std %i0, [%o0 + 96] - std %i2, [%o0 + 104] - std %i4, [%o0 + 112] - std %i6, [%o0 + 120] - jmp %o7 - clr %o0 // return UNW_ESUCCESS - +#elif defined(__sparc__) + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in o0 +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + ta 3 + add %o7, 8, %o7 + std %g0, [%o0 + 0] + std %g2, [%o0 + 8] + std %g4, [%o0 + 16] + std %g6, [%o0 + 24] + std %o0, [%o0 + 32] + std %o2, [%o0 + 40] + std %o4, [%o0 + 48] + std %o6, [%o0 + 56] + std %l0, [%o0 + 64] + std %l2, [%o0 + 72] + std %l4, [%o0 + 80] + std %l6, [%o0 + 88] + std %i0, [%o0 + 96] + std %i2, [%o0 + 104] + std %i4, [%o0 + 112] + std %i6, [%o0 + 120] + jmp %o7 + clr %o0 // return UNW_ESUCCESS + #elif defined(__riscv) - -# -# extern int __unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in a0 -# -DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in a0 +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc ISTORE x1, (RISCV_ISIZE * 1)(a0) ISTORE x2, (RISCV_ISIZE * 2)(a0) @@ -1128,7 +1128,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) ISTORE x29, (RISCV_ISIZE * 29)(a0) ISTORE x30, (RISCV_ISIZE * 30)(a0) ISTORE x31, (RISCV_ISIZE * 31)(a0) - + # if defined(__riscv_flen) FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0) FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0) @@ -1163,13 +1163,13 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0) FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0) # endif - - li a0, 0 // return UNW_ESUCCESS - ret // jump to ra -#endif - - WEAK_ALIAS(__unw_getcontext, unw_getcontext) - -#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ - -NO_EXEC_STACK_DIRECTIVE + + li a0, 0 // return UNW_ESUCCESS + ret // jump to ra +#endif + + WEAK_ALIAS(__unw_getcontext, unw_getcontext) + +#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ + +NO_EXEC_STACK_DIRECTIVE diff --git a/contrib/libs/libunwind/src/Unwind_AppleExtras.cpp b/contrib/libs/libunwind/src/Unwind_AppleExtras.cpp index ffb49a89e5..efe86260df 100644 --- a/contrib/libs/libunwind/src/Unwind_AppleExtras.cpp +++ b/contrib/libs/libunwind/src/Unwind_AppleExtras.cpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // //===----------------------------------------------------------------------===// @@ -27,7 +27,7 @@ __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \ extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \ __attribute__((visibility("default"))) const char sym##_tmp43 = 0; -#elif defined(__aarch64__) +#elif defined(__aarch64__) #define NOT_HERE_BEFORE_10_6(sym) #define NEVER_HERE(sym) #else @@ -46,7 +46,7 @@ #endif -#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) +#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) // // symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in @@ -85,12 +85,12 @@ NEVER_HERE(__register_frame_table) NEVER_HERE(__deregister_frame_info) NEVER_HERE(__deregister_frame_info_bases) -#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) +#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) -#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) +#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) // // symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in // earlier versions @@ -110,4 +110,4 @@ NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException) NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister) -#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) +#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) diff --git a/contrib/libs/libunwind/src/assembly.h b/contrib/libs/libunwind/src/assembly.h index 978f6bd619..826c686643 100644 --- a/contrib/libs/libunwind/src/assembly.h +++ b/contrib/libs/libunwind/src/assembly.h @@ -1,8 +1,8 @@ /* ===-- assembly.h - libUnwind assembler support macros -------------------=== * - * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - * See https://llvm.org/LICENSE.txt for license information. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * * ===----------------------------------------------------------------------=== * @@ -22,17 +22,17 @@ #define _LIBUNWIND_CET_ENDBR #endif -#if defined(__powerpc64__) -#define SEPARATOR ; -#define PPC64_OFFS_SRR0 0 -#define PPC64_OFFS_CR 272 -#define PPC64_OFFS_XER 280 -#define PPC64_OFFS_LR 288 -#define PPC64_OFFS_CTR 296 -#define PPC64_OFFS_VRSAVE 304 -#define PPC64_OFFS_FP 312 -#define PPC64_OFFS_V 824 -#elif defined(__APPLE__) && defined(__aarch64__) +#if defined(__powerpc64__) +#define SEPARATOR ; +#define PPC64_OFFS_SRR0 0 +#define PPC64_OFFS_CR 272 +#define PPC64_OFFS_XER 280 +#define PPC64_OFFS_LR 288 +#define PPC64_OFFS_CTR 296 +#define PPC64_OFFS_VRSAVE 304 +#define PPC64_OFFS_FP 312 +#define PPC64_OFFS_V 824 +#elif defined(__APPLE__) && defined(__aarch64__) #define SEPARATOR %% #elif defined(__riscv) # define RISCV_ISIZE (__riscv_xlen / 8) @@ -67,38 +67,38 @@ #define SEPARATOR ; #endif -#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) -#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR -#define PPC64_OPD2 SEPARATOR \ - .p2align 3 SEPARATOR \ - .quad .Lfunc_begin0 SEPARATOR \ - .quad .TOC.@tocbase SEPARATOR \ - .quad 0 SEPARATOR \ - .text SEPARATOR \ -.Lfunc_begin0: +#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) +#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR +#define PPC64_OPD2 SEPARATOR \ + .p2align 3 SEPARATOR \ + .quad .Lfunc_begin0 SEPARATOR \ + .quad .TOC.@tocbase SEPARATOR \ + .quad 0 SEPARATOR \ + .text SEPARATOR \ +.Lfunc_begin0: #else -#define PPC64_OPD1 -#define PPC64_OPD2 +#define PPC64_OPD1 +#define PPC64_OPD2 #endif #if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) - .pushsection ".note.gnu.property", "a" SEPARATOR \ - .balign 8 SEPARATOR \ - .long 4 SEPARATOR \ - .long 0x10 SEPARATOR \ - .long 0x5 SEPARATOR \ - .asciz "GNU" SEPARATOR \ - .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \ - .long 4 SEPARATOR \ - .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \ - /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \ - .long 0 SEPARATOR \ - .popsection SEPARATOR -#define AARCH64_BTI bti c -#else -#define AARCH64_BTI -#endif - + .pushsection ".note.gnu.property", "a" SEPARATOR \ + .balign 8 SEPARATOR \ + .long 4 SEPARATOR \ + .long 0x10 SEPARATOR \ + .long 0x5 SEPARATOR \ + .asciz "GNU" SEPARATOR \ + .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \ + .long 4 SEPARATOR \ + .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \ + /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \ + .long 0 SEPARATOR \ + .popsection SEPARATOR +#define AARCH64_BTI bti c +#else +#define AARCH64_BTI +#endif + #if !defined(__aarch64__) #ifdef __ARM_FEATURE_PAC_DEFAULT .eabi_attribute Tag_PAC_extension, 2 @@ -115,23 +115,23 @@ #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) #if defined(__APPLE__) - + #define SYMBOL_IS_FUNC(name) #define HIDDEN_SYMBOL(name) .private_extern name #if defined(_LIBUNWIND_HIDE_SYMBOLS) #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) #else -#define EXPORT_SYMBOL(name) +#define EXPORT_SYMBOL(name) #endif -#define WEAK_ALIAS(name, aliasname) \ - .globl SYMBOL_NAME(aliasname) SEPARATOR \ +#define WEAK_ALIAS(name, aliasname) \ + .globl SYMBOL_NAME(aliasname) SEPARATOR \ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ - SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) - -#define NO_EXEC_STACK_DIRECTIVE - + SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) + +#define NO_EXEC_STACK_DIRECTIVE + #elif defined(__ELF__) - + #if defined(__arm__) #define SYMBOL_IS_FUNC(name) .type name,%function #else @@ -141,83 +141,83 @@ #if defined(_LIBUNWIND_HIDE_SYMBOLS) #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) #else -#define EXPORT_SYMBOL(name) +#define EXPORT_SYMBOL(name) #endif -#define WEAK_SYMBOL(name) .weak name - -#if defined(__hexagon__) +#define WEAK_SYMBOL(name) .weak name + +#if defined(__hexagon__) #define WEAK_ALIAS(name, aliasname) \ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ - .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name) -#else -#define WEAK_ALIAS(name, aliasname) \ + .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name) +#else +#define WEAK_ALIAS(name, aliasname) \ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ - SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) -#endif - -#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ - defined(__linux__) -#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits + SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) +#endif + +#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ + defined(__linux__) +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits #else -#define NO_EXEC_STACK_DIRECTIVE -#endif - -#elif defined(_WIN32) - +#define NO_EXEC_STACK_DIRECTIVE +#endif + +#elif defined(_WIN32) + #define SYMBOL_IS_FUNC(name) \ .def name SEPARATOR \ .scl 2 SEPARATOR \ .type 32 SEPARATOR \ .endef -#define EXPORT_SYMBOL2(name) \ - .section .drectve,"yn" SEPARATOR \ - .ascii "-export:", #name, "\0" SEPARATOR \ - .text +#define EXPORT_SYMBOL2(name) \ + .section .drectve,"yn" SEPARATOR \ + .ascii "-export:", #name, "\0" SEPARATOR \ + .text #if defined(_LIBUNWIND_HIDE_SYMBOLS) -#define EXPORT_SYMBOL(name) -#else -#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name) -#endif -#define HIDDEN_SYMBOL(name) - -#if defined(__MINGW32__) -#define WEAK_ALIAS(name, aliasname) \ - .globl SYMBOL_NAME(aliasname) SEPARATOR \ - EXPORT_SYMBOL(aliasname) SEPARATOR \ - SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) -#else -#define WEAK_ALIAS3(name, aliasname) \ - .section .drectve,"yn" SEPARATOR \ - .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \ - .text -#define WEAK_ALIAS2(name, aliasname) \ - WEAK_ALIAS3(name, aliasname) -#define WEAK_ALIAS(name, aliasname) \ - EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ - WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname)) -#endif - -#define NO_EXEC_STACK_DIRECTIVE - -#elif defined(__sparc__) - -#else - -#error Unsupported target - -#endif - -#define DEFINE_LIBUNWIND_FUNCTION(name) \ - .globl SYMBOL_NAME(name) SEPARATOR \ - HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - PPC64_OPD1 \ - SYMBOL_NAME(name): \ - PPC64_OPD2 \ - AARCH64_BTI - +#define EXPORT_SYMBOL(name) +#else +#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name) +#endif +#define HIDDEN_SYMBOL(name) + +#if defined(__MINGW32__) +#define WEAK_ALIAS(name, aliasname) \ + .globl SYMBOL_NAME(aliasname) SEPARATOR \ + EXPORT_SYMBOL(aliasname) SEPARATOR \ + SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) +#else +#define WEAK_ALIAS3(name, aliasname) \ + .section .drectve,"yn" SEPARATOR \ + .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \ + .text +#define WEAK_ALIAS2(name, aliasname) \ + WEAK_ALIAS3(name, aliasname) +#define WEAK_ALIAS(name, aliasname) \ + EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ + WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname)) +#endif + +#define NO_EXEC_STACK_DIRECTIVE + +#elif defined(__sparc__) + +#else + +#error Unsupported target + +#endif + +#define DEFINE_LIBUNWIND_FUNCTION(name) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + PPC64_OPD1 \ + SYMBOL_NAME(name): \ + PPC64_OPD2 \ + AARCH64_BTI + #if defined(__arm__) #if !defined(__ARM_ARCH) #define __ARM_ARCH 4 diff --git a/contrib/libs/libunwind/src/config.h b/contrib/libs/libunwind/src/config.h index 560edda04e..0a7eac8c68 100644 --- a/contrib/libs/libunwind/src/config.h +++ b/contrib/libs/libunwind/src/config.h @@ -1,11 +1,11 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -// Defines macros used within libunwind project. +// Defines macros used within libunwind project. // //===----------------------------------------------------------------------===// @@ -15,227 +15,227 @@ #include <assert.h> #include <stdio.h> -#include <stdint.h> -#include <stdlib.h> +#include <stdint.h> +#include <stdlib.h> -#include <__libunwind_config.h> +#include <__libunwind_config.h> // Platform specific configuration defines. #ifdef __APPLE__ - #if defined(FOR_DYLD) - #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 - #else - #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 - #endif -#elif defined(_WIN32) - #ifdef __SEH__ - #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1 - #else - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 + #if defined(FOR_DYLD) + #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 + #else + #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 #endif -#elif defined(_LIBUNWIND_IS_BAREMETAL) - #if !defined(_LIBUNWIND_ARM_EHABI) - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 - #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 - #endif -#elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI) - // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After - // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster. - #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1 -#else - // Assume an ELF system with a dl_iterate_phdr function. - #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 - #if !defined(_LIBUNWIND_ARM_EHABI) - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 - #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 +#elif defined(_WIN32) + #ifdef __SEH__ + #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1 + #else + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 #endif -#endif +#elif defined(_LIBUNWIND_IS_BAREMETAL) + #if !defined(_LIBUNWIND_ARM_EHABI) + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 + #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 + #endif +#elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI) + // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After + // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster. + #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1 +#else + // Assume an ELF system with a dl_iterate_phdr function. + #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 + #if !defined(_LIBUNWIND_ARM_EHABI) + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 + #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 + #endif +#endif #if defined(_LIBUNWIND_HIDE_SYMBOLS) // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility. - #define _LIBUNWIND_EXPORT - #define _LIBUNWIND_HIDDEN -#else - #if !defined(__ELF__) && !defined(__MACH__) - #define _LIBUNWIND_EXPORT __declspec(dllexport) - #define _LIBUNWIND_HIDDEN + #define _LIBUNWIND_EXPORT + #define _LIBUNWIND_HIDDEN +#else + #if !defined(__ELF__) && !defined(__MACH__) + #define _LIBUNWIND_EXPORT __declspec(dllexport) + #define _LIBUNWIND_HIDDEN #else - #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) - #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) + #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) + #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) #endif -#endif - -#define STR(a) #a -#define XSTR(a) STR(a) -#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name +#endif -#if defined(__APPLE__) +#define STR(a) #a +#define XSTR(a) STR(a) +#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name + +#if defined(__APPLE__) #if defined(_LIBUNWIND_HIDE_SYMBOLS) #define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name); #else #define _LIBUNWIND_ALIAS_VISIBILITY(name) #endif -#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ - __asm__(".globl " SYMBOL_NAME(aliasname)); \ - __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ +#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ + __asm__(".globl " SYMBOL_NAME(aliasname)); \ + __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname)) -#elif defined(__ELF__) -#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ - extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ - __attribute__((weak, alias(#name))); -#elif defined(_WIN32) -#if defined(__MINGW32__) -#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ - extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ - __attribute__((alias(#name))); +#elif defined(__ELF__) +#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ + extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ + __attribute__((weak, alias(#name))); +#elif defined(_WIN32) +#if defined(__MINGW32__) +#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ + extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ + __attribute__((alias(#name))); #else -#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ - __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ - SYMBOL_NAME(name))) \ - extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; -#endif -#else -#error Unsupported target -#endif - -// Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also -// needs to include the SJLJ APIs. -#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) -#define _LIBUNWIND_BUILD_SJLJ_APIS -#endif +#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ + __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ + SYMBOL_NAME(name))) \ + extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; +#endif +#else +#error Unsupported target +#endif + +// Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also +// needs to include the SJLJ APIs. +#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) +#define _LIBUNWIND_BUILD_SJLJ_APIS +#endif #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) -#define _LIBUNWIND_SUPPORT_FRAME_APIS -#endif - -#if defined(__i386__) || defined(__x86_64__) || \ - defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ - (!defined(__APPLE__) && defined(__arm__)) || \ - defined(__aarch64__) || \ - defined(__mips__) || \ - defined(__riscv) || \ - defined(__hexagon__) -#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) -#define _LIBUNWIND_BUILD_ZERO_COST_APIS -#endif -#endif - -#ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC -#if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \ - defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \ - defined(_LIBUNWIND_IS_BAREMETAL) -#define _LIBUNWIND_REMEMBER_ALLOC(_size) alloca(_size) -#define _LIBUNWIND_REMEMBER_FREE(_ptr) \ - do { \ - } while (0) -#elif defined(_WIN32) -#define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size) -#define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr) -#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED -#else -#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) -#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) -#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED -#endif -#else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */ -#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) -#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) -#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED -#endif - -#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) -#define _LIBUNWIND_ABORT(msg) \ - do { \ - abort(); \ - } while (0) -#else -#define _LIBUNWIND_ABORT(msg) \ - do { \ - fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ - fflush(stderr); \ - abort(); \ - } while (0) -#endif - -#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) -#define _LIBUNWIND_LOG0(msg) -#define _LIBUNWIND_LOG(msg, ...) -#else -#define _LIBUNWIND_LOG0(msg) \ - fprintf(stderr, "libunwind: " msg "\n") -#define _LIBUNWIND_LOG(msg, ...) \ - fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) -#endif - -#if defined(NDEBUG) - #define _LIBUNWIND_LOG_IF_FALSE(x) x -#else - #define _LIBUNWIND_LOG_IF_FALSE(x) \ - do { \ - bool _ret = x; \ - if (!_ret) \ - _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ - } while (0) -#endif - +#define _LIBUNWIND_SUPPORT_FRAME_APIS +#endif + +#if defined(__i386__) || defined(__x86_64__) || \ + defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ + (!defined(__APPLE__) && defined(__arm__)) || \ + defined(__aarch64__) || \ + defined(__mips__) || \ + defined(__riscv) || \ + defined(__hexagon__) +#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) +#define _LIBUNWIND_BUILD_ZERO_COST_APIS +#endif +#endif + +#ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC +#if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \ + defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \ + defined(_LIBUNWIND_IS_BAREMETAL) +#define _LIBUNWIND_REMEMBER_ALLOC(_size) alloca(_size) +#define _LIBUNWIND_REMEMBER_FREE(_ptr) \ + do { \ + } while (0) +#elif defined(_WIN32) +#define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size) +#define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr) +#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED +#else +#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) +#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) +#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED +#endif +#else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */ +#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) +#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) +#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED +#endif + +#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) +#define _LIBUNWIND_ABORT(msg) \ + do { \ + abort(); \ + } while (0) +#else +#define _LIBUNWIND_ABORT(msg) \ + do { \ + fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ + fflush(stderr); \ + abort(); \ + } while (0) +#endif + +#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) +#define _LIBUNWIND_LOG0(msg) +#define _LIBUNWIND_LOG(msg, ...) +#else +#define _LIBUNWIND_LOG0(msg) \ + fprintf(stderr, "libunwind: " msg "\n") +#define _LIBUNWIND_LOG(msg, ...) \ + fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) +#endif + +#if defined(NDEBUG) + #define _LIBUNWIND_LOG_IF_FALSE(x) x +#else + #define _LIBUNWIND_LOG_IF_FALSE(x) \ + do { \ + bool _ret = x; \ + if (!_ret) \ + _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ + } while (0) +#endif + // Macros that define away in non-Debug builds #ifdef NDEBUG #define _LIBUNWIND_DEBUG_LOG(msg, ...) #define _LIBUNWIND_TRACE_API(msg, ...) - #define _LIBUNWIND_TRACING_UNWINDING (0) - #define _LIBUNWIND_TRACING_DWARF (0) + #define _LIBUNWIND_TRACING_UNWINDING (0) + #define _LIBUNWIND_TRACING_DWARF (0) #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) - #define _LIBUNWIND_TRACE_DWARF(...) + #define _LIBUNWIND_TRACE_DWARF(...) #else #ifdef __cplusplus extern "C" { #endif extern bool logAPIs(); extern bool logUnwinding(); - extern bool logDWARF(); + extern bool logDWARF(); #ifdef __cplusplus } #endif #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) - #define _LIBUNWIND_TRACE_API(msg, ...) \ - do { \ - if (logAPIs()) \ - _LIBUNWIND_LOG(msg, __VA_ARGS__); \ - } while (0) + #define _LIBUNWIND_TRACE_API(msg, ...) \ + do { \ + if (logAPIs()) \ + _LIBUNWIND_LOG(msg, __VA_ARGS__); \ + } while (0) #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() - #define _LIBUNWIND_TRACING_DWARF logDWARF() - #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ - do { \ - if (logUnwinding()) \ - _LIBUNWIND_LOG(msg, __VA_ARGS__); \ - } while (0) - #define _LIBUNWIND_TRACE_DWARF(...) \ - do { \ - if (logDWARF()) \ - fprintf(stderr, __VA_ARGS__); \ - } while (0) -#endif - -#ifdef __cplusplus -// Used to fit UnwindCursor and Registers_xxx types against unw_context_t / -// unw_cursor_t sized memory blocks. -#if defined(_LIBUNWIND_IS_NATIVE_ONLY) -# define COMP_OP == -#else -# define COMP_OP <= -#endif -template <typename _Type, typename _Mem> -struct check_fit { - template <typename T> - struct blk_count { - static const size_t count = - (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); - }; - static const bool does_fit = - (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); -}; -#undef COMP_OP -#endif // __cplusplus + #define _LIBUNWIND_TRACING_DWARF logDWARF() + #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ + do { \ + if (logUnwinding()) \ + _LIBUNWIND_LOG(msg, __VA_ARGS__); \ + } while (0) + #define _LIBUNWIND_TRACE_DWARF(...) \ + do { \ + if (logDWARF()) \ + fprintf(stderr, __VA_ARGS__); \ + } while (0) +#endif + +#ifdef __cplusplus +// Used to fit UnwindCursor and Registers_xxx types against unw_context_t / +// unw_cursor_t sized memory blocks. +#if defined(_LIBUNWIND_IS_NATIVE_ONLY) +# define COMP_OP == +#else +# define COMP_OP <= +#endif +template <typename _Type, typename _Mem> +struct check_fit { + template <typename T> + struct blk_count { + static const size_t count = + (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); + }; + static const bool does_fit = + (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); +}; +#undef COMP_OP +#endif // __cplusplus #endif // LIBUNWIND_CONFIG_H diff --git a/contrib/libs/libunwind/src/dwarf2.h b/contrib/libs/libunwind/src/dwarf2.h index 174277d5a7..53d65fe326 100644 --- a/contrib/libs/libunwind/src/dwarf2.h +++ b/contrib/libs/libunwind/src/dwarf2.h @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -48,10 +48,10 @@ enum { // GNU extensions DW_CFA_GNU_window_save = 0x2D, DW_CFA_GNU_args_size = 0x2E, - DW_CFA_GNU_negative_offset_extended = 0x2F, - - // AARCH64 extensions - DW_CFA_AARCH64_negate_ra_state = 0x2D + DW_CFA_GNU_negative_offset_extended = 0x2F, + + // AARCH64 extensions + DW_CFA_AARCH64_negate_ra_state = 0x2D }; diff --git a/contrib/libs/libunwind/src/libunwind.cpp b/contrib/libs/libunwind/src/libunwind.cpp index 03f8b75b5b..ee2f423289 100644 --- a/contrib/libs/libunwind/src/libunwind.cpp +++ b/contrib/libs/libunwind/src/libunwind.cpp @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Implements unw_* functions from <libunwind.h> @@ -21,13 +21,13 @@ #if !defined(__has_feature) #define __has_feature(feature) 0 #endif - + #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) #include <sanitizer/asan_interface.h> #endif -#if !defined(__USING_SJLJ_EXCEPTIONS__) -#include "AddressSpace.hpp" +#if !defined(__USING_SJLJ_EXCEPTIONS__) +#include "AddressSpace.hpp" #include "UnwindCursor.hpp" using namespace libunwind; @@ -39,61 +39,61 @@ _LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space = (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace; /// Create a cursor of a thread in this process given 'context' recorded by -/// __unw_getcontext(). -_LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, - unw_context_t *context) { - _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)", +/// __unw_getcontext(). +_LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, + unw_context_t *context) { + _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)", static_cast<void *>(cursor), static_cast<void *>(context)); #if defined(__i386__) -# define REGISTER_KIND Registers_x86 +# define REGISTER_KIND Registers_x86 #elif defined(__x86_64__) -# define REGISTER_KIND Registers_x86_64 -#elif defined(__powerpc64__) -# define REGISTER_KIND Registers_ppc64 +# define REGISTER_KIND Registers_x86_64 +#elif defined(__powerpc64__) +# define REGISTER_KIND Registers_ppc64 #elif defined(__powerpc__) -# define REGISTER_KIND Registers_ppc -#elif defined(__aarch64__) -# define REGISTER_KIND Registers_arm64 -#elif defined(__arm__) -# define REGISTER_KIND Registers_arm +# define REGISTER_KIND Registers_ppc +#elif defined(__aarch64__) +# define REGISTER_KIND Registers_arm64 +#elif defined(__arm__) +# define REGISTER_KIND Registers_arm #elif defined(__or1k__) -# define REGISTER_KIND Registers_or1k -#elif defined(__hexagon__) -# define REGISTER_KIND Registers_hexagon -#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 -# define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips64) -# define REGISTER_KIND Registers_mips_newabi +# define REGISTER_KIND Registers_or1k +#elif defined(__hexagon__) +# define REGISTER_KIND Registers_hexagon +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 +# define REGISTER_KIND Registers_mips_o32 +#elif defined(__mips64) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) -# warning The MIPS architecture is not supported with this ABI and environment! +# warning The MIPS architecture is not supported with this ABI and environment! #elif defined(__sparc__) && defined(__arch64__) #define REGISTER_KIND Registers_sparc64 -#elif defined(__sparc__) -# define REGISTER_KIND Registers_sparc +#elif defined(__sparc__) +# define REGISTER_KIND Registers_sparc #elif defined(__riscv) -# define REGISTER_KIND Registers_riscv +# define REGISTER_KIND Registers_riscv #elif defined(__ve__) # define REGISTER_KIND Registers_ve #else -# error Architecture not supported +# error Architecture not supported #endif - // Use "placement new" to allocate UnwindCursor in the cursor buffer. - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor)) - UnwindCursor<LocalAddressSpace, REGISTER_KIND>( - context, LocalAddressSpace::sThisAddressSpace); -#undef REGISTER_KIND + // Use "placement new" to allocate UnwindCursor in the cursor buffer. + new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor)) + UnwindCursor<LocalAddressSpace, REGISTER_KIND>( + context, LocalAddressSpace::sThisAddressSpace); +#undef REGISTER_KIND AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; } -_LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local) +_LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local) /// Get value of specified register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_word_t *value) { - _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)", +_LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, + unw_word_t *value) { + _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -103,44 +103,44 @@ _LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } -_LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) +_LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) /// Set value of specified register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_word_t value) { - _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR - ")", - static_cast<void *>(cursor), regNum, value); +_LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, + unw_word_t value) { + _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR + ")", + static_cast<void *>(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { co->setReg(regNum, (pint_t)value); // specical case altering IP to re-find info (being called by personality // function) - if (regNum == UNW_REG_IP) { - unw_proc_info_t info; - // First, get the FDE for the old location and then update it. - co->getInfo(&info); + if (regNum == UNW_REG_IP) { + unw_proc_info_t info; + // First, get the FDE for the old location and then update it. + co->getInfo(&info); co->setInfoBasedOnIPRegister(false); - // If the original call expects stack adjustment, perform this now. - // Normal frame unwinding would have included the offset already in the - // CFA computation. - // Note: for PA-RISC and other platforms where the stack grows up, - // this should actually be - info.gp. LLVM doesn't currently support - // any such platforms and Clang doesn't export a macro for them. - if (info.gp) - co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); - } + // If the original call expects stack adjustment, perform this now. + // Normal frame unwinding would have included the offset already in the + // CFA computation. + // Note: for PA-RISC and other platforms where the stack grows up, + // this should actually be - info.gp. LLVM doesn't currently support + // any such platforms and Clang doesn't export a macro for them. + if (info.gp) + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); + } return UNW_ESUCCESS; } return UNW_EBADREG; } -_LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg) +_LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg) /// Get value of specified float register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_fpreg_t *value) { - _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)", +_LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, + unw_fpreg_t *value) { + _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -150,16 +150,16 @@ _LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } -_LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg) +_LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg) /// Set value of specified float register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_fpreg_t value) { -#if defined(_LIBUNWIND_ARM_EHABI) - _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", +_LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, + unw_fpreg_t value) { +#if defined(_LIBUNWIND_ARM_EHABI) + _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", static_cast<void *>(cursor), regNum, value); #else - _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", + _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", static_cast<void *>(cursor), regNum, value); #endif AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -169,32 +169,32 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } -_LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) +_LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) /// Move cursor to next frame. -_LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor)); +_LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { + _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->step(); } -_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) +_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) /// Get unwind info at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor, - unw_proc_info_t *info) { - _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)", +_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor, + unw_proc_info_t *info) { + _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)", static_cast<void *>(cursor), static_cast<void *>(info)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->getInfo(info); if (info->end_ip == 0) return UNW_ENOINFO; - return UNW_ESUCCESS; + return UNW_ESUCCESS; } -_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info) +_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info) /// Resume execution at cursor position (aka longjump). -_LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor)); +_LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) { + _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor)); #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) // Inform the ASan runtime that now might be a good time to clean stuff up. __asan_handle_no_return(); @@ -203,75 +203,75 @@ _LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) { co->jumpto(); return UNW_EUNSPEC; } -_LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume) +_LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume) /// Get name of function at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf, - size_t bufLen, unw_word_t *offset) { - _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)", +_LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf, + size_t bufLen, unw_word_t *offset) { + _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)", static_cast<void *>(cursor), static_cast<void *>(buf), static_cast<unsigned long>(bufLen)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->getFunctionName(buf, bufLen, offset)) return UNW_ESUCCESS; - return UNW_EUNSPEC; + return UNW_EUNSPEC; } -_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name) +_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name) /// Checks if a register is a floating-point register. -_LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor, - unw_regnum_t regNum) { - _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)", +_LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor, + unw_regnum_t regNum) { + _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->validFloatReg(regNum); } -_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg) +_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg) /// Checks if a register is a floating-point register. -_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor, - unw_regnum_t regNum) { - _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)", +_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor, + unw_regnum_t regNum) { + _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->getRegisterName(regNum); } -_LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) +_LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) /// Checks if current frame is signal trampoline. -_LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)", +_LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) { + _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)", static_cast<void *>(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->isSignalFrame(); } -_LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) +_LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) #ifdef __arm__ // Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD -_LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)", +_LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) { + _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)", static_cast<void *>(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->saveVFPAsX(); } -_LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X) +_LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X) #endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -/// SPI: walks cached DWARF entries -_LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)( +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +/// SPI: walks cached DWARF entries +_LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)( unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { - _LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)", + _LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)", reinterpret_cast<void *>(func)); DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func); } -_LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache, - unw_iterate_dwarf_unwind_cache) +_LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache, + unw_iterate_dwarf_unwind_cache) /// IPI: for __register_frame() -void __unw_add_dynamic_fde(unw_word_t fde) { +void __unw_add_dynamic_fde(unw_word_t fde) { CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE( @@ -285,14 +285,14 @@ void __unw_add_dynamic_fde(unw_word_t fde) { fdeInfo.pcStart, fdeInfo.pcEnd, fdeInfo.fdeStart); } else { - _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message); + _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message); } } /// IPI: for __deregister_frame() -void __unw_remove_dynamic_fde(unw_word_t fde) { +void __unw_remove_dynamic_fde(unw_word_t fde) { // fde is own mh_group - DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde); + DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde); } void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start) { @@ -323,8 +323,8 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { (LocalAddressSpace::pint_t)eh_frame_start); } -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#endif // !defined(__USING_SJLJ_EXCEPTIONS__) +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +#endif // !defined(__USING_SJLJ_EXCEPTIONS__) @@ -356,17 +356,17 @@ bool logUnwinding() { return log; } -_LIBUNWIND_HIDDEN -bool logDWARF() { - // do manual lock to avoid use of _cxa_guard_acquire or initializers - static bool checked = false; - static bool log = false; - if (!checked) { - log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL); - checked = true; - } - return log; -} - +_LIBUNWIND_HIDDEN +bool logDWARF() { + // do manual lock to avoid use of _cxa_guard_acquire or initializers + static bool checked = false; + static bool log = false; + if (!checked) { + log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL); + checked = true; + } + return log; +} + #endif // NDEBUG - + diff --git a/contrib/libs/libunwind/src/libunwind_ext.h b/contrib/libs/libunwind/src/libunwind_ext.h index 7065ffcdae..a35f0f0463 100644 --- a/contrib/libs/libunwind/src/libunwind_ext.h +++ b/contrib/libs/libunwind/src/libunwind_ext.h @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Extensions to libunwind API. @@ -22,39 +22,39 @@ #ifdef __cplusplus extern "C" { #endif - -extern int __unw_getcontext(unw_context_t *); -extern int __unw_init_local(unw_cursor_t *, unw_context_t *); -extern int __unw_step(unw_cursor_t *); -extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); -extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); -extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); -extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); -extern int __unw_resume(unw_cursor_t *); - -#ifdef __arm__ -/* Save VFP registers in FSTMX format (instead of FSTMD). */ -extern void __unw_save_vfp_as_X(unw_cursor_t *); -#endif - -extern const char *__unw_regname(unw_cursor_t *, unw_regnum_t); -extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *); -extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); -extern int __unw_is_signal_frame(unw_cursor_t *); -extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); - + +extern int __unw_getcontext(unw_context_t *); +extern int __unw_init_local(unw_cursor_t *, unw_context_t *); +extern int __unw_step(unw_cursor_t *); +extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); +extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); +extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); +extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); +extern int __unw_resume(unw_cursor_t *); + +#ifdef __arm__ +/* Save VFP registers in FSTMX format (instead of FSTMD). */ +extern void __unw_save_vfp_as_X(unw_cursor_t *); +#endif + +extern const char *__unw_regname(unw_cursor_t *, unw_regnum_t); +extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *); +extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); +extern int __unw_is_signal_frame(unw_cursor_t *); +extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); + // SPI -extern void __unw_iterate_dwarf_unwind_cache(void (*func)( - unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)); +extern void __unw_iterate_dwarf_unwind_cache(void (*func)( + unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)); // IPI -extern void __unw_add_dynamic_fde(unw_word_t fde); -extern void __unw_remove_dynamic_fde(unw_word_t fde); +extern void __unw_add_dynamic_fde(unw_word_t fde); +extern void __unw_remove_dynamic_fde(unw_word_t fde); extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start); -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, diff --git a/contrib/libs/libunwind/ya.make b/contrib/libs/libunwind/ya.make index 2d1aa635d4..09b0982f95 100644 --- a/contrib/libs/libunwind/ya.make +++ b/contrib/libs/libunwind/ya.make @@ -1,5 +1,5 @@ # Generated by devtools/yamaker from nixpkgs 21.11. - + LIBRARY() OWNER( @@ -11,34 +11,34 @@ OWNER( VERSION(2022-02-05) ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/2b9554b8850192bdd86c02eb671de1d866df8d87.tar.gz) - + LICENSE( Apache-2.0 AND Apache-2.0 WITH LLVM-exception AND MIT AND NCSA ) - + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -DISABLE(USE_LTO) +DISABLE(USE_LTO) ADDINCL( contrib/libs/libunwind/include ) -NO_RUNTIME() - -NO_UTIL() - -NO_SANITIZE() - -NO_SANITIZE_COVERAGE() - -CFLAGS( - GLOBAL -D_libunwind_ - -D_LIBUNWIND_IS_NATIVE_ONLY - -fno-exceptions +NO_RUNTIME() + +NO_UTIL() + +NO_SANITIZE() + +NO_SANITIZE_COVERAGE() + +CFLAGS( + GLOBAL -D_libunwind_ + -D_LIBUNWIND_IS_NATIVE_ONLY + -fno-exceptions -fno-rtti -funwind-tables ) @@ -47,26 +47,26 @@ IF (SANITIZER_TYPE == memory) CFLAGS( -fPIC ) -ENDIF() +ENDIF() SRCS( - src/Unwind-EHABI.cpp - src/Unwind-seh.cpp - src/Unwind-sjlj.c - src/UnwindLevel1-gcc-ext.c - src/UnwindLevel1.c - src/UnwindRegistersRestore.S - src/UnwindRegistersSave.S - src/libunwind.cpp + src/Unwind-EHABI.cpp + src/Unwind-seh.cpp + src/Unwind-sjlj.c + src/UnwindLevel1-gcc-ext.c + src/UnwindLevel1.c + src/UnwindRegistersRestore.S + src/UnwindRegistersSave.S + src/libunwind.cpp ) -IF (OS_DARWIN OR OS_IOS) +IF (OS_DARWIN OR OS_IOS) SRCS( - src/Unwind_AppleExtras.cpp + src/Unwind_AppleExtras.cpp ) -ENDIF() +ENDIF() -END() +END() RECURSE_FOR_TESTS( ut |