diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:22 +0000 |
commit | cd5ff43da54e357cd6a79fea21f2ae1afb8d3660 (patch) | |
tree | f84ce6bb47224ea6049644f9fe90f9b68fbac565 | |
parent | 8ef57cf97cea96f88139ced9dfaa80f1049144cb (diff) |
Vendor import of stripped LLVM libunwind trunk r366426 (just before thevendor/llvm-libunwind/libunwind-trunk-r366426vendor/llvm-libunwind/libunwind-release_900-r372316vendor/llvm-libunwind/libunwind-release_90-r371301vendor/llvm-libunwind/libunwind-release_90-r370514vendor/llvm-libunwind/libunwind-release_90-r369369vendor/llvm-libunwind-90
release_90 branch point):
https://llvm.org/svn/llvm-project/libunwind/trunk@366426
Notes
Notes:
svn path=/vendor/llvm-libunwind/dist/; revision=351286
svn path=/vendor/llvm-libunwind/libunwind-release_900-r372316/; revision=352528; tag=vendor/llvm-libunwind/libunwind-release_900-r372316
-rw-r--r-- | LICENSE.TXT | 237 | ||||
-rw-r--r-- | include/__libunwind_config.h | 7 | ||||
-rw-r--r-- | include/libunwind.h | 35 | ||||
-rw-r--r-- | include/mach-o/compact_unwind_encoding.h | 7 | ||||
-rw-r--r-- | include/unwind.h | 9 | ||||
-rw-r--r-- | src/AddressSpace.hpp | 155 | ||||
-rw-r--r-- | src/CompactUnwinder.hpp | 7 | ||||
-rw-r--r-- | src/DwarfInstructions.hpp | 39 | ||||
-rw-r--r-- | src/DwarfParser.hpp | 7 | ||||
-rw-r--r-- | src/EHHeaderParser.hpp | 23 | ||||
-rw-r--r-- | src/RWMutex.hpp | 49 | ||||
-rw-r--r-- | src/Registers.hpp | 27 | ||||
-rw-r--r-- | src/Unwind-EHABI.cpp | 109 | ||||
-rw-r--r-- | src/Unwind-EHABI.h | 7 | ||||
-rw-r--r-- | src/Unwind-seh.cpp | 100 | ||||
-rw-r--r-- | src/Unwind-sjlj.c | 120 | ||||
-rw-r--r-- | src/UnwindCursor.hpp | 53 | ||||
-rw-r--r-- | src/UnwindLevel1-gcc-ext.c | 41 | ||||
-rw-r--r-- | src/UnwindLevel1.c | 120 | ||||
-rw-r--r-- | src/UnwindRegistersRestore.S | 289 | ||||
-rw-r--r-- | src/UnwindRegistersSave.S | 337 | ||||
-rw-r--r-- | src/Unwind_AppleExtras.cpp | 7 | ||||
-rw-r--r-- | src/assembly.h | 74 | ||||
-rw-r--r-- | src/config.h | 36 | ||||
-rw-r--r-- | src/dwarf2.h | 7 | ||||
-rw-r--r-- | src/libunwind.cpp | 214 | ||||
-rw-r--r-- | src/libunwind_ext.h | 38 |
27 files changed, 1181 insertions, 973 deletions
diff --git a/LICENSE.TXT b/LICENSE.TXT index 23109b4aa7bb..1e3120621cae 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,240 @@ ============================================================================== -libunwind License +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 diff --git a/include/__libunwind_config.h b/include/__libunwind_config.h index a8e30de13a6a..6e7e5e6f7f86 100644 --- a/include/__libunwind_config.h +++ b/include/__libunwind_config.h @@ -1,9 +1,8 @@ //===------------------------- __libunwind_config.h -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/libunwind.h b/include/libunwind.h index 29c4aebde5ac..d06724d3c31f 100644 --- a/include/libunwind.h +++ b/include/libunwind.h @@ -1,9 +1,8 @@ //===---------------------------- libunwind.h -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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: @@ -76,7 +75,7 @@ typedef struct unw_addr_space *unw_addr_space_t; typedef int unw_regnum_t; typedef uintptr_t unw_word_t; -#if defined(__arm__) +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) typedef uint64_t unw_fpreg_t; #else typedef double unw_fpreg_t; @@ -125,32 +124,6 @@ extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUN extern unw_addr_space_t unw_local_addr_space; -#ifdef UNW_REMOTE -/* - * Mac OS X "remote" API for unwinding other processes on same machine - * - */ -extern unw_addr_space_t unw_create_addr_space_for_task(task_t); -extern void unw_destroy_addr_space(unw_addr_space_t); -extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *); -#endif /* UNW_REMOTE */ - -/* - * traditional libunwind "remote" API - * NOT IMPLEMENTED on Mac OS X - * - * extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t, - * thread_t*); - * extern unw_accessors_t unw_get_accessors(unw_addr_space_t); - * extern unw_addr_space_t unw_create_addr_space(unw_accessors_t, int); - * extern void unw_flush_cache(unw_addr_space_t, unw_word_t, - * unw_word_t); - * extern int unw_set_caching_policy(unw_addr_space_t, - * unw_caching_policy_t); - * extern void _U_dyn_register(unw_dyn_info_t*); - * extern void _U_dyn_cancel(unw_dyn_info_t*); - */ - #ifdef __cplusplus } #endif diff --git a/include/mach-o/compact_unwind_encoding.h b/include/mach-o/compact_unwind_encoding.h index de14fd51e53e..5301b1055ef9 100644 --- a/include/mach-o/compact_unwind_encoding.h +++ b/include/mach-o/compact_unwind_encoding.h @@ -1,9 +1,8 @@ //===------------------ mach-o/compact_unwind_encoding.h ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. diff --git a/include/unwind.h b/include/unwind.h index ae8ae5d24edc..b6cc70498b37 100644 --- a/include/unwind.h +++ b/include/unwind.h @@ -1,13 +1,12 @@ //===------------------------------- unwind.h -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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: -// http://mentorembedded.github.io/cxx-abi/abi-eh.html +// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html // //===----------------------------------------------------------------------===// diff --git a/src/AddressSpace.hpp b/src/AddressSpace.hpp index 30ad35995aec..fb07c807db9e 100644 --- a/src/AddressSpace.hpp +++ b/src/AddressSpace.hpp @@ -1,9 +1,8 @@ //===------------------------- AddressSpace.hpp ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -28,6 +27,9 @@ #if _LIBUNWIND_USE_DLADDR #include <dlfcn.h> +#if defined(__unix__) && defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA) +#pragma comment(lib, "dl") +#endif #endif #ifdef __APPLE__ @@ -457,6 +459,8 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, #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_ARM_EHABI) && defined(__BIONIC__) && \ (__ANDROID_API__ < 21) @@ -534,11 +538,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, #endif cbdata->sects->dwarf_index_section = eh_frame_hdr_start; cbdata->sects->dwarf_index_section_length = phdr->p_memsz; - EHHeaderParser<LocalAddressSpace>::decodeEHHdr( + found_hdr = EHHeaderParser<LocalAddressSpace>::decodeEHHdr( *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, hdrInfo); - cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; - found_hdr = true; + if (found_hdr) + cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; } } @@ -597,142 +601,15 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, return true; } } +#else + (void)addr; + (void)buf; + (void)bufLen; + (void)offset; #endif return false; } - - -#ifdef UNW_REMOTE - -/// RemoteAddressSpace is used as a template parameter to UnwindCursor when -/// unwinding a thread in the another process. The other process can be a -/// different endianness and a different pointer size which is handled by -/// the P template parameter. -template <typename P> -class RemoteAddressSpace { -public: - RemoteAddressSpace(task_t task) : fTask(task) {} - - typedef typename P::uint_t pint_t; - - uint8_t get8(pint_t addr); - uint16_t get16(pint_t addr); - uint32_t get32(pint_t addr); - uint64_t get64(pint_t addr); - pint_t getP(pint_t addr); - uint64_t getRegister(pint_t addr); - uint64_t getULEB128(pint_t &addr, pint_t end); - int64_t getSLEB128(pint_t &addr, pint_t end); - pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, - pint_t datarelBase = 0); - bool findFunctionName(pint_t addr, char *buf, size_t bufLen, - unw_word_t *offset); - bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); - bool findOtherFDE(pint_t targetAddr, pint_t &fde); -private: - void *localCopy(pint_t addr); - - task_t fTask; -}; - -template <typename P> uint8_t RemoteAddressSpace<P>::get8(pint_t addr) { - return *((uint8_t *)localCopy(addr)); -} - -template <typename P> uint16_t RemoteAddressSpace<P>::get16(pint_t addr) { - return P::E::get16(*(uint16_t *)localCopy(addr)); -} - -template <typename P> uint32_t RemoteAddressSpace<P>::get32(pint_t addr) { - return P::E::get32(*(uint32_t *)localCopy(addr)); -} - -template <typename P> uint64_t RemoteAddressSpace<P>::get64(pint_t addr) { - return P::E::get64(*(uint64_t *)localCopy(addr)); -} - -template <typename P> -typename P::uint_t RemoteAddressSpace<P>::getP(pint_t addr) { - return P::getP(*(uint64_t *)localCopy(addr)); -} - -template <typename P> -typename P::uint_t OtherAddressSpace<P>::getRegister(pint_t addr) { - return P::getRegister(*(uint64_t *)localCopy(addr)); -} - -template <typename P> -uint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { - uintptr_t size = (end - addr); - LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); - LocalAddressSpace::pint_t sladdr = laddr; - uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size); - addr += (laddr - sladdr); - return result; -} - -template <typename P> -int64_t RemoteAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) { - uintptr_t size = (end - addr); - LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); - LocalAddressSpace::pint_t sladdr = laddr; - uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size); - addr += (laddr - sladdr); - return result; -} - -template <typename P> void *RemoteAddressSpace<P>::localCopy(pint_t addr) { - // FIX ME -} - -template <typename P> -bool RemoteAddressSpace<P>::findFunctionName(pint_t addr, char *buf, - size_t bufLen, - unw_word_t *offset) { - // FIX ME -} - -/// unw_addr_space is the base class that abstract unw_addr_space_t type in -/// libunwind.h points to. -struct unw_addr_space { - cpu_type_t cpuType; - task_t taskPort; -}; - -/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points -/// to when examining -/// a 32-bit intel process. -struct unw_addr_space_i386 : public unw_addr_space { - unw_addr_space_i386(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer32<LittleEndian>> oas; -}; - -/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t -/// points to when examining -/// a 64-bit intel process. -struct unw_addr_space_x86_64 : public unw_addr_space { - unw_addr_space_x86_64(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer64<LittleEndian>> oas; -}; - -/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points -/// to when examining -/// a 32-bit PowerPC process. -struct unw_addr_space_ppc : public unw_addr_space { - unw_addr_space_ppc(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer32<BigEndian>> oas; -}; - -/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points -/// to when examining a 64-bit PowerPC process. -struct unw_addr_space_ppc64 : public unw_addr_space { - unw_addr_space_ppc64(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer64<LittleEndian>> oas; -}; - -#endif // UNW_REMOTE - } // namespace libunwind #endif // __ADDRESSSPACE_HPP__ diff --git a/src/CompactUnwinder.hpp b/src/CompactUnwinder.hpp index 7b97bf84cebd..1c3175dff50a 100644 --- a/src/CompactUnwinder.hpp +++ b/src/CompactUnwinder.hpp @@ -1,9 +1,8 @@ //===-------------------------- CompactUnwinder.hpp -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. diff --git a/src/DwarfInstructions.hpp b/src/DwarfInstructions.hpp index ec70c0a11f70..29a070fa3e04 100644 --- a/src/DwarfInstructions.hpp +++ b/src/DwarfInstructions.hpp @@ -1,9 +1,8 @@ //===-------------------------- DwarfInstructions.hpp ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -82,12 +81,11 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser<A>::kRegisterInCFA: - return addressSpace.getRegister(cfa + (pint_t)savedReg.value); + return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser<A>::kRegisterAtExpression: - return 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, @@ -234,6 +232,31 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, } #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); diff --git a/src/DwarfParser.hpp b/src/DwarfParser.hpp index a2c6d7f8db9f..df69c2a4bd23 100644 --- a/src/DwarfParser.hpp +++ b/src/DwarfParser.hpp @@ -1,9 +1,8 @@ //===--------------------------- DwarfParser.hpp --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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). diff --git a/src/EHHeaderParser.hpp b/src/EHHeaderParser.hpp index 9bdaf5505ff0..0101835b8e63 100644 --- a/src/EHHeaderParser.hpp +++ b/src/EHHeaderParser.hpp @@ -1,9 +1,8 @@ //===------------------------- EHHeaderParser.hpp -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -36,7 +35,7 @@ public: uint8_t table_enc; }; - static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, + static bool decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo); static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, uint32_t sectionLength, @@ -53,12 +52,14 @@ private: }; template <typename A> -void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, +bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) { pint_t p = ehHdrStart; uint8_t version = addressSpace.get8(p++); - if (version != 1) - _LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version"); + if (version != 1) { + _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version"); + return false; + } uint8_t eh_frame_ptr_enc = addressSpace.get8(p++); uint8_t fde_count_enc = addressSpace.get8(p++); @@ -71,6 +72,8 @@ void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, ? 0 : addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart); ehHdrInfo.table = p; + + return true; } template <typename A> @@ -102,7 +105,9 @@ bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, pint_t ehHdrEnd = ehHdrStart + sectionLength; EHHeaderParser<A>::EHHeaderInfo hdrInfo; - EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo); + if (!EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, + hdrInfo)) + return false; size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc); pint_t tableEntry; diff --git a/src/RWMutex.hpp b/src/RWMutex.hpp index 50a78a57b089..a37ac77144f3 100644 --- a/src/RWMutex.hpp +++ b/src/RWMutex.hpp @@ -1,9 +1,8 @@ //===----------------------------- Registers.hpp --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 @@ -18,6 +17,9 @@ #include <windows.h> #elif !defined(_LIBUNWIND_HAS_NO_THREADS) #include <pthread.h> +#if defined(__unix__) && defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA) +#pragma comment(lib, "pthread") +#endif #endif namespace libunwind { @@ -57,11 +59,11 @@ private: SRWLOCK _lock = SRWLOCK_INIT; }; -#else +#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD) class _LIBUNWIND_HIDDEN RWMutex { public: - bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; } + 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; } @@ -70,6 +72,41 @@ 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 diff --git a/src/Registers.hpp b/src/Registers.hpp index a4f5a85f2a7b..a36c6cf90d3f 100644 --- a/src/Registers.hpp +++ b/src/Registers.hpp @@ -1,9 +1,8 @@ //===----------------------------- Registers.hpp --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -2104,16 +2103,16 @@ private: uint32_t __pc; // Program counter r15 }; - static void saveVFPWithFSTMD(unw_fpreg_t*); - static void saveVFPWithFSTMX(unw_fpreg_t*); - static void saveVFPv3(unw_fpreg_t*); - static void restoreVFPWithFLDMD(unw_fpreg_t*); - static void restoreVFPWithFLDMX(unw_fpreg_t*); - static void restoreVFPv3(unw_fpreg_t*); + 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(unw_fpreg_t*); + static void saveiWMMX(void*); static void saveiWMMXControl(uint32_t*); - static void restoreiWMMX(unw_fpreg_t*); + static void restoreiWMMX(void*); static void restoreiWMMXControl(uint32_t*); #endif void restoreCoreAndJumpTo(); @@ -2155,7 +2154,7 @@ inline Registers_arm::Registers_arm(const void *registers) _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. + // See __unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); @@ -2434,7 +2433,7 @@ 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)) diff --git a/src/Unwind-EHABI.cpp b/src/Unwind-EHABI.cpp index f37732c6ac86..4ff5e318b5f1 100644 --- a/src/Unwind-EHABI.cpp +++ b/src/Unwind-EHABI.cpp @@ -1,9 +1,8 @@ //===--------------------------- Unwind-EHABI.cpp -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 @@ -21,8 +20,6 @@ #include <stdlib.h> #include <string.h> -#include <type_traits> - #include "config.h" #include "libunwind.h" #include "libunwind_ext.h" @@ -34,7 +31,11 @@ namespace { // signinficant byte. uint8_t getByte(const uint32_t* data, size_t offset) { const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data); +#ifdef __LITTLE_ENDIAN__ return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))]; +#else + return byteData[offset]; +#endif } const char* getNextWord(const char* data, uint32_t* out) { @@ -182,7 +183,7 @@ static _Unwind_Reason_Code unwindOneFrame(_Unwind_State state, if (result != _URC_CONTINUE_UNWIND) return result; - if (unw_step(reinterpret_cast<unw_cursor_t*>(context)) != UNW_STEP_SUCCESS) + if (__unw_step(reinterpret_cast<unw_cursor_t *>(context)) != UNW_STEP_SUCCESS) return _URC_FAILURE; return _URC_CONTINUE_UNWIND; } @@ -443,17 +444,18 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // 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; } @@ -462,12 +464,12 @@ 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, @@ -537,7 +539,7 @@ 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)", static_cast<void *>(exception_object)); @@ -559,19 +561,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; } @@ -580,8 +583,8 @@ 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( @@ -625,8 +628,8 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // 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, static_cast<void *>(exception_object), @@ -637,11 +640,11 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // 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 @@ -670,7 +673,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { static_cast<void *>(exception_object)); unw_context_t uc; unw_cursor_t cursor; - unw_getcontext(&uc); + __unw_getcontext(&uc); // This field for is for compatibility with GCC to say this isn't a forced // unwind. EHABI #7.2 @@ -708,7 +711,7 @@ _Unwind_Resume(_Unwind_Exception *exception_object) { static_cast<void *>(exception_object)); unw_context_t uc; unw_cursor_t cursor; - unw_getcontext(&uc); + __unw_getcontext(&uc); // _Unwind_RaiseException on EHABI will always set the reserved1 field to 0, // which is in the same position as private_1 below. @@ -725,7 +728,7 @@ _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", @@ -765,8 +768,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: @@ -776,28 +779,28 @@ _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 + 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_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 @@ -819,8 +822,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: @@ -830,28 +833,28 @@ _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 + 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_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 @@ -960,7 +963,7 @@ _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", static_cast<void *>(context), (long long)result); @@ -983,7 +986,7 @@ extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception *exception_object, struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; - if (unw_step(cursor) != UNW_STEP_SUCCESS) + if (__unw_step(cursor) != UNW_STEP_SUCCESS) return _URC_FAILURE; return _URC_OK; } diff --git a/src/Unwind-EHABI.h b/src/Unwind-EHABI.h index fe164ff7be1e..6897082a337f 100644 --- a/src/Unwind-EHABI.h +++ b/src/Unwind-EHABI.h @@ -1,9 +1,8 @@ //===------------------------- Unwind-EHABI.hpp ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // // //===----------------------------------------------------------------------===// diff --git a/src/Unwind-seh.cpp b/src/Unwind-seh.cpp index c5cf7c47d40d..7647f2e0db0b 100644 --- a/src/Unwind-seh.cpp +++ b/src/Unwind-seh.cpp @@ -1,9 +1,8 @@ //===--------------------------- Unwind-seh.cpp ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -53,14 +52,16 @@ static const uint64_t kSEHExceptionClass = 0x434C4E4753454800; // CLNGSEH\0 /// Exception cleanup routine used by \c _GCC_specific_handler to /// free foreign exceptions. static void seh_exc_cleanup(_Unwind_Reason_Code urc, _Unwind_Exception *exc) { + (void)urc; if (exc->exception_class != kSEHExceptionClass) _LIBUNWIND_ABORT("SEH cleanup called on non-SEH exception"); free(exc); } -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); +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: @@ -69,7 +70,6 @@ static void _unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp _LIBUNWIND_EXPORT EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, DISPATCHER_CONTEXT *disp, __personality_routine pers) { - unw_context_t uc; unw_cursor_t cursor; _Unwind_Exception *exc; _Unwind_Action action; @@ -78,7 +78,9 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, uintptr_t retval, target; bool ours = false; - _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler(%#010x(%x), %p)", ms_exc->ExceptionCode, ms_exc->ExceptionFlags, frame); + _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 @@ -112,9 +114,9 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, memset(exc->private_, 0, sizeof(exc->private_)); } 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); + __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)) { @@ -130,7 +132,10 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, } } - _LIBUNWIND_TRACE_UNWINDING("_GCC_specific_handler() calling personality function %p(1, %d, %llx, %p, %p)", pers, action, exc->exception_class, exc, ctx); + _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) { @@ -168,18 +173,18 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, _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]); + __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]); + __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_ARM64_X0, &retval); - unw_get_reg(&cursor, UNW_ARM64_X1, &exc->private_[3]); + __unw_get_reg(&cursor, UNW_ARM64_X0, &retval); + __unw_get_reg(&cursor, UNW_ARM64_X1, &exc->private_[3]); #endif - unw_get_reg(&cursor, UNW_REG_IP, &target); + __unw_get_reg(&cursor, UNW_REG_IP, &target); ms_exc->ExceptionCode = STATUS_GCC_UNWIND; #ifdef __x86_64__ ms_exc->ExceptionInformation[2] = disp->TargetIp; @@ -199,7 +204,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, } } -/// Personality function returned by \c unw_get_proc_info() in SEH contexts. +/// 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()). @@ -207,6 +212,8 @@ 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; @@ -215,7 +222,8 @@ __libunwind_seh_personality(int version, _Unwind_Action state, 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); + 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, @@ -234,15 +242,15 @@ 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); + __unw_init_local(&cursor2, uc); // Walk each frame until we reach where search phase said to stop - while (unw_step(&cursor2) > 0) { + 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 " + 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; @@ -253,8 +261,8 @@ unwind_phase2_forced(unw_context_t *uc, char functionBuf[512]; const char *functionName = functionBuf; unw_word_t offset; - if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || + if ((__unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf), + &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip)) functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( @@ -304,7 +312,7 @@ unwind_phase2_forced(unw_context_t *uc, "_URC_INSTALL_CONTEXT", (void *)exception_object); // We may get control back if landing pad calls _Unwind_Resume(). - unw_resume(&cursor2); + __unw_resume(&cursor2); break; default: // Personality routine returned an unknown result code. @@ -369,7 +377,7 @@ _Unwind_Resume(_Unwind_Exception *exception_object) { if (exception_object->private_[0] != 0) { unw_context_t uc; - unw_getcontext(&uc); + __unw_getcontext(&uc); unwind_phase2_forced(&uc, exception_object, (_Unwind_Stop_Fn) exception_object->private_[0], (void *)exception_object->private_[4]); @@ -407,7 +415,7 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", (void *)exception_object, (void *)(uintptr_t)stop); unw_context_t uc; - unw_getcontext(&uc); + __unw_getcontext(&uc); // Mark that this is a forced unwind, so _Unwind_Resume() can do // the right thing. @@ -421,7 +429,8 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, /// 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; + 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); @@ -432,30 +441,32 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { /// function. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) { - DISPATCHER_CONTEXT *disp = _unw_seh_get_disp_ctx((unw_cursor_t *)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) { +static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { #ifdef _LIBUNWIND_TARGET_X86_64 - new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>( - context, LocalAddressSpace::sThisAddressSpace); + 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 ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>( - context, LocalAddressSpace::sThisAddressSpace); + 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 ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>( - context, LocalAddressSpace::sThisAddressSpace); + 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; @@ -464,8 +475,7 @@ _unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { #endif } -static DISPATCHER_CONTEXT * -_unw_seh_get_disp_ctx(unw_cursor_t *cursor) { +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) @@ -477,8 +487,8 @@ _unw_seh_get_disp_ctx(unw_cursor_t *cursor) { #endif } -static void -_unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp) { +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) diff --git a/src/Unwind-sjlj.c b/src/Unwind-sjlj.c index 90cac3f8c763..b8bb7c83bdff 100644 --- a/src/Unwind-sjlj.c +++ b/src/Unwind-sjlj.c @@ -1,9 +1,8 @@ //===--------------------------- Unwind-sjlj.c ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 @@ -12,6 +11,7 @@ #include <unwind.h> +#include <inttypes.h> #include <stdint.h> #include <stdbool.h> #include <stdlib.h> @@ -52,7 +52,7 @@ struct _Unwind_FunctionContext { #else # if __STDC_VERSION__ >= 201112L # define _LIBUNWIND_THREAD_LOCAL _Thread_local -# elif defined(_WIN32) +# elif defined(_MSC_VER) # define _LIBUNWIND_THREAD_LOCAL __declspec(thread) # elif defined(__GNUC__) || defined(__clang__) # define _LIBUNWIND_THREAD_LOCAL __thread @@ -108,7 +108,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", 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) { @@ -117,17 +118,18 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { if (c == NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): reached " "bottom => _URC_END_OF_STACK", - exception_object); + (void *)exception_object); return _URC_END_OF_STACK; } - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", 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", - exception_object, 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); @@ -138,12 +140,14 @@ 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", 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", exception_object); + "_URC_CONTINUE_UNWIND", + (void *)exception_object); // continue unwinding break; @@ -151,7 +155,7 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { // something went wrong _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", - exception_object); + (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } } @@ -162,19 +166,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)", 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", - exception_object, c); + (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", - 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; } @@ -194,7 +200,7 @@ unwind_phase2(struct _Unwind_Exception *exception_object) { // continue unwinding _LIBUNWIND_TRACE_UNWINDING( "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", - exception_object); + (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 " @@ -203,14 +209,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", - 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 @@ -237,9 +243,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", - 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; } @@ -251,11 +258,11 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, (struct _Unwind_Context *)c, stop_parameter); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "stop function returned %d", - exception_object, stopResult); + (void *)exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "stopped by stop function", - exception_object); + (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -264,7 +271,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, __personality_routine p = (__personality_routine) c->personality; _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "calling personality function %p", - exception_object, p); + (void *)exception_object, (void *)p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)c); @@ -272,13 +279,13 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned _URC_CONTINUE_UNWIND", - exception_object); + (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", - exception_object); + (void *)exception_object); // we may get control back if landing pad calls _Unwind_Resume() __Unwind_SjLj_SetTopOfFunctionStack(c); __builtin_longjmp(c->jbuf, 1); @@ -288,7 +295,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned %d, " "_URC_FATAL_PHASE2_ERROR", - exception_object, personalityResult); + (void *)exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } } @@ -298,8 +305,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", - 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, @@ -314,7 +321,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)", 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 @@ -344,7 +352,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)", 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, @@ -362,8 +371,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=%ld", - 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. @@ -386,7 +395,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%0lX", context, ufc->lsda); + "=> 0x%" PRIuPTR, + (void *)context, ufc->lsda); return ufc->lsda; } @@ -394,8 +404,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)", - 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]; } @@ -404,8 +414,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%0lX)" - , 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; } @@ -414,8 +425,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%lX", context, - ufc->resumeLocation + 1); + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIu32, + (void *)context, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -427,8 +438,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%lX", - context, 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; } @@ -436,8 +448,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%0lX)", - 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; } @@ -449,7 +461,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)", context); + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", (void *)context); return 0; } @@ -459,7 +471,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { _LIBUNWIND_EXPORT void _Unwind_DeleteException(struct _Unwind_Exception *exception_object) { _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", - exception_object); + (void *)exception_object); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object); @@ -473,7 +485,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)", context); + _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); } @@ -484,14 +496,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)", 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)", 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. diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp index 52439f9b5453..a96c9f39958d 100644 --- a/src/UnwindCursor.hpp +++ b/src/UnwindCursor.hpp @@ -1,9 +1,8 @@ //===------------------------- UnwindCursor.hpp ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 @@ -12,7 +11,6 @@ #ifndef __UNWINDCURSOR_HPP__ #define __UNWINDCURSOR_HPP__ -#include <algorithm> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -106,7 +104,6 @@ private: static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); static bool _registeredForDyldUnloads; #endif - // Can't use std::vector<> here because this code is below libc++. static entry *_buffer; static entry *_bufferUsed; static entry *_bufferEnd; @@ -485,6 +482,10 @@ public: 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; } @@ -789,6 +790,8 @@ bool UnwindCursor<A, R>::validFloatReg(int regNum) { if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true; #elif defined(_LIBUNWIND_TARGET_AARCH64) if (regNum >= UNW_ARM64_D0 && regNum <= UNW_ARM64_D31) return true; +#else + (void)regNum; #endif return false; } @@ -816,6 +819,7 @@ unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { #elif defined(_LIBUNWIND_TARGET_AARCH64) return _msContext.V[regNum - UNW_ARM64_D0].D[0]; #else + (void)regNum; _LIBUNWIND_ABORT("float registers unimplemented"); #endif } @@ -843,6 +847,8 @@ void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { #elif defined(_LIBUNWIND_TARGET_AARCH64) _msContext.V[regNum - UNW_ARM64_D0].D[0] = value; #else + (void)regNum; + (void)value; _LIBUNWIND_ABORT("float registers unimplemented"); #endif } @@ -892,6 +898,10 @@ public: virtual void saveVFPAsX(); #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; } + private: #if defined(_LIBUNWIND_ARM_EHABI) @@ -1221,7 +1231,6 @@ template<typename A> struct EHABISectionIterator { typedef EHABISectionIterator _Self; - typedef std::random_access_iterator_tag iterator_category; typedef typename A::pint_t value_type; typedef typename A::pint_t* pointer; typedef typename A::pint_t& reference; @@ -1275,6 +1284,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; +} + +} + template <typename A, typename R> bool UnwindCursor<A, R>::getInfoFromEHABISection( pint_t pc, @@ -1286,7 +1318,7 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( if (begin == end) return false; - EHABISectionIterator<A> itNextPC = std::upper_bound(begin, end, pc); + EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc); if (itNextPC == begin) return false; EHABISectionIterator<A> itThisPC = itNextPC - 1; @@ -1296,8 +1328,7 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( // 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) ? std::numeric_limits<pint_t>::max() - : itNextPC.functionAddress(); + pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress(); pint_t indexDataAddr = itThisPC.dataAddress(); if (indexDataAddr == 0) @@ -1709,7 +1740,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, --personalityIndex; // change 1-based to zero-based index if (personalityIndex > sectionHeader.personalityArrayCount()) { _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, " - "but personality table has only %d entires", + "but personality table has only %d entries", encoding, personalityIndex, sectionHeader.personalityArrayCount()); return false; diff --git a/src/UnwindLevel1-gcc-ext.c b/src/UnwindLevel1-gcc-ext.c index 1c6626585465..63e4083a4579 100644 --- a/src/UnwindLevel1-gcc-ext.c +++ b/src/UnwindLevel1-gcc-ext.c @@ -1,9 +1,8 @@ //===--------------------- UnwindLevel1-gcc-ext.c -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -94,10 +93,10 @@ _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(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); - if (unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) + __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; @@ -109,8 +108,8 @@ _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)", (void *)(uintptr_t)callback); @@ -129,7 +128,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { #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", _URC_END_OF_STACK); @@ -138,7 +137,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { #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; } @@ -165,8 +164,8 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { 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, @@ -192,10 +191,10 @@ _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; @@ -209,7 +208,7 @@ _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); + __unw_get_reg(cursor, UNW_REG_SP, &result); _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIxPTR, (void *)context, result); return (uintptr_t)result; @@ -234,7 +233,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, /// 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); + __unw_add_dynamic_fde((unw_word_t)(uintptr_t)fde); } @@ -244,7 +243,7 @@ _LIBUNWIND_EXPORT void __register_frame(const void *fde) { /// 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); + __unw_remove_dynamic_fde((unw_word_t)(uintptr_t)fde); } diff --git a/src/UnwindLevel1.c b/src/UnwindLevel1.c index 0a04438bba2f..bcb1a7fbec2a 100644 --- a/src/UnwindLevel1.c +++ b/src/UnwindLevel1.c @@ -1,13 +1,12 @@ //===------------------------- UnwindLevel1.c -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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: -// http://mentorembedded.github.io/cxx-abi/abi-eh.html +// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html // using libunwind // //===----------------------------------------------------------------------===// @@ -26,9 +25,10 @@ #include <stdio.h> #include <string.h> +#include "config.h" #include "libunwind.h" +#include "libunwind_ext.h" #include "unwind.h" -#include "config.h" #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) @@ -36,33 +36,36 @@ static _Unwind_Reason_Code unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { - unw_init_local(cursor, uc); + __unw_init_local(cursor, uc); // Walk each frame looking for a place to stop. bool handlerNotFound = true; while (handlerNotFound) { // 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; } // 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; } @@ -71,12 +74,12 @@ 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 "", @@ -100,7 +103,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // found a catch clause or locals that need destructing in this frame // stop search and remember stack pointer at the frame handlerNotFound = false; - 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", @@ -129,7 +132,7 @@ 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); + __unw_init_local(cursor, uc); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", (void *)exception_object); @@ -139,27 +142,30 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // 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; } @@ -168,8 +174,8 @@ 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 @@ -212,15 +218,15 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // 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, (void *)exception_object, pc, sp); } - 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; default: // Personality routine returned an unknown result code. @@ -240,15 +246,15 @@ static _Unwind_Reason_Code 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); // 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 " + 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; @@ -259,8 +265,8 @@ 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( @@ -310,7 +316,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, "_URC_INSTALL_CONTEXT", (void *)exception_object); // We may get control back if landing pad calls _Unwind_Resume(). - unw_resume(cursor); + __unw_resume(cursor); break; default: // Personality routine returned an unknown result code. @@ -346,7 +352,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { (void *)exception_object); unw_context_t uc; unw_cursor_t cursor; - unw_getcontext(&uc); + __unw_getcontext(&uc); // Mark that this is a non-forced unwind, so _Unwind_Resume() // can do the right thing. @@ -380,7 +386,7 @@ _Unwind_Resume(_Unwind_Exception *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_getcontext(&uc); if (exception_object->private_1 != 0) unwind_phase2_forced(&uc, &cursor, exception_object, @@ -405,7 +411,7 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, (void *)exception_object, (void *)(uintptr_t)stop); unw_context_t uc; unw_cursor_t cursor; - unw_getcontext(&uc); + __unw_getcontext(&uc); // Mark that this is a forced unwind, so _Unwind_Resume() can do // the right thing. @@ -423,7 +429,7 @@ _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, @@ -444,7 +450,7 @@ _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, (void *)context, result); @@ -469,7 +475,7 @@ _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); + __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; @@ -482,14 +488,14 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, ")", (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); + __unw_get_reg(cursor, UNW_REG_IP, &result); _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, (void *)context, result); return (uintptr_t)result; @@ -503,7 +509,7 @@ _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, _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__) diff --git a/src/UnwindRegistersRestore.S b/src/UnwindRegistersRestore.S index 389db67579cd..8122bf3e1b2e 100644 --- a/src/UnwindRegistersRestore.S +++ b/src/UnwindRegistersRestore.S @@ -1,9 +1,8 @@ //===-------------------- UnwindRegistersRestore.S ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -14,7 +13,7 @@ #if !defined(__USING_SJLJ_EXCEPTIONS__) #if defined(__i386__) -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) # # void libunwind::Registers_x86::jumpto() # @@ -61,7 +60,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) #elif defined(__x86_64__) -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) # # void libunwind::Registers_x86_64::jumpto() # @@ -130,7 +129,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) #elif defined(__powerpc64__) -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) // // void libunwind::Registers_ppc64::jumpto() // @@ -395,120 +394,120 @@ Lnovec: #elif defined(__ppc__) -DEFINE_LIBUNWIND_PRIVATE_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 r2, 16(r3) - ; skip r3 for now - ; skip r4 for now - ; skip r5 for now - lwz r6, 32(r3) - lwz r7, 36(r3) - lwz r8, 40(r3) - lwz r9, 44(r3) - lwz r10, 48(r3) - lwz r11, 52(r3) - lwz r12, 56(r3) - lwz r13, 60(r3) - lwz r14, 64(r3) - lwz r15, 68(r3) - lwz r16, 72(r3) - lwz r17, 76(r3) - lwz r18, 80(r3) - lwz r19, 84(r3) - lwz r20, 88(r3) - lwz r21, 92(r3) - lwz r22, 96(r3) - lwz r23,100(r3) - lwz r24,104(r3) - lwz r25,108(r3) - lwz r26,112(r3) - lwz r27,116(r3) - lwz r28,120(r3) - lwz r29,124(r3) - lwz r30,128(r3) - lwz r31,132(r3) - - ; restore float registers - lfd f0, 160(r3) - lfd f1, 168(r3) - lfd f2, 176(r3) - lfd f3, 184(r3) - lfd f4, 192(r3) - lfd f5, 200(r3) - lfd f6, 208(r3) - lfd f7, 216(r3) - lfd f8, 224(r3) - lfd f9, 232(r3) - lfd f10,240(r3) - lfd f11,248(r3) - lfd f12,256(r3) - lfd f13,264(r3) - lfd f14,272(r3) - lfd f15,280(r3) - lfd f16,288(r3) - lfd f17,296(r3) - lfd f18,304(r3) - lfd f19,312(r3) - lfd f20,320(r3) - lfd f21,328(r3) - lfd f22,336(r3) - lfd f23,344(r3) - lfd f24,352(r3) - lfd f25,360(r3) - lfd f26,368(r3) - lfd f27,376(r3) - lfd f28,384(r3) - lfd f29,392(r3) - lfd f30,400(r3) - lfd f31,408(r3) - - ; restore vector registers if any are in use - lwz r5,156(r3) ; test VRsave - cmpwi r5,0 - beq Lnovec - - subi r4,r1,16 - rlwinm r4,r4,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 +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 %r2, 16(%r3) + // skip r3 for now + // skip r4 for now + // skip r5 for now + lwz %r6, 32(%r3) + lwz %r7, 36(%r3) + lwz %r8, 40(%r3) + lwz %r9, 44(%r3) + lwz %r10, 48(%r3) + lwz %r11, 52(%r3) + lwz %r12, 56(%r3) + lwz %r13, 60(%r3) + lwz %r14, 64(%r3) + lwz %r15, 68(%r3) + lwz %r16, 72(%r3) + lwz %r17, 76(%r3) + lwz %r18, 80(%r3) + lwz %r19, 84(%r3) + lwz %r20, 88(%r3) + lwz %r21, 92(%r3) + lwz %r22, 96(%r3) + lwz %r23,100(%r3) + lwz %r24,104(%r3) + lwz %r25,108(%r3) + lwz %r26,112(%r3) + lwz %r27,116(%r3) + lwz %r28,120(%r3) + lwz %r29,124(%r3) + lwz %r30,128(%r3) + lwz %r31,132(%r3) + + // restore float registers + lfd %f0, 160(%r3) + lfd %f1, 168(%r3) + lfd %f2, 176(%r3) + lfd %f3, 184(%r3) + lfd %f4, 192(%r3) + lfd %f5, 200(%r3) + lfd %f6, 208(%r3) + lfd %f7, 216(%r3) + lfd %f8, 224(%r3) + lfd %f9, 232(%r3) + lfd %f10,240(%r3) + lfd %f11,248(%r3) + lfd %f12,256(%r3) + lfd %f13,264(%r3) + lfd %f14,272(%r3) + lfd %f15,280(%r3) + lfd %f16,288(%r3) + lfd %f17,296(%r3) + lfd %f18,304(%r3) + lfd %f19,312(%r3) + lfd %f20,320(%r3) + lfd %f21,328(%r3) + lfd %f22,336(%r3) + lfd %f23,344(%r3) + lfd %f24,352(%r3) + lfd %f25,360(%r3) + lfd %f26,368(%r3) + lfd %f27,376(%r3) + lfd %f28,384(%r3) + lfd %f29,392(%r3) + lfd %f30,400(%r3) + lfd %f31,408(%r3) + // restore vector registers if any are in use + lwz %r5, 156(%r3) // test VRsave + cmpwi %r5, 0 + beq Lnovec + + subi %r4, %r1, 16 + rlwinm %r4, %r4, 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 + #define LOAD_VECTOR_UNALIGNEDl(_index) \ - andis. r0,r5,(1<<(15-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ -Ldone ## _index: + andis. %r0, %r5, (1<<(15-_index)) SEPARATOR \ + beq Ldone ## _index SEPARATOR \ + lwz %r0, 424+_index*16(%r3) SEPARATOR \ + stw %r0, 0(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ + stw %r0, 4(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ + stw %r0, 8(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ + stw %r0, 12(%r4) SEPARATOR \ + lvx %v ## _index, 0, %r4 SEPARATOR \ + Ldone ## _index: #define LOAD_VECTOR_UNALIGNEDh(_index) \ - andi. r0,r5,(1<<(31-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ - Ldone ## _index: + andi. %r0, %r5, (1<<(31-_index)) SEPARATOR \ + beq Ldone ## _index SEPARATOR \ + lwz %r0, 424+_index*16(%r3) SEPARATOR \ + stw %r0, 0(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ + stw %r0, 4(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ + stw %r0, 8(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ + stw %r0, 12(%r4) SEPARATOR \ + lvx %v ## _index, 0, %r4 SEPARATOR \ + Ldone ## _index: LOAD_VECTOR_UNALIGNEDl(0) @@ -545,17 +544,17 @@ Ldone ## _index: LOAD_VECTOR_UNALIGNEDh(31) Lnovec: - lwz r0, 136(r3) ; __cr - mtocrf 255,r0 - lwz r0, 148(r3) ; __ctr - mtctr r0 - lwz r0, 0(r3) ; __ssr0 - mtctr r0 - lwz r0, 8(r3) ; do r0 now - lwz r5,28(r3) ; do r5 now - lwz r4,24(r3) ; do r4 now - lwz r1,12(r3) ; do sp now - lwz r3,20(r3) ; do r3 last + lwz %r0, 136(%r3) // __cr + mtcr %r0 + lwz %r0, 148(%r3) // __ctr + mtctr %r0 + lwz %r0, 0(%r3) // __ssr0 + mtctr %r0 + lwz %r0, 8(%r3) // do r0 now + lwz %r5, 28(%r3) // do r5 now + lwz %r4, 24(%r3) // do r4 now + lwz %r1, 12(%r3) // do sp now + lwz %r3, 20(%r3) // do r3 last bctr #elif defined(__arm64__) || defined(__aarch64__) @@ -567,7 +566,7 @@ Lnovec: // thread_state pointer is in x0 // .p2align 2 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) // skip restore of x0,x1 for now ldp x2, x3, [x0, #0x010] ldp x4, x5, [x0, #0x020] @@ -576,7 +575,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) ldp x10,x11, [x0, #0x050] ldp x12,x13, [x0, #0x060] ldp x14,x15, [x0, #0x070] - ldp x16,x17, [x0, #0x080] + // 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] @@ -584,8 +584,6 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) ldp x26,x27, [x0, #0x0D0] ldp x28,x29, [x0, #0x0E0] ldr x30, [x0, #0x100] // restore pc into lr - ldr x1, [x0, #0x0F8] - mov sp,x1 // restore sp ldp d0, d1, [x0, #0x110] ldp d2, d3, [x0, #0x120] @@ -605,12 +603,21 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) 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] ldp x0, x1, [x0, #0x000] // restore x0,x1 + 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 .thumb #endif @@ -621,7 +628,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) @ thread_state pointer is in r0 @ .p2align 2 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) +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 @@ -659,7 +666,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJu #if defined(__ELF__) .fpu vfpv3-d16 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy) +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 @@ -680,7 +687,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL #if defined(__ELF__) .fpu vfpv3-d16 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPv) vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia JMP(lr) @@ -694,7 +701,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL #if defined(__ELF__) .fpu vfpv3 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPv) vldmia r0, {d16-d31} JMP(lr) @@ -710,7 +717,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy) #if defined(__ELF__) .arch armv5te #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy) +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 @@ -739,7 +746,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy) #if defined(__ELF__) .arch armv5te #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) +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 @@ -750,7 +757,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXCont #elif defined(__or1k__) -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # # void libunwind::Registers_or1k::jumpto() # @@ -809,7 +816,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) .set push .set noat .set noreorder @@ -918,7 +925,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder @@ -1008,7 +1015,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) // On entry: // thread_state pointer is in o0 // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) ta 3 ldd [%o0 + 64], %l0 ldd [%o0 + 72], %l2 diff --git a/src/UnwindRegistersSave.S b/src/UnwindRegistersSave.S index 48ecb0aec70f..54505e53bac7 100644 --- a/src/UnwindRegistersSave.S +++ b/src/UnwindRegistersSave.S @@ -1,9 +1,8 @@ //===------------------------ UnwindRegistersSave.S -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -16,7 +15,7 @@ #if defined(__i386__) # -# extern int unw_getcontext(unw_context_t* thread_state) +# extern int __unw_getcontext(unw_context_t* thread_state) # # On entry: # + + @@ -27,7 +26,7 @@ # +-----------------------+ <-- SP # + + # -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) push %eax movl 8(%esp), %eax movl %ebx, 4(%eax) @@ -57,12 +56,12 @@ 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) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #if defined(_WIN64) #define PTR %rcx #define TMP %rdx @@ -119,12 +118,12 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 # -# 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 a0 ($4) # -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) .set push .set noat .set noreorder @@ -228,12 +227,12 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #elif defined(__mips64) # -# 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 a0 ($4) # -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) .set push .set noat .set noreorder @@ -318,21 +317,21 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) # 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) +// 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) // store register (GPR) #define PPC64_STR(n) \ @@ -557,157 +556,157 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #elif defined(__ppc__) -; -; extern int unw_getcontext(unw_context_t* thread_state) -; -; On entry: -; thread_state pointer is in r3 -; -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - stw r0, 8(r3) - mflr r0 - stw r0, 0(r3) ; store lr as ssr0 - stw r1, 12(r3) - stw r2, 16(r3) - stw r3, 20(r3) - stw r4, 24(r3) - stw r5, 28(r3) - stw r6, 32(r3) - stw r7, 36(r3) - stw r8, 40(r3) - stw r9, 44(r3) - stw r10, 48(r3) - stw r11, 52(r3) - stw r12, 56(r3) - stw r13, 60(r3) - stw r14, 64(r3) - stw r15, 68(r3) - stw r16, 72(r3) - stw r17, 76(r3) - stw r18, 80(r3) - stw r19, 84(r3) - stw r20, 88(r3) - stw r21, 92(r3) - stw r22, 96(r3) - stw r23,100(r3) - stw r24,104(r3) - stw r25,108(r3) - stw r26,112(r3) - stw r27,116(r3) - stw r28,120(r3) - stw r29,124(r3) - stw r30,128(r3) - stw r31,132(r3) - - ; save VRSave register - mfspr r0,256 - stw r0,156(r3) - ; save CR registers - mfcr r0 - stw r0,136(r3) - ; save CTR register - mfctr r0 - stw r0,148(r3) - - ; save float registers - stfd f0, 160(r3) - stfd f1, 168(r3) - stfd f2, 176(r3) - stfd f3, 184(r3) - stfd f4, 192(r3) - stfd f5, 200(r3) - stfd f6, 208(r3) - stfd f7, 216(r3) - stfd f8, 224(r3) - stfd f9, 232(r3) - stfd f10,240(r3) - stfd f11,248(r3) - stfd f12,256(r3) - stfd f13,264(r3) - stfd f14,272(r3) - stfd f15,280(r3) - stfd f16,288(r3) - stfd f17,296(r3) - stfd f18,304(r3) - stfd f19,312(r3) - stfd f20,320(r3) - stfd f21,328(r3) - stfd f22,336(r3) - stfd f23,344(r3) - stfd f24,352(r3) - stfd f25,360(r3) - stfd f26,368(r3) - stfd f27,376(r3) - stfd f28,384(r3) - stfd f29,392(r3) - stfd f30,400(r3) - stfd f31,408(r3) - - - ; save vector registers - - subi r4,r1,16 - rlwinm r4,r4,0,0,27 ; mask low 4-bits - ; r4 is now a 16-byte aligned pointer into the red zone +// +// extern int unw_getcontext(unw_context_t* thread_state) +// +// On entry: +// thread_state pointer is in r3 +// +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + stw %r0, 8(%r3) + mflr %r0 + stw %r0, 0(%r3) // store lr as ssr0 + stw %r1, 12(%r3) + stw %r2, 16(%r3) + stw %r3, 20(%r3) + stw %r4, 24(%r3) + stw %r5, 28(%r3) + stw %r6, 32(%r3) + stw %r7, 36(%r3) + stw %r8, 40(%r3) + stw %r9, 44(%r3) + stw %r10, 48(%r3) + stw %r11, 52(%r3) + stw %r12, 56(%r3) + stw %r13, 60(%r3) + stw %r14, 64(%r3) + stw %r15, 68(%r3) + stw %r16, 72(%r3) + stw %r17, 76(%r3) + stw %r18, 80(%r3) + stw %r19, 84(%r3) + stw %r20, 88(%r3) + stw %r21, 92(%r3) + stw %r22, 96(%r3) + stw %r23,100(%r3) + stw %r24,104(%r3) + stw %r25,108(%r3) + stw %r26,112(%r3) + stw %r27,116(%r3) + stw %r28,120(%r3) + stw %r29,124(%r3) + stw %r30,128(%r3) + stw %r31,132(%r3) + + // save VRSave register + mfspr %r0, 256 + stw %r0, 156(%r3) + // save CR registers + mfcr %r0 + stw %r0, 136(%r3) + // save CTR register + mfctr %r0 + stw %r0, 148(%r3) + + // save float registers + stfd %f0, 160(%r3) + stfd %f1, 168(%r3) + stfd %f2, 176(%r3) + stfd %f3, 184(%r3) + stfd %f4, 192(%r3) + stfd %f5, 200(%r3) + stfd %f6, 208(%r3) + stfd %f7, 216(%r3) + stfd %f8, 224(%r3) + stfd %f9, 232(%r3) + stfd %f10,240(%r3) + stfd %f11,248(%r3) + stfd %f12,256(%r3) + stfd %f13,264(%r3) + stfd %f14,272(%r3) + stfd %f15,280(%r3) + stfd %f16,288(%r3) + stfd %f17,296(%r3) + stfd %f18,304(%r3) + stfd %f19,312(%r3) + stfd %f20,320(%r3) + stfd %f21,328(%r3) + stfd %f22,336(%r3) + stfd %f23,344(%r3) + stfd %f24,352(%r3) + stfd %f25,360(%r3) + stfd %f26,368(%r3) + stfd %f27,376(%r3) + stfd %f28,384(%r3) + stfd %f29,392(%r3) + stfd %f30,400(%r3) + stfd %f31,408(%r3) + + + // save vector registers + + subi %r4, %r1, 16 + rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits + // r4 is now a 16-byte aligned pointer into the red zone #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ - stvx _vec,0,r4 @\ - lwz r5, 0(r4) @\ - stw r5, _offset(r3) @\ - lwz r5, 4(r4) @\ - stw r5, _offset+4(r3) @\ - lwz r5, 8(r4) @\ - stw r5, _offset+8(r3) @\ - lwz r5, 12(r4) @\ - stw r5, _offset+12(r3) - - SAVE_VECTOR_UNALIGNED( v0, 424+0x000) - SAVE_VECTOR_UNALIGNED( v1, 424+0x010) - SAVE_VECTOR_UNALIGNED( v2, 424+0x020) - SAVE_VECTOR_UNALIGNED( v3, 424+0x030) - SAVE_VECTOR_UNALIGNED( v4, 424+0x040) - SAVE_VECTOR_UNALIGNED( v5, 424+0x050) - SAVE_VECTOR_UNALIGNED( v6, 424+0x060) - SAVE_VECTOR_UNALIGNED( v7, 424+0x070) - SAVE_VECTOR_UNALIGNED( v8, 424+0x080) - SAVE_VECTOR_UNALIGNED( v9, 424+0x090) - SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0) - SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0) - SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0) - SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0) - SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0) - SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0) - SAVE_VECTOR_UNALIGNED(v16, 424+0x100) - SAVE_VECTOR_UNALIGNED(v17, 424+0x110) - SAVE_VECTOR_UNALIGNED(v18, 424+0x120) - SAVE_VECTOR_UNALIGNED(v19, 424+0x130) - SAVE_VECTOR_UNALIGNED(v20, 424+0x140) - SAVE_VECTOR_UNALIGNED(v21, 424+0x150) - SAVE_VECTOR_UNALIGNED(v22, 424+0x160) - SAVE_VECTOR_UNALIGNED(v23, 424+0x170) - SAVE_VECTOR_UNALIGNED(v24, 424+0x180) - SAVE_VECTOR_UNALIGNED(v25, 424+0x190) - SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0) - SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0) - SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0) - SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0) - SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0) - SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0) - - li r3, 0 ; return UNW_ESUCCESS + stvx _vec, 0, %r4 SEPARATOR \ + lwz %r5, 0(%r4) SEPARATOR \ + stw %r5, _offset(%r3) SEPARATOR \ + lwz %r5, 4(%r4) SEPARATOR \ + stw %r5, _offset+4(%r3) SEPARATOR \ + lwz %r5, 8(%r4) SEPARATOR \ + stw %r5, _offset+8(%r3) SEPARATOR \ + lwz %r5, 12(%r4) SEPARATOR \ + stw %r5, _offset+12(%r3) + + SAVE_VECTOR_UNALIGNED( %v0, 424+0x000) + SAVE_VECTOR_UNALIGNED( %v1, 424+0x010) + SAVE_VECTOR_UNALIGNED( %v2, 424+0x020) + SAVE_VECTOR_UNALIGNED( %v3, 424+0x030) + SAVE_VECTOR_UNALIGNED( %v4, 424+0x040) + SAVE_VECTOR_UNALIGNED( %v5, 424+0x050) + SAVE_VECTOR_UNALIGNED( %v6, 424+0x060) + SAVE_VECTOR_UNALIGNED( %v7, 424+0x070) + SAVE_VECTOR_UNALIGNED( %v8, 424+0x080) + SAVE_VECTOR_UNALIGNED( %v9, 424+0x090) + SAVE_VECTOR_UNALIGNED(%v10, 424+0x0A0) + SAVE_VECTOR_UNALIGNED(%v11, 424+0x0B0) + SAVE_VECTOR_UNALIGNED(%v12, 424+0x0C0) + SAVE_VECTOR_UNALIGNED(%v13, 424+0x0D0) + SAVE_VECTOR_UNALIGNED(%v14, 424+0x0E0) + SAVE_VECTOR_UNALIGNED(%v15, 424+0x0F0) + SAVE_VECTOR_UNALIGNED(%v16, 424+0x100) + SAVE_VECTOR_UNALIGNED(%v17, 424+0x110) + SAVE_VECTOR_UNALIGNED(%v18, 424+0x120) + SAVE_VECTOR_UNALIGNED(%v19, 424+0x130) + SAVE_VECTOR_UNALIGNED(%v20, 424+0x140) + SAVE_VECTOR_UNALIGNED(%v21, 424+0x150) + SAVE_VECTOR_UNALIGNED(%v22, 424+0x160) + SAVE_VECTOR_UNALIGNED(%v23, 424+0x170) + SAVE_VECTOR_UNALIGNED(%v24, 424+0x180) + SAVE_VECTOR_UNALIGNED(%v25, 424+0x190) + SAVE_VECTOR_UNALIGNED(%v26, 424+0x1A0) + SAVE_VECTOR_UNALIGNED(%v27, 424+0x1B0) + SAVE_VECTOR_UNALIGNED(%v28, 424+0x1C0) + SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0) + SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0) + SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0) + + li %r3, 0 // return UNW_ESUCCESS blr #elif defined(__arm64__) || 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] @@ -751,11 +750,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 .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 @@ -764,10 +766,10 @@ 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) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 stm r0!, {r0-r7} mov r1, r8 @@ -808,7 +810,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #if defined(__ELF__) .fpu vfpv3-d16 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) vstmia r0, {d0-d15} JMP(lr) @@ -822,7 +824,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMD #if defined(__ELF__) .fpu vfpv3-d16 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy) +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia JMP(lr) @@ -836,7 +838,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMX #if defined(__ELF__) .fpu vfpv3 #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy) +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 @@ -859,7 +861,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy) #if defined(__ELF__) .arch armv5te #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy) +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 @@ -888,7 +890,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy) #if defined(__ELF__) .arch armv5te #endif -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) +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 @@ -900,12 +902,12 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControl #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 @@ -946,12 +948,12 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #elif defined(__sparc__) # -# 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 o0 # -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) ta 3 add %o7, 8, %o7 std %g0, [%o0 + 0] @@ -973,6 +975,9 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) jmp %o7 clr %o0 // return UNW_ESUCCESS #endif + + WEAK_ALIAS(__unw_getcontext, unw_getcontext) + #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ NO_EXEC_STACK_DIRECTIVE diff --git a/src/Unwind_AppleExtras.cpp b/src/Unwind_AppleExtras.cpp index 39f379c5298c..248d99570e94 100644 --- a/src/Unwind_AppleExtras.cpp +++ b/src/Unwind_AppleExtras.cpp @@ -1,9 +1,8 @@ //===--------------------- Unwind_AppleExtras.cpp -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // // //===----------------------------------------------------------------------===// diff --git a/src/assembly.h b/src/assembly.h index 2df930214fae..7132b6c561b0 100644 --- a/src/assembly.h +++ b/src/assembly.h @@ -1,9 +1,8 @@ /* ===-- assembly.h - libUnwind assembler support macros -------------------=== * - * The LLVM Compiler Infrastructure - * - * This file is dual licensed under the MIT and the University of Illinois Open - * Source Licenses. See LICENSE.TXT for details. + * 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 * * ===----------------------------------------------------------------------=== * @@ -29,14 +28,26 @@ #ifdef _ARCH_PWR8 #define PPC64_HAS_VMX #endif -#elif defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) -#define SEPARATOR @ #elif defined(__arm64__) #define SEPARATOR %% #else #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: +#else +#define PPC64_OPD1 +#define PPC64_OPD2 +#endif + #define GLUE2(a, b) a ## b #define GLUE(a, b) GLUE2(a, b) #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) @@ -46,6 +57,12 @@ #define SYMBOL_IS_FUNC(name) #define EXPORT_SYMBOL(name) #define HIDDEN_SYMBOL(name) .private_extern name +#define WEAK_SYMBOL(name) .weak_reference name +#define WEAK_ALIAS(name, aliasname) \ + .globl SYMBOL_NAME(aliasname) SEPARATOR \ + WEAK_SYMBOL(aliasname) SEPARATOR \ + SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) + #define NO_EXEC_STACK_DIRECTIVE #elif defined(__ELF__) @@ -57,6 +74,10 @@ #endif #define EXPORT_SYMBOL(name) #define HIDDEN_SYMBOL(name) .hidden name +#define WEAK_SYMBOL(name) .weak name +#define WEAK_ALIAS(name, aliasname) \ + WEAK_SYMBOL(aliasname) SEPARATOR \ + SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ defined(__linux__) @@ -72,9 +93,9 @@ .scl 2 SEPARATOR \ .type 32 SEPARATOR \ .endef -#define EXPORT_SYMBOL2(name) \ - .section .drectve,"yn" SEPARATOR \ - .ascii "-export:", #name, "\0" SEPARATOR \ +#define EXPORT_SYMBOL2(name) \ + .section .drectve,"yn" SEPARATOR \ + .ascii "-export:", #name, "\0" SEPARATOR \ .text #if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS) #define EXPORT_SYMBOL(name) @@ -83,6 +104,23 @@ #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__) @@ -93,17 +131,13 @@ #endif -#define DEFINE_LIBUNWIND_FUNCTION(name) \ - .globl SYMBOL_NAME(name) SEPARATOR \ - EXPORT_SYMBOL(name) SEPARATOR \ - SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): - -#define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \ - .globl SYMBOL_NAME(name) SEPARATOR \ - HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): +#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 #if defined(__arm__) #if !defined(__ARM_ARCH) diff --git a/src/config.h b/src/config.h index fc7fd646707e..09bb261647ca 100644 --- a/src/config.h +++ b/src/config.h @@ -1,9 +1,8 @@ //===----------------------------- config.h -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -63,6 +62,35 @@ #endif #endif +#define STR(a) #a +#define XSTR(a) STR(a) +#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name + +#if defined(__APPLE__) +#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ + __asm__(".globl " SYMBOL_NAME(aliasname)); \ + __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ + extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ + __attribute__((weak_import)); +#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 + #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) #define _LIBUNWIND_BUILD_SJLJ_APIS #endif diff --git a/src/dwarf2.h b/src/dwarf2.h index 58525eea044e..40f0daf46805 100644 --- a/src/dwarf2.h +++ b/src/dwarf2.h @@ -1,9 +1,8 @@ //===------------------------------- dwarf2.h -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/src/libunwind.cpp b/src/libunwind.cpp index f4d71a1863bf..c90032bd66c9 100644 --- a/src/libunwind.cpp +++ b/src/libunwind.cpp @@ -1,9 +1,8 @@ //===--------------------------- libunwind.cpp ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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> @@ -12,12 +11,6 @@ #include <libunwind.h> -#ifndef NDEBUG -#include <cstdlib> // getenv -#endif -#include <new> -#include <algorithm> - #include "libunwind_ext.h" #include "config.h" @@ -36,15 +29,11 @@ LocalAddressSpace LocalAddressSpace::sThisAddressSpace; _LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space = (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace; -/// record the registers and stack position of the caller -extern int unw_getcontext(unw_context_t *); -// note: unw_getcontext() implemented in assembly - /// Create a cursor of a thread in this process given 'context' recorded by -/// unw_getcontext(). -_LIBUNWIND_EXPORT 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__) @@ -73,101 +62,21 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor, # error Architecture not supported #endif // Use "placement new" to allocate UnwindCursor in the cursor buffer. - new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>( - context, LocalAddressSpace::sThisAddressSpace); + 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; } - -#ifdef UNW_REMOTE -/// Create a cursor into a thread in another process. -_LIBUNWIND_EXPORT int unw_init_remote_thread(unw_cursor_t *cursor, - unw_addr_space_t as, - void *arg) { - // special case: unw_init_remote(xx, unw_local_addr_space, xx) - if (as == (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace) - return unw_init_local(cursor, NULL); //FIXME - - // use "placement new" to allocate UnwindCursor in the cursor buffer - switch (as->cpuType) { - case CPU_TYPE_I386: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer32<LittleEndian>>, - Registers_x86>(((unw_addr_space_i386 *)as)->oas, arg); - break; - case CPU_TYPE_X86_64: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer64<LittleEndian>>, - Registers_x86_64>(((unw_addr_space_x86_64 *)as)->oas, arg); - break; - case CPU_TYPE_POWERPC: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer32<BigEndian>>, - Registers_ppc>(((unw_addr_space_ppc *)as)->oas, arg); - break; - default: - return UNW_EUNSPEC; - } - return UNW_ESUCCESS; -} - - -static bool is64bit(task_t task) { - return false; // FIXME -} - -/// Create an address_space object for use in examining another task. -_LIBUNWIND_EXPORT unw_addr_space_t unw_create_addr_space_for_task(task_t task) { -#if __i386__ - if (is64bit(task)) { - unw_addr_space_x86_64 *as = new unw_addr_space_x86_64(task); - as->taskPort = task; - as->cpuType = CPU_TYPE_X86_64; - //as->oas - } else { - unw_addr_space_i386 *as = new unw_addr_space_i386(task); - as->taskPort = task; - as->cpuType = CPU_TYPE_I386; - //as->oas - } -#else -// FIXME -#endif -} - - -/// Delete an address_space object. -_LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) { - switch (asp->cpuType) { -#if __i386__ || __x86_64__ - case CPU_TYPE_I386: { - unw_addr_space_i386 *as = (unw_addr_space_i386 *)asp; - delete as; - } - break; - case CPU_TYPE_X86_64: { - unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp; - delete as; - } - break; -#endif - case CPU_TYPE_POWERPC: { - unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp; - delete as; - } - break; - } -} -#endif // UNW_REMOTE - +_LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local) /// Get value of specified register at cursor position in stack frame. -_LIBUNWIND_EXPORT 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; @@ -177,12 +86,13 @@ _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } - +_LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) /// Set value of specified register at cursor position in stack frame. -_LIBUNWIND_EXPORT 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 ")", +_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; @@ -208,12 +118,12 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } - +_LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg) /// Get value of specified float register at cursor position in stack frame. -_LIBUNWIND_EXPORT 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; @@ -223,16 +133,16 @@ _LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } - +_LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg) /// Set value of specified float register at cursor position in stack frame. -_LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_fpreg_t value) { +_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_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; @@ -242,20 +152,20 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } return UNW_EBADREG; } - +_LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) /// Move cursor to next frame. -_LIBUNWIND_EXPORT 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) /// Get unwind info at cursor position in stack frame. -_LIBUNWIND_EXPORT 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); @@ -264,21 +174,21 @@ _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor, else return UNW_ESUCCESS; } - +_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info) /// Resume execution at cursor position (aka longjump). -_LIBUNWIND_EXPORT 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)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->jumpto(); return UNW_EUNSPEC; } - +_LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume) /// Get name of function at cursor position in stack frame. -_LIBUNWIND_EXPORT 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; @@ -287,58 +197,62 @@ _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf, else return UNW_EUNSPEC; } - +_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name) /// Checks if a register is a floating-point register. -_LIBUNWIND_EXPORT 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) /// Checks if a register is a floating-point register. -_LIBUNWIND_EXPORT 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) /// Checks if current frame is signal trampoline. -_LIBUNWIND_EXPORT 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) #ifdef __arm__ // Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD -_LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_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) #endif #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) /// SPI: walks cached DWARF entries -_LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)( +_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) /// 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( @@ -352,12 +266,12 @@ 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); } diff --git a/src/libunwind_ext.h b/src/libunwind_ext.h index ec645a846739..316dee298246 100644 --- a/src/libunwind_ext.h +++ b/src/libunwind_ext.h @@ -1,9 +1,8 @@ //===------------------------ libunwind_ext.h -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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. @@ -23,15 +22,34 @@ #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 *); + // 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); #if defined(_LIBUNWIND_ARM_EHABI) extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); |