Vendor import of stripped compiler-rt trunk r366426 (just before the release_90
branch point): https://llvm.org/svn/llvm-project/compiler-rt/trunk@366426
This commit is contained in:
parent
63714eb580
commit
8f3cadc28c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/compiler-rt/dist/; revision=351282 svn path=/vendor/compiler-rt/compiler-rt-trunk-r366426/; revision=351283; tag=vendor/compiler-rt/compiler-rt-trunk-r366426
252
LICENSE.TXT
252
LICENSE.TXT
@ -1,5 +1,240 @@
|
||||
==============================================================================
|
||||
compiler_rt 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 compiler_rt library is dual licensed under both the University of Illinois
|
||||
@ -74,18 +309,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
Copyrights and Licenses for Third Party Software Distributed with LLVM:
|
||||
==============================================================================
|
||||
The LLVM software contains code written by third parties. Such software will
|
||||
have its own individual LICENSE.TXT file in the directory in which it appears.
|
||||
This file will describe the copyrights, license, and restrictions which apply
|
||||
to that code.
|
||||
|
||||
The disclaimer of warranty in the University of Illinois Open Source License
|
||||
applies to all code in the LLVM Distribution, and nothing in any of the
|
||||
other licenses gives permission to use the names of the LLVM Team or the
|
||||
University of Illinois to endorse or promote products derived from this
|
||||
Software.
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- allocator_interface.h ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,13 +1,12 @@
|
||||
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer.
|
||||
// This file is a part of AddressSanitizer (ASan).
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -19,28 +18,54 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Marks memory region [addr, addr+size) as unaddressable.
|
||||
// This memory must be previously allocated by the user program. Accessing
|
||||
// addresses in this region from instrumented code is forbidden until
|
||||
// this region is unpoisoned. This function is not guaranteed to poison
|
||||
// the whole region - it may poison only subregion of [addr, addr+size) due
|
||||
// to ASan alignment restrictions.
|
||||
// Method is NOT thread-safe in the sense that no two threads can
|
||||
// (un)poison memory in the same memory region simultaneously.
|
||||
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||
// Marks memory region [addr, addr+size) as addressable.
|
||||
// This memory must be previously allocated by the user program. Accessing
|
||||
// addresses in this region is allowed until this region is poisoned again.
|
||||
// This function may unpoison a superregion of [addr, addr+size) due to
|
||||
// ASan alignment restrictions.
|
||||
// Method is NOT thread-safe in the sense that no two threads can
|
||||
// (un)poison memory in the same memory region simultaneously.
|
||||
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
/// Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
|
||||
///
|
||||
/// This memory must be previously allocated by your program. Instrumented
|
||||
/// code is forbidden from accessing addresses in this region until it is
|
||||
/// unpoisoned. This function is not guaranteed to poison the entire region -
|
||||
/// it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
|
||||
/// alignment restrictions.
|
||||
///
|
||||
/// \note This function is not thread-safe because no two threads can poison or
|
||||
/// unpoison memory in the same memory region simultaneously.
|
||||
///
|
||||
/// \param addr Start of memory region.
|
||||
/// \param size Size of memory region.
|
||||
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||
|
||||
// User code should use macros instead of functions.
|
||||
/// Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
|
||||
///
|
||||
/// This memory must be previously allocated by your program. Accessing
|
||||
/// addresses in this region is allowed until this region is poisoned again.
|
||||
/// This function could unpoison a super-region of <c>[addr, addr+size)</c> due
|
||||
/// to ASan alignment restrictions.
|
||||
///
|
||||
/// \note This function is not thread-safe because no two threads can
|
||||
/// poison or unpoison memory in the same memory region simultaneously.
|
||||
///
|
||||
/// \param addr Start of memory region.
|
||||
/// \param size Size of memory region.
|
||||
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
|
||||
// Macros provided for convenience.
|
||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
/// Marks a memory region as unaddressable.
|
||||
///
|
||||
/// \note Macro provided for convenience; defined as a no-op if ASan is not
|
||||
/// enabled.
|
||||
///
|
||||
/// \param addr Start of memory region.
|
||||
/// \param size Size of memory region.
|
||||
#define ASAN_POISON_MEMORY_REGION(addr, size) \
|
||||
__asan_poison_memory_region((addr), (size))
|
||||
|
||||
/// Marks a memory region as addressable.
|
||||
///
|
||||
/// \note Macro provided for convenience; defined as a no-op if ASan is not
|
||||
/// enabled.
|
||||
///
|
||||
/// \param addr Start of memory region.
|
||||
/// \param size Size of memory region.
|
||||
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
|
||||
__asan_unpoison_memory_region((addr), (size))
|
||||
#else
|
||||
@ -50,103 +75,245 @@ extern "C" {
|
||||
((void)(addr), (void)(size))
|
||||
#endif
|
||||
|
||||
// Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this
|
||||
// address will result in error report from AddressSanitizer).
|
||||
// Otherwise returns 0.
|
||||
int __asan_address_is_poisoned(void const volatile *addr);
|
||||
/// Checks if an address is poisoned.
|
||||
///
|
||||
/// Returns 1 if <c><i>addr</i></c> is poisoned (that is, 1-byte read/write
|
||||
/// access to this address would result in an error report from ASan).
|
||||
/// Otherwise returns 0.
|
||||
///
|
||||
/// \param addr Address to check.
|
||||
///
|
||||
/// \retval 1 Address is poisoned.
|
||||
/// \retval 0 Address is not poisoned.
|
||||
int __asan_address_is_poisoned(void const volatile *addr);
|
||||
|
||||
// If at least one byte in [beg, beg+size) is poisoned, return the address
|
||||
// of the first such byte. Otherwise return 0.
|
||||
void *__asan_region_is_poisoned(void *beg, size_t size);
|
||||
/// Checks if a region is poisoned.
|
||||
///
|
||||
/// If at least one byte in <c>[beg, beg+size)</c> is poisoned, returns the
|
||||
/// address of the first such byte. Otherwise returns 0.
|
||||
///
|
||||
/// \param beg Start of memory region.
|
||||
/// \param size Start of memory region.
|
||||
/// \returns Address of first poisoned byte.
|
||||
void *__asan_region_is_poisoned(void *beg, size_t size);
|
||||
|
||||
// Print the description of addr (useful when debugging in gdb).
|
||||
void __asan_describe_address(void *addr);
|
||||
/// Describes an address (useful for calling from the debugger).
|
||||
///
|
||||
/// Prints the description of <c><i>addr</i></c>.
|
||||
///
|
||||
/// \param addr Address to describe.
|
||||
void __asan_describe_address(void *addr);
|
||||
|
||||
// Useful for calling from a debugger to get information about an ASan error.
|
||||
// Returns 1 if an error has been (or is being) reported, otherwise returns 0.
|
||||
int __asan_report_present(void);
|
||||
/// Checks if an error has been or is being reported (useful for calling from
|
||||
/// the debugger to get information about an ASan error).
|
||||
///
|
||||
/// Returns 1 if an error has been (or is being) reported. Otherwise returns 0.
|
||||
///
|
||||
/// \returns 1 if an error has been (or is being) reported. Otherwise returns
|
||||
/// 0.
|
||||
int __asan_report_present(void);
|
||||
|
||||
// Useful for calling from a debugger to get information about an ASan error.
|
||||
// If an error has been (or is being) reported, the following functions return
|
||||
// the pc, bp, sp, address, access type (0 = read, 1 = write), access size and
|
||||
// bug description (e.g. "heap-use-after-free"). Otherwise they return 0.
|
||||
void *__asan_get_report_pc(void);
|
||||
void *__asan_get_report_bp(void);
|
||||
void *__asan_get_report_sp(void);
|
||||
void *__asan_get_report_address(void);
|
||||
int __asan_get_report_access_type(void);
|
||||
size_t __asan_get_report_access_size(void);
|
||||
const char *__asan_get_report_description(void);
|
||||
/// Gets the PC (program counter) register value of an ASan error (useful for
|
||||
/// calling from the debugger).
|
||||
///
|
||||
/// Returns PC if an error has been (or is being) reported.
|
||||
/// Otherwise returns 0.
|
||||
///
|
||||
/// \returns PC value.
|
||||
void *__asan_get_report_pc(void);
|
||||
|
||||
// Useful for calling from the debugger to get information about a pointer.
|
||||
// Returns the category of the given pointer as a constant string.
|
||||
// Possible return values are "global", "stack", "stack-fake", "heap",
|
||||
// "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown".
|
||||
// If global or stack, tries to also return the variable name, address and
|
||||
// size. If heap, tries to return the chunk address and size. 'name' should
|
||||
// point to an allocated buffer of size 'name_size'.
|
||||
const char *__asan_locate_address(void *addr, char *name, size_t name_size,
|
||||
void **region_address, size_t *region_size);
|
||||
/// Gets the BP (base pointer) register value of an ASan error (useful for
|
||||
/// calling from the debugger).
|
||||
///
|
||||
/// Returns BP if an error has been (or is being) reported.
|
||||
/// Otherwise returns 0.
|
||||
///
|
||||
/// \returns BP value.
|
||||
void *__asan_get_report_bp(void);
|
||||
|
||||
// Useful for calling from the debugger to get the allocation stack trace
|
||||
// and thread ID for a heap address. Stores up to 'size' frames into 'trace',
|
||||
// returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
/// Gets the SP (stack pointer) register value of an ASan error (useful for
|
||||
/// calling from the debugger).
|
||||
///
|
||||
/// If an error has been (or is being) reported, returns SP.
|
||||
/// Otherwise returns 0.
|
||||
///
|
||||
/// \returns SP value.
|
||||
void *__asan_get_report_sp(void);
|
||||
|
||||
// Useful for calling from the debugger to get the free stack trace
|
||||
// and thread ID for a heap address. Stores up to 'size' frames into 'trace',
|
||||
// returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
/// Gets the address of the report buffer of an ASan error (useful for calling
|
||||
/// from the debugger).
|
||||
///
|
||||
/// Returns the address of the report buffer if an error has been (or is being)
|
||||
/// reported. Otherwise returns 0.
|
||||
///
|
||||
/// \returns Address of report buffer.
|
||||
void *__asan_get_report_address(void);
|
||||
|
||||
// Useful for calling from the debugger to get the current shadow memory
|
||||
// mapping.
|
||||
void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
|
||||
/// Gets access type of an ASan error (useful for calling from the debugger).
|
||||
///
|
||||
/// Returns access type (read or write) if an error has been (or is being)
|
||||
/// reported. Otherwise returns 0.
|
||||
///
|
||||
/// \returns Access type (0 = read, 1 = write).
|
||||
int __asan_get_report_access_type(void);
|
||||
|
||||
// This is an internal function that is called to report an error.
|
||||
// However it is still a part of the interface because users may want to
|
||||
// set a breakpoint on this function in a debugger.
|
||||
void __asan_report_error(void *pc, void *bp, void *sp,
|
||||
void *addr, int is_write, size_t access_size);
|
||||
/// Gets access size of an ASan error (useful for calling from the debugger).
|
||||
///
|
||||
/// Returns access size if an error has been (or is being) reported. Otherwise
|
||||
/// returns 0.
|
||||
///
|
||||
/// \returns Access size in bytes.
|
||||
size_t __asan_get_report_access_size(void);
|
||||
|
||||
// Deprecated. Call __sanitizer_set_death_callback instead.
|
||||
void __asan_set_death_callback(void (*callback)(void));
|
||||
/// Gets the bug description of an ASan error (useful for calling from a
|
||||
/// debugger).
|
||||
///
|
||||
/// \returns Returns a bug description if an error has been (or is being)
|
||||
/// reported - for example, "heap-use-after-free". Otherwise returns an empty
|
||||
/// string.
|
||||
const char *__asan_get_report_description(void);
|
||||
|
||||
void __asan_set_error_report_callback(void (*callback)(const char*));
|
||||
/// Gets information about a pointer (useful for calling from the debugger).
|
||||
///
|
||||
/// Returns the category of the given pointer as a constant string.
|
||||
/// Possible return values are <c>global</c>, <c>stack</c>, <c>stack-fake</c>,
|
||||
/// <c>heap</c>, <c>heap-invalid</c>, <c>shadow-low</c>, <c>shadow-gap</c>,
|
||||
/// <c>shadow-high</c>, and <c>unknown</c>.
|
||||
///
|
||||
/// If the return value is <c>global</c> or <c>stack</c>, tries to also return
|
||||
/// the variable name, address, and size. If the return value is <c>heap</c>,
|
||||
/// tries to return the chunk address and size. <c><i>name</i></c> should point
|
||||
/// to an allocated buffer of size <c><i>name_size</i></c>.
|
||||
///
|
||||
/// \param addr Address to locate.
|
||||
/// \param name Buffer to store the variable's name.
|
||||
/// \param name_size Size in bytes of the variable's name buffer.
|
||||
/// \param region_address [out] Address of the region.
|
||||
/// \param region_size [out] Size of the region in bytes.
|
||||
///
|
||||
/// \returns Returns the category of the given pointer as a constant string.
|
||||
const char *__asan_locate_address(void *addr, char *name, size_t name_size,
|
||||
void **region_address, size_t *region_size);
|
||||
|
||||
// User may provide function that would be called right when ASan detects
|
||||
// an error. This can be used to notice cases when ASan detects an error, but
|
||||
// the program crashes before ASan report is printed.
|
||||
void __asan_on_error(void);
|
||||
/// Gets the allocation stack trace and thread ID for a heap address (useful
|
||||
/// for calling from the debugger).
|
||||
///
|
||||
/// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns
|
||||
/// the number of stored frames or 0 on error.
|
||||
///
|
||||
/// \param addr A heap address.
|
||||
/// \param trace A buffer to store the stack trace.
|
||||
/// \param size Size in bytes of the trace buffer.
|
||||
/// \param thread_id [out] The thread ID of the address.
|
||||
///
|
||||
/// \returns Returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
|
||||
// Prints accumulated stats to stderr. Used for debugging.
|
||||
void __asan_print_accumulated_stats(void);
|
||||
/// Gets the free stack trace and thread ID for a heap address (useful for
|
||||
/// calling from the debugger).
|
||||
///
|
||||
/// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns
|
||||
/// the number of stored frames or 0 on error.
|
||||
///
|
||||
/// \param addr A heap address.
|
||||
/// \param trace A buffer to store the stack trace.
|
||||
/// \param size Size in bytes of the trace buffer.
|
||||
/// \param thread_id [out] The thread ID of the address.
|
||||
///
|
||||
/// \returns Returns the number of stored frames or 0 on error.
|
||||
size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
|
||||
int *thread_id);
|
||||
|
||||
// This function may be optionally provided by user and should return
|
||||
// a string containing ASan runtime options. See asan_flags.h for details.
|
||||
const char* __asan_default_options(void);
|
||||
/// Gets the current shadow memory mapping (useful for calling from the
|
||||
/// debugger).
|
||||
///
|
||||
/// \param shadow_scale [out] Shadow scale value.
|
||||
/// \param shadow_offset [out] Offset value.
|
||||
void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
|
||||
|
||||
// The following 2 functions facilitate garbage collection in presence of
|
||||
// asan's fake stack.
|
||||
/// This is an internal function that is called to report an error. However,
|
||||
/// it is still a part of the interface because you might want to set a
|
||||
/// breakpoint on this function in the debugger.
|
||||
///
|
||||
/// \param pc <c><i>pc</i></c> value of the ASan error.
|
||||
/// \param bp <c><i>bp</i></c> value of the ASan error.
|
||||
/// \param sp <c><i>sp</i></c> value of the ASan error.
|
||||
/// \param addr Address of the ASan error.
|
||||
/// \param is_write True if the error is a write error; false otherwise.
|
||||
/// \param access_size Size of the memory access of the ASan error.
|
||||
void __asan_report_error(void *pc, void *bp, void *sp,
|
||||
void *addr, int is_write, size_t access_size);
|
||||
|
||||
// Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.
|
||||
// Returns NULL if the current thread does not have a fake stack.
|
||||
void *__asan_get_current_fake_stack(void);
|
||||
// Deprecated. Call __sanitizer_set_death_callback instead.
|
||||
void __asan_set_death_callback(void (*callback)(void));
|
||||
|
||||
// If fake_stack is non-NULL and addr belongs to a fake frame in
|
||||
// fake_stack, returns the address on real stack that corresponds to
|
||||
// the fake frame and sets beg/end to the boundaries of this fake frame.
|
||||
// Otherwise returns NULL and does not touch beg/end.
|
||||
// If beg/end are NULL, they are not touched.
|
||||
// This function may be called from a thread other than the owner of
|
||||
// fake_stack, but the owner thread need to be alive.
|
||||
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
|
||||
void **end);
|
||||
/// Sets the callback function to be called during ASan error reporting.
|
||||
///
|
||||
/// The callback provides a string pointer to the report.
|
||||
///
|
||||
/// \param callback User-provided function.
|
||||
void __asan_set_error_report_callback(void (*callback)(const char *));
|
||||
|
||||
// Performs cleanup before a [[noreturn]] function. Must be called
|
||||
// before things like _exit and execl to avoid false positives on stack.
|
||||
void __asan_handle_no_return(void);
|
||||
/// User-provided callback on ASan errors.
|
||||
///
|
||||
/// You can provide a function that would be called immediately when ASan
|
||||
/// detects an error. This is useful in cases when ASan detects an error but
|
||||
/// your program crashes before the ASan report is printed.
|
||||
void __asan_on_error(void);
|
||||
|
||||
/// Prints accumulated statistics to <c>stderr</c> (useful for calling from the
|
||||
/// debugger).
|
||||
void __asan_print_accumulated_stats(void);
|
||||
|
||||
/// User-provided default option settings.
|
||||
///
|
||||
/// You can provide your own implementation of this function to return a string
|
||||
/// containing ASan runtime options (for example,
|
||||
/// <c>verbosity=1:halt_on_error=0</c>).
|
||||
///
|
||||
/// \returns Default options string.
|
||||
const char* __asan_default_options(void);
|
||||
|
||||
// The following two functions facilitate garbage collection in presence of
|
||||
// ASan's fake stack.
|
||||
|
||||
/// Gets an opaque handler to the current thread's fake stack.
|
||||
///
|
||||
/// Returns an opaque handler to be used by
|
||||
/// <c>__asan_addr_is_in_fake_stack()</c>. Returns NULL if the current thread
|
||||
/// does not have a fake stack.
|
||||
///
|
||||
/// \returns An opaque handler to the fake stack or NULL.
|
||||
void *__asan_get_current_fake_stack(void);
|
||||
|
||||
/// Checks if an address belongs to a given fake stack.
|
||||
///
|
||||
/// If <c><i>fake_stack</i></c> is non-NULL and <c><i>addr</i></c> belongs to a
|
||||
/// fake frame in <c><i>fake_stack</i></c>, returns the address of the real
|
||||
/// stack that corresponds to the fake frame and sets <c><i>beg</i></c> and
|
||||
/// <c><i>end</i></c> to the boundaries of this fake frame. Otherwise returns
|
||||
/// NULL and does not touch <c><i>beg</i></c> and <c><i>end</i></c>.
|
||||
///
|
||||
/// If <c><i>beg</i></c> or <c><i>end</i></c> are NULL, they are not touched.
|
||||
///
|
||||
/// \note This function can be called from a thread other than the owner of
|
||||
/// <c><i>fake_stack</i></c>, but the owner thread needs to be alive.
|
||||
///
|
||||
/// \param fake_stack An opaque handler to a fake stack.
|
||||
/// \param addr Address to test.
|
||||
/// \param beg [out] Beginning of fake frame.
|
||||
/// \param end [out] End of fake frame.
|
||||
/// \returns Stack address or NULL.
|
||||
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
|
||||
void **end);
|
||||
|
||||
/// Performs shadow memory cleanup of the current thread's stack before a
|
||||
/// function marked with the <c>[[noreturn]]</c> attribute is called.
|
||||
///
|
||||
/// To avoid false positives on the stack, must be called before no-return
|
||||
/// functions like <c>_exit()</c> and <c>execl()</c>.
|
||||
void __asan_handle_no_return(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -18,189 +17,335 @@
|
||||
|
||||
// GCC does not understand __has_feature.
|
||||
#if !defined(__has_feature)
|
||||
# define __has_feature(x) 0
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Arguments for __sanitizer_sandbox_on_notify() below.
|
||||
typedef struct {
|
||||
// Enable sandbox support in sanitizer coverage.
|
||||
int coverage_sandboxed;
|
||||
// File descriptor to write coverage data to. If -1 is passed, a file will
|
||||
// be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
|
||||
// effect if coverage_sandboxed == 0.
|
||||
intptr_t coverage_fd;
|
||||
// If non-zero, split the coverage data into well-formed blocks. This is
|
||||
// useful when coverage_fd is a socket descriptor. Each block will contain
|
||||
// a header, allowing data from multiple processes to be sent over the same
|
||||
// socket.
|
||||
unsigned int coverage_max_block_size;
|
||||
} __sanitizer_sandbox_arguments;
|
||||
// Arguments for __sanitizer_sandbox_on_notify() below.
|
||||
typedef struct {
|
||||
// Enable sandbox support in sanitizer coverage.
|
||||
int coverage_sandboxed;
|
||||
// File descriptor to write coverage data to. If -1 is passed, a file will
|
||||
// be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
|
||||
// effect if coverage_sandboxed == 0.
|
||||
intptr_t coverage_fd;
|
||||
// If non-zero, split the coverage data into well-formed blocks. This is
|
||||
// useful when coverage_fd is a socket descriptor. Each block will contain
|
||||
// a header, allowing data from multiple processes to be sent over the same
|
||||
// socket.
|
||||
unsigned int coverage_max_block_size;
|
||||
} __sanitizer_sandbox_arguments;
|
||||
|
||||
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
|
||||
void __sanitizer_set_report_path(const char *path);
|
||||
// Tell the tools to write their reports to the provided file descriptor
|
||||
// (casted to void *).
|
||||
void __sanitizer_set_report_fd(void *fd);
|
||||
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
|
||||
void __sanitizer_set_report_path(const char *path);
|
||||
// Tell the tools to write their reports to the provided file descriptor
|
||||
// (casted to void *).
|
||||
void __sanitizer_set_report_fd(void *fd);
|
||||
|
||||
// Notify the tools that the sandbox is going to be turned on. The reserved
|
||||
// parameter will be used in the future to hold a structure with functions
|
||||
// that the tools may call to bypass the sandbox.
|
||||
void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
|
||||
// Notify the tools that the sandbox is going to be turned on. The reserved
|
||||
// parameter will be used in the future to hold a structure with functions
|
||||
// that the tools may call to bypass the sandbox.
|
||||
void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
|
||||
|
||||
// This function is called by the tool when it has just finished reporting
|
||||
// an error. 'error_summary' is a one-line string that summarizes
|
||||
// the error message. This function can be overridden by the client.
|
||||
void __sanitizer_report_error_summary(const char *error_summary);
|
||||
// This function is called by the tool when it has just finished reporting
|
||||
// an error. 'error_summary' is a one-line string that summarizes
|
||||
// the error message. This function can be overridden by the client.
|
||||
void __sanitizer_report_error_summary(const char *error_summary);
|
||||
|
||||
// Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen
|
||||
// in unaligned loads/stores. In order to find such bugs reliably one needs
|
||||
// to replace plain unaligned loads/stores with these calls.
|
||||
uint16_t __sanitizer_unaligned_load16(const void *p);
|
||||
uint32_t __sanitizer_unaligned_load32(const void *p);
|
||||
uint64_t __sanitizer_unaligned_load64(const void *p);
|
||||
void __sanitizer_unaligned_store16(void *p, uint16_t x);
|
||||
void __sanitizer_unaligned_store32(void *p, uint32_t x);
|
||||
void __sanitizer_unaligned_store64(void *p, uint64_t x);
|
||||
// Some of the sanitizers (for example ASan/TSan) could miss bugs that happen
|
||||
// in unaligned loads/stores. To find such bugs reliably, you need to replace
|
||||
// plain unaligned loads/stores with these calls.
|
||||
|
||||
// Returns 1 on the first call, then returns 0 thereafter. Called by the tool
|
||||
// to ensure only one report is printed when multiple errors occur
|
||||
// simultaneously.
|
||||
int __sanitizer_acquire_crash_state();
|
||||
/// Loads a 16-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
///
|
||||
/// \returns Loaded value.
|
||||
uint16_t __sanitizer_unaligned_load16(const void *p);
|
||||
|
||||
// Annotate the current state of a contiguous container, such as
|
||||
// std::vector, std::string or similar.
|
||||
// A contiguous container is a container that keeps all of its elements
|
||||
// in a contiguous region of memory. The container owns the region of memory
|
||||
// [beg, end); the memory [beg, mid) is used to store the current elements
|
||||
// and the memory [mid, end) is reserved for future elements;
|
||||
// beg <= mid <= end. For example, in "std::vector<> v"
|
||||
// beg = &v[0];
|
||||
// end = beg + v.capacity() * sizeof(v[0]);
|
||||
// mid = beg + v.size() * sizeof(v[0]);
|
||||
//
|
||||
// This annotation tells the Sanitizer tool about the current state of the
|
||||
// container so that the tool can report errors when memory from [mid, end)
|
||||
// is accessed. Insert this annotation into methods like push_back/pop_back.
|
||||
// Supply the old and the new values of mid (old_mid/new_mid).
|
||||
// In the initial state mid == end and so should be the final
|
||||
// state when the container is destroyed or when it reallocates the storage.
|
||||
//
|
||||
// Use with caution and don't use for anything other than vector-like classes.
|
||||
//
|
||||
// For AddressSanitizer, 'beg' should be 8-aligned and 'end' should
|
||||
// be either 8-aligned or it should point to the end of a separate heap-,
|
||||
// stack-, or global- allocated buffer. I.e. the following will not work:
|
||||
// int64_t x[2]; // 16 bytes, 8-aligned.
|
||||
// char *beg = (char *)&x[0];
|
||||
// char *end = beg + 12; // Not 8 aligned, not the end of the buffer.
|
||||
// This however will work fine:
|
||||
// int32_t x[3]; // 12 bytes, but 8-aligned under AddressSanitizer.
|
||||
// char *beg = (char*)&x[0];
|
||||
// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer.
|
||||
void __sanitizer_annotate_contiguous_container(const void *beg,
|
||||
const void *end,
|
||||
const void *old_mid,
|
||||
const void *new_mid);
|
||||
// Returns true if the contiguous container [beg, end) is properly poisoned
|
||||
// (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
|
||||
// - [beg, mid) is addressable,
|
||||
// - [mid, end) is unaddressable.
|
||||
// Full verification requires O(end-beg) time; this function tries to avoid
|
||||
// such complexity by touching only parts of the container around beg/mid/end.
|
||||
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
|
||||
const void *end);
|
||||
/// Loads a 32-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
///
|
||||
/// \returns Loaded value.
|
||||
uint32_t __sanitizer_unaligned_load32(const void *p);
|
||||
|
||||
// Similar to __sanitizer_verify_contiguous_container but returns the address
|
||||
// of the first improperly poisoned byte otherwise. Returns null if the area
|
||||
// is poisoned properly.
|
||||
const void *__sanitizer_contiguous_container_find_bad_address(
|
||||
const void *beg, const void *mid, const void *end);
|
||||
/// Loads a 64-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
///
|
||||
/// \returns Loaded value.
|
||||
uint64_t __sanitizer_unaligned_load64(const void *p);
|
||||
|
||||
// Print the stack trace leading to this call. Useful for debugging user code.
|
||||
void __sanitizer_print_stack_trace(void);
|
||||
/// Stores a 16-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
/// \param x 16-bit value to store.
|
||||
void __sanitizer_unaligned_store16(void *p, uint16_t x);
|
||||
|
||||
// Symbolizes the supplied 'pc' using the format string 'fmt'.
|
||||
// Outputs at most 'out_buf_size' bytes into 'out_buf'.
|
||||
// If 'out_buf' is not empty then output is zero or more non empty C strings
|
||||
// followed by single empty C string. Multiple strings can be returned if PC
|
||||
// corresponds to inlined function. Inlined frames are printed in the order
|
||||
// from "most-inlined" to the "least-inlined", so the last frame should be the
|
||||
// not inlined function.
|
||||
// Inlined frames can be removed with 'symbolize_inline_frames=0'.
|
||||
// The format syntax is described in
|
||||
// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
|
||||
void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
|
||||
size_t out_buf_size);
|
||||
// Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
|
||||
void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
|
||||
char *out_buf, size_t out_buf_size);
|
||||
/// Stores a 32-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
/// \param x 32-bit value to store.
|
||||
void __sanitizer_unaligned_store32(void *p, uint32_t x);
|
||||
|
||||
// Sets the callback to be called right before death on error.
|
||||
// Passing 0 will unset the callback.
|
||||
void __sanitizer_set_death_callback(void (*callback)(void));
|
||||
/// Stores a 64-bit unaligned value.
|
||||
///
|
||||
/// \param p Pointer to unaligned memory.
|
||||
/// \param x 64-bit value to store.
|
||||
void __sanitizer_unaligned_store64(void *p, uint64_t x);
|
||||
|
||||
// Interceptor hooks.
|
||||
// Whenever a libc function interceptor is called it checks if the
|
||||
// corresponding weak hook is defined, and it so -- calls it.
|
||||
// The primary use case is data-flow-guided fuzzing, where the fuzzer needs
|
||||
// to know what is being passed to libc functions, e.g. memcmp.
|
||||
// FIXME: implement more hooks.
|
||||
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
|
||||
const void *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
void __sanitizer_weak_hook_memmem(void *called_pc,
|
||||
const void *s1, size_t len1,
|
||||
const void *s2, size_t len2, void *result);
|
||||
// Returns 1 on the first call, then returns 0 thereafter. Called by the tool
|
||||
// to ensure only one report is printed when multiple errors occur
|
||||
// simultaneously.
|
||||
int __sanitizer_acquire_crash_state();
|
||||
|
||||
// Prints stack traces for all live heap allocations ordered by total
|
||||
// allocation size until `top_percent` of total live heap is shown.
|
||||
// `top_percent` should be between 1 and 100.
|
||||
// At most `max_number_of_contexts` contexts (stack traces) is printed.
|
||||
// Experimental feature currently available only with asan on Linux/x86_64.
|
||||
void __sanitizer_print_memory_profile(size_t top_percent,
|
||||
size_t max_number_of_contexts);
|
||||
/// Annotates the current state of a contiguous container, such as
|
||||
/// <c>std::vector</c>, <c>std::string</c>, or similar.
|
||||
///
|
||||
/// A contiguous container is a container that keeps all of its elements
|
||||
/// in a contiguous region of memory. The container owns the region of memory
|
||||
/// <c>[beg, end)</c>; the memory <c>[beg, mid)</c> is used to store the
|
||||
/// current elements, and the memory <c>[mid, end)</c> is reserved for future
|
||||
/// elements (<c>beg <= mid <= end</c>). For example, in
|
||||
/// <c>std::vector<> v</c>:
|
||||
///
|
||||
/// \code
|
||||
/// beg = &v[0];
|
||||
/// end = beg + v.capacity() * sizeof(v[0]);
|
||||
/// mid = beg + v.size() * sizeof(v[0]);
|
||||
/// \endcode
|
||||
///
|
||||
/// This annotation tells the Sanitizer tool about the current state of the
|
||||
/// container so that the tool can report errors when memory from
|
||||
/// <c>[mid, end)</c> is accessed. Insert this annotation into methods like
|
||||
/// <c>push_back()</c> or <c>pop_back()</c>. Supply the old and new values of
|
||||
/// <c>mid</c>(<c><i>old_mid</i></c> and <c><i>new_mid</i></c>). In the initial
|
||||
/// state <c>mid == end</c>, so that should be the final state when the
|
||||
/// container is destroyed or when the container reallocates the storage.
|
||||
///
|
||||
/// For ASan, <c><i>beg</i></c> should be 8-aligned and <c><i>end</i></c>
|
||||
/// should be either 8-aligned or it should point to the end of a separate
|
||||
/// heap-, stack-, or global-allocated buffer. So the following example will
|
||||
/// not work:
|
||||
///
|
||||
/// \code
|
||||
/// int64_t x[2]; // 16 bytes, 8-aligned
|
||||
/// char *beg = (char *)&x[0];
|
||||
/// char *end = beg + 12; // Not 8-aligned, not the end of the buffer
|
||||
/// \endcode
|
||||
///
|
||||
/// The following, however, will work:
|
||||
/// \code
|
||||
/// int32_t x[3]; // 12 bytes, but 8-aligned under ASan.
|
||||
/// char *beg = (char*)&x[0];
|
||||
/// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer
|
||||
/// \endcode
|
||||
///
|
||||
/// \note Use this function with caution and do not use for anything other
|
||||
/// than vector-like classes.
|
||||
///
|
||||
/// \param beg Beginning of memory region.
|
||||
/// \param end End of memory region.
|
||||
/// \param old_mid Old middle of memory region.
|
||||
/// \param new_mid New middle of memory region.
|
||||
void __sanitizer_annotate_contiguous_container(const void *beg,
|
||||
const void *end,
|
||||
const void *old_mid,
|
||||
const void *new_mid);
|
||||
|
||||
// Fiber annotation interface.
|
||||
// Before switching to a different stack, one must call
|
||||
// __sanitizer_start_switch_fiber with a pointer to the bottom of the
|
||||
// destination stack and its size. When code starts running on the new stack,
|
||||
// it must call __sanitizer_finish_switch_fiber to finalize the switch.
|
||||
// The start_switch function takes a void** to store the current fake stack if
|
||||
// there is one (it is needed when detect_stack_use_after_return is enabled).
|
||||
// When restoring a stack, this pointer must be given to the finish_switch
|
||||
// function. In most cases, this void* can be stored on the stack just before
|
||||
// switching. When leaving a fiber definitely, null must be passed as first
|
||||
// argument to the start_switch function so that the fake stack is destroyed.
|
||||
// If you do not want support for stack use-after-return detection, you can
|
||||
// always pass null to these two functions.
|
||||
// Note that the fake stack mechanism is disabled during fiber switch, so if a
|
||||
// signal callback runs during the switch, it will not benefit from the stack
|
||||
// use-after-return detection.
|
||||
void __sanitizer_start_switch_fiber(void **fake_stack_save,
|
||||
const void *bottom, size_t size);
|
||||
void __sanitizer_finish_switch_fiber(void *fake_stack_save,
|
||||
const void **bottom_old,
|
||||
size_t *size_old);
|
||||
/// Returns true if the contiguous container <c>[beg, end)</c> is properly
|
||||
/// poisoned.
|
||||
///
|
||||
/// Proper poisoning could occur, for example, with
|
||||
/// <c>__sanitizer_annotate_contiguous_container</c>), that is, if
|
||||
/// <c>[beg, mid)</c> is addressable and <c>[mid, end)</c> is unaddressable.
|
||||
/// Full verification requires O (<c>end - beg</c>) time; this function tries
|
||||
/// to avoid such complexity by touching only parts of the container around
|
||||
/// <c><i>beg</i></c>, <c><i>mid</i></c>, and <c><i>end</i></c>.
|
||||
///
|
||||
/// \param beg Beginning of memory region.
|
||||
/// \param mid Middle of memory region.
|
||||
/// \param end Old end of memory region.
|
||||
///
|
||||
/// \returns True if the contiguous container <c>[beg, end)</c> is properly
|
||||
/// poisoned.
|
||||
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
|
||||
const void *end);
|
||||
|
||||
// Get full module name and calculate pc offset within it.
|
||||
// Returns 1 if pc belongs to some module, 0 if module was not found.
|
||||
int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
|
||||
size_t module_path_len,
|
||||
void **pc_offset);
|
||||
/// Similar to <c>__sanitizer_verify_contiguous_container()</c> but also
|
||||
/// returns the address of the first improperly poisoned byte.
|
||||
///
|
||||
/// Returns NULL if the area is poisoned properly.
|
||||
///
|
||||
/// \param beg Beginning of memory region.
|
||||
/// \param mid Middle of memory region.
|
||||
/// \param end Old end of memory region.
|
||||
///
|
||||
/// \returns The bad address or NULL.
|
||||
const void *__sanitizer_contiguous_container_find_bad_address(const void *beg,
|
||||
const void *mid,
|
||||
const void *end);
|
||||
|
||||
/// Prints the stack trace leading to this call (useful for calling from the
|
||||
/// debugger).
|
||||
void __sanitizer_print_stack_trace(void);
|
||||
|
||||
// Symbolizes the supplied 'pc' using the format string 'fmt'.
|
||||
// Outputs at most 'out_buf_size' bytes into 'out_buf'.
|
||||
// If 'out_buf' is not empty then output is zero or more non empty C strings
|
||||
// followed by single empty C string. Multiple strings can be returned if PC
|
||||
// corresponds to inlined function. Inlined frames are printed in the order
|
||||
// from "most-inlined" to the "least-inlined", so the last frame should be the
|
||||
// not inlined function.
|
||||
// Inlined frames can be removed with 'symbolize_inline_frames=0'.
|
||||
// The format syntax is described in
|
||||
// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
|
||||
void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
|
||||
size_t out_buf_size);
|
||||
// Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
|
||||
void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
|
||||
char *out_buf, size_t out_buf_size);
|
||||
|
||||
/// Sets the callback to be called immediately before death on error.
|
||||
///
|
||||
/// Passing 0 will unset the callback.
|
||||
///
|
||||
/// \param callback User-provided callback.
|
||||
void __sanitizer_set_death_callback(void (*callback)(void));
|
||||
|
||||
|
||||
// Interceptor hooks.
|
||||
// Whenever a libc function interceptor is called, it checks if the
|
||||
// corresponding weak hook is defined, and calls it if it is indeed defined.
|
||||
// The primary use-case is data-flow-guided fuzzing, where the fuzzer needs
|
||||
// to know what is being passed to libc functions (for example memcmp).
|
||||
// FIXME: implement more hooks.
|
||||
|
||||
/// Interceptor hook for <c>memcmp()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param n Number of bytes to compare.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
|
||||
const void *s2, size_t n, int result);
|
||||
|
||||
/// Interceptor hook for <c>strncmp()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param n Number of bytes to compare.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
|
||||
/// Interceptor hook for <c>strncasecmp()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param n Number of bytes to compare.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
|
||||
/// Interceptor hook for <c>strcmp()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
|
||||
/// Interceptor hook for <c>strcasecmp()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
|
||||
/// Interceptor hook for <c>strstr()</c>.
|
||||
///
|
||||
/// \param called_pc PC (program counter) address of the original call.
|
||||
/// \param s1 Pointer to block of memory.
|
||||
/// \param s2 Pointer to block of memory.
|
||||
/// \param result Value returned by the intercepted function.
|
||||
void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
|
||||
void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
|
||||
void __sanitizer_weak_hook_memmem(void *called_pc,
|
||||
const void *s1, size_t len1,
|
||||
const void *s2, size_t len2, void *result);
|
||||
|
||||
// Prints stack traces for all live heap allocations ordered by total
|
||||
// allocation size until top_percent of total live heap is shown. top_percent
|
||||
// should be between 1 and 100. At most max_number_of_contexts contexts
|
||||
// (stack traces) are printed.
|
||||
// Experimental feature currently available only with ASan on Linux/x86_64.
|
||||
void __sanitizer_print_memory_profile(size_t top_percent,
|
||||
size_t max_number_of_contexts);
|
||||
|
||||
/// Notify ASan that a fiber switch has started (required only if implementing
|
||||
/// your own fiber library).
|
||||
///
|
||||
/// Before switching to a different stack, you must call
|
||||
/// <c>__sanitizer_start_switch_fiber()</c> with a pointer to the bottom of the
|
||||
/// destination stack and with its size. When code starts running on the new
|
||||
/// stack, it must call <c>__sanitizer_finish_switch_fiber()</c> to finalize
|
||||
/// the switch. The <c>__sanitizer_start_switch_fiber()</c> function takes a
|
||||
/// <c>void**</c> pointer argument to store the current fake stack if there is
|
||||
/// one (it is necessary when the runtime option
|
||||
/// <c>detect_stack_use_after_return</c> is enabled).
|
||||
///
|
||||
/// When restoring a stack, this <c>void**</c> pointer must be given to the
|
||||
/// <c>__sanitizer_finish_switch_fiber()</c> function. In most cases, this
|
||||
/// pointer can be stored on the stack immediately before switching. When
|
||||
/// leaving a fiber definitely, NULL must be passed as the first argument to
|
||||
/// the <c>__sanitizer_start_switch_fiber()</c> function so that the fake stack
|
||||
/// is destroyed. If your program does not need stack use-after-return
|
||||
/// detection, you can always pass NULL to these two functions.
|
||||
///
|
||||
/// \note The fake stack mechanism is disabled during fiber switch, so if a
|
||||
/// signal callback runs during the switch, it will not benefit from stack
|
||||
/// use-after-return detection.
|
||||
///
|
||||
/// \param fake_stack_save [out] Fake stack save location.
|
||||
/// \param bottom Bottom address of stack.
|
||||
/// \param size Size of stack in bytes.
|
||||
void __sanitizer_start_switch_fiber(void **fake_stack_save,
|
||||
const void *bottom, size_t size);
|
||||
|
||||
/// Notify ASan that a fiber switch has completed (required only if
|
||||
/// implementing your own fiber library).
|
||||
///
|
||||
/// When code starts running on the new stack, it must call
|
||||
/// <c>__sanitizer_finish_switch_fiber()</c> to finalize
|
||||
/// the switch. For usage details, see the description of
|
||||
/// <c>__sanitizer_start_switch_fiber()</c>.
|
||||
///
|
||||
/// \param fake_stack_save Fake stack save location.
|
||||
/// \param bottom_old [out] Bottom address of old stack.
|
||||
/// \param size_old [out] Size of old stack in bytes.
|
||||
void __sanitizer_finish_switch_fiber(void *fake_stack_save,
|
||||
const void **bottom_old,
|
||||
size_t *size_old);
|
||||
|
||||
// Get full module name and calculate pc offset within it.
|
||||
// Returns 1 if pc belongs to some module, 0 if module was not found.
|
||||
int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
|
||||
size_t module_path_len,
|
||||
void **pc_offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- sanitizer/coverage_interface.h --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- dfsan_interface.h -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -80,6 +79,12 @@ dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
|
||||
/// Returns the number of labels allocated.
|
||||
size_t dfsan_get_label_count(void);
|
||||
|
||||
/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated
|
||||
/// with the application memory. Will work only if there are no other
|
||||
/// threads executing DFSan-instrumented code concurrently.
|
||||
/// Use this call to start over the taint tracking within the same procces.
|
||||
void dfsan_flush(void);
|
||||
|
||||
/// Sets a callback to be invoked on calls to write(). The callback is invoked
|
||||
/// before the write is done. The write is not guaranteed to succeed when the
|
||||
/// callback executes. Pass in NULL to remove any callback.
|
||||
|
@ -1,50 +0,0 @@
|
||||
//===-- sanitizer/esan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of EfficiencySanitizer, a family of performance tuners.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_ESAN_INTERFACE_H
|
||||
#define SANITIZER_ESAN_INTERFACE_H
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
// We declare our interface routines as weak to allow the user to avoid
|
||||
// ifdefs and instead use this pattern to allow building the same sources
|
||||
// with and without our runtime library:
|
||||
// if (__esan_report)
|
||||
// __esan_report();
|
||||
#ifdef _MSC_VER
|
||||
/* selectany is as close to weak as we'll get. */
|
||||
#define COMPILER_RT_WEAK __declspec(selectany)
|
||||
#elif __GNUC__
|
||||
#define COMPILER_RT_WEAK __attribute__((weak))
|
||||
#else
|
||||
#define COMPILER_RT_WEAK
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This function can be called mid-run (or at the end of a run for
|
||||
// a server process that doesn't shut down normally) to request that
|
||||
// data for that point in the run be reported from the tool.
|
||||
void COMPILER_RT_WEAK __esan_report(void);
|
||||
|
||||
// This function returns the number of samples that the esan tool has collected
|
||||
// to this point. This is useful for testing.
|
||||
unsigned int COMPILER_RT_WEAK __esan_get_sample_count(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_ESAN_INTERFACE_H
|
@ -1,9 +1,8 @@
|
||||
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -19,11 +18,15 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Initialize shadow but not the rest of the runtime.
|
||||
// Libc hook for program startup in statically linked executables.
|
||||
// Initializes enough of the runtime to run instrumented code. This function
|
||||
// should only be called in statically linked executables because it modifies
|
||||
// the GOT, which won't work in regular binaries because RELRO will already
|
||||
// have been applied by the time the function is called. This also means that
|
||||
// the function should be called before libc applies RELRO.
|
||||
// Does not call libc unless there is an error.
|
||||
// Can be called multiple times, or not at all (in which case shadow will
|
||||
// be initialized in compiler-inserted __hwasan_init() call).
|
||||
void __hwasan_shadow_init(void);
|
||||
// Can be called multiple times.
|
||||
void __hwasan_init_static(void);
|
||||
|
||||
// This function may be optionally provided by user and should return
|
||||
// a string containing HWASan runtime options. See asan_flags.h for details.
|
||||
@ -47,6 +50,10 @@ extern "C" {
|
||||
// does would cause false reports.
|
||||
void __hwasan_handle_longjmp(const void *sp_dst);
|
||||
|
||||
// Set memory tag for the part of the current thread stack below sp_dst to
|
||||
// zero. Call this in vfork() before returning in the parent process.
|
||||
void __hwasan_handle_vfork(const void *sp_dst);
|
||||
|
||||
// Libc hook for thread creation. Should be called in the child thread before
|
||||
// any instrumented code.
|
||||
void __hwasan_thread_enter();
|
||||
@ -62,6 +69,10 @@ extern "C" {
|
||||
// Print one-line report about the memory usage of the current process.
|
||||
void __hwasan_print_memory_usage();
|
||||
|
||||
/* Returns the offset of the first byte in the memory range that can not be
|
||||
* accessed through the pointer in x, or -1 if the whole range is good. */
|
||||
intptr_t __hwasan_test_shadow(const volatile void *x, size_t size);
|
||||
|
||||
int __sanitizer_posix_memalign(void **memptr, size_t alignment, size_t size);
|
||||
void * __sanitizer_memalign(size_t alignment, size_t size);
|
||||
void * __sanitizer_aligned_alloc(size_t alignment, size_t size);
|
||||
@ -76,6 +87,7 @@ extern "C" {
|
||||
void __sanitizer_malloc_stats(void);
|
||||
void * __sanitizer_calloc(size_t nmemb, size_t size);
|
||||
void * __sanitizer_realloc(void *ptr, size_t size);
|
||||
void * __sanitizer_reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
void * __sanitizer_malloc(size_t size);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- linux_syscall_hooks.h ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- sanitizer/lsan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- msan_interface.h --------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -43,6 +42,9 @@ extern "C" {
|
||||
contents). */
|
||||
void __msan_unpoison_string(const volatile char *a);
|
||||
|
||||
/* Make first n parameters of the next function call fully initialized. */
|
||||
void __msan_unpoison_param(size_t n);
|
||||
|
||||
/* Make memory region fully uninitialized (without changing its contents).
|
||||
This is a legacy interface that does not update origin information. Use
|
||||
__msan_allocated_memory() instead. */
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- netbsd_syscall_hooks.h --------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- sanitizer/scudo_interface.h -----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -137,6 +136,24 @@ void __tsan_external_assign_tag(void *addr, void *tag);
|
||||
void __tsan_external_read(void *addr, void *caller_pc, void *tag);
|
||||
void __tsan_external_write(void *addr, void *caller_pc, void *tag);
|
||||
|
||||
// Fiber switching API.
|
||||
// - TSAN context for fiber can be created by __tsan_create_fiber
|
||||
// and freed by __tsan_destroy_fiber.
|
||||
// - TSAN context of current fiber or thread can be obtained
|
||||
// by calling __tsan_get_current_fiber.
|
||||
// - __tsan_switch_to_fiber should be called immediatly before switch
|
||||
// to fiber, such as call of swapcontext.
|
||||
// - Fiber name can be set by __tsan_set_fiber_name.
|
||||
void *__tsan_get_current_fiber(void);
|
||||
void *__tsan_create_fiber(unsigned flags);
|
||||
void __tsan_destroy_fiber(void *fiber);
|
||||
void __tsan_switch_to_fiber(void *fiber, unsigned flags);
|
||||
void __tsan_set_fiber_name(void *fiber, const char *name);
|
||||
|
||||
// Flags for __tsan_switch_to_fiber:
|
||||
// Do not establish a happens-before relation between fibers
|
||||
const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- tsan_interface_atomic.h ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -31,7 +30,7 @@ __extension__ typedef __int128 __tsan_atomic128;
|
||||
#endif
|
||||
|
||||
// Part of ABI, do not change.
|
||||
// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup
|
||||
// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic
|
||||
typedef enum {
|
||||
__tsan_memory_order_relaxed,
|
||||
__tsan_memory_order_consume,
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===- xray_interface.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- xray_log_interface.h ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- xray_records.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_activation.cc --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_activation.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_activation_flags.inc -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_allocator.cc -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -880,6 +879,17 @@ void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
|
||||
return SetErrnoOnNull(instance.Calloc(nmemb, size, stack));
|
||||
}
|
||||
|
||||
void *asan_reallocarray(void *p, uptr nmemb, uptr size,
|
||||
BufferedStackTrace *stack) {
|
||||
if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
|
||||
errno = errno_ENOMEM;
|
||||
if (AllocatorMayReturnNull())
|
||||
return nullptr;
|
||||
ReportReallocArrayOverflow(nmemb, size, stack);
|
||||
}
|
||||
return asan_realloc(p, nmemb * size, stack);
|
||||
}
|
||||
|
||||
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
|
||||
if (!p)
|
||||
return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_allocator.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -134,11 +133,15 @@ const uptr kAllocatorSpace = ~(uptr)0;
|
||||
const uptr kAllocatorSize = 0x2000000000ULL; // 128G.
|
||||
typedef VeryCompactSizeClassMap SizeClassMap;
|
||||
# elif defined(__aarch64__)
|
||||
// AArch64/SANITIZER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA
|
||||
// AArch64/SANITIZER_CAN_USE_ALLOCATOR64 is only for 42-bit VMA
|
||||
// so no need to different values for different VMA.
|
||||
const uptr kAllocatorSpace = 0x10000000000ULL;
|
||||
const uptr kAllocatorSize = 0x10000000000ULL; // 3T.
|
||||
typedef DefaultSizeClassMap SizeClassMap;
|
||||
#elif defined(__sparc__)
|
||||
const uptr kAllocatorSpace = ~(uptr)0;
|
||||
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
|
||||
typedef DefaultSizeClassMap SizeClassMap;
|
||||
# elif SANITIZER_WINDOWS
|
||||
const uptr kAllocatorSpace = ~(uptr)0;
|
||||
const uptr kAllocatorSize = 0x8000000000ULL; // 500G
|
||||
@ -163,16 +166,6 @@ template <typename AddressSpaceView>
|
||||
using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
|
||||
using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
|
||||
#else // Fallback to SizeClassAllocator32.
|
||||
static const uptr kRegionSizeLog = 20;
|
||||
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
|
||||
# if SANITIZER_WORDSIZE == 32
|
||||
template <typename AddressSpaceView>
|
||||
using ByteMapASVT = FlatByteMap<kNumRegions, AddressSpaceView>;
|
||||
# elif SANITIZER_WORDSIZE == 64
|
||||
template <typename AddressSpaceView>
|
||||
using ByteMapASVT =
|
||||
TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>;
|
||||
# endif
|
||||
typedef CompactSizeClassMap SizeClassMap;
|
||||
template <typename AddressSpaceViewTy>
|
||||
struct AP32 {
|
||||
@ -180,9 +173,8 @@ struct AP32 {
|
||||
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
|
||||
static const uptr kMetadataSize = 16;
|
||||
typedef __asan::SizeClassMap SizeClassMap;
|
||||
static const uptr kRegionSizeLog = __asan::kRegionSizeLog;
|
||||
static const uptr kRegionSizeLog = 20;
|
||||
using AddressSpaceView = AddressSpaceViewTy;
|
||||
using ByteMap = __asan::ByteMapASVT<AddressSpaceView>;
|
||||
typedef AsanMapUnmapCallback MapUnmapCallback;
|
||||
static const uptr kFlags = 0;
|
||||
};
|
||||
@ -192,21 +184,12 @@ using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
|
||||
#endif // SANITIZER_CAN_USE_ALLOCATOR64
|
||||
|
||||
static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
|
||||
template <typename AddressSpaceView>
|
||||
using AllocatorCacheASVT =
|
||||
SizeClassAllocatorLocalCache<PrimaryAllocatorASVT<AddressSpaceView>>;
|
||||
using AllocatorCache = AllocatorCacheASVT<LocalAddressSpaceView>;
|
||||
|
||||
template <typename AddressSpaceView>
|
||||
using SecondaryAllocatorASVT =
|
||||
LargeMmapAllocator<AsanMapUnmapCallback, DefaultLargeMmapAllocatorPtrArray,
|
||||
AddressSpaceView>;
|
||||
template <typename AddressSpaceView>
|
||||
using AsanAllocatorASVT =
|
||||
CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>,
|
||||
AllocatorCacheASVT<AddressSpaceView>,
|
||||
SecondaryAllocatorASVT<AddressSpaceView>>;
|
||||
CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>>;
|
||||
using AsanAllocator = AsanAllocatorASVT<LocalAddressSpaceView>;
|
||||
using AllocatorCache = AsanAllocator::AllocatorCache;
|
||||
|
||||
struct AsanThreadLocalMallocStorage {
|
||||
uptr quarantine_cache[16];
|
||||
@ -226,6 +209,8 @@ void asan_delete(void *ptr, uptr size, uptr alignment,
|
||||
void *asan_malloc(uptr size, BufferedStackTrace *stack);
|
||||
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
|
||||
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);
|
||||
void *asan_reallocarray(void *p, uptr nmemb, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
void *asan_valloc(uptr size, BufferedStackTrace *stack);
|
||||
void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_debugging.cc -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_descriptions.cc ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_descriptions.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_errors.cc ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -36,7 +35,7 @@ static void OnStackUnwind(const SignalContext &sig,
|
||||
// corresponding code in the sanitizer_common and we use this callback to
|
||||
// print it.
|
||||
static_cast<const ScarinessScoreBase *>(callback_context)->Print();
|
||||
GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast);
|
||||
stack->Unwind(sig.pc, sig.bp, sig.context, fast);
|
||||
}
|
||||
|
||||
void ErrorDeadlySignal::Print() {
|
||||
@ -178,6 +177,19 @@ void ErrorCallocOverflow::Print() {
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorReallocArrayOverflow::Print() {
|
||||
Decorator d;
|
||||
Printf("%s", d.Error());
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: reallocarray parameters overflow: count * size "
|
||||
"(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
|
||||
count, size, AsanThreadIdAndName(tid).c_str());
|
||||
Printf("%s", d.Default());
|
||||
stack->Print();
|
||||
PrintHintAllocatorCannotReturnNull();
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorPvallocOverflow::Print() {
|
||||
Decorator d;
|
||||
Printf("%s", d.Error());
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_errors.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -164,6 +163,21 @@ struct ErrorCallocOverflow : ErrorBase {
|
||||
void Print();
|
||||
};
|
||||
|
||||
struct ErrorReallocArrayOverflow : ErrorBase {
|
||||
const BufferedStackTrace *stack;
|
||||
uptr count;
|
||||
uptr size;
|
||||
|
||||
ErrorReallocArrayOverflow() = default; // (*)
|
||||
ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
|
||||
uptr size_)
|
||||
: ErrorBase(tid, 10, "reallocarray-overflow"),
|
||||
stack(stack_),
|
||||
count(count_),
|
||||
size(size_) {}
|
||||
void Print();
|
||||
};
|
||||
|
||||
struct ErrorPvallocOverflow : ErrorBase {
|
||||
const BufferedStackTrace *stack;
|
||||
uptr size;
|
||||
@ -372,6 +386,7 @@ struct ErrorGeneric : ErrorBase {
|
||||
macro(MallocUsableSizeNotOwned) \
|
||||
macro(SanitizerGetAllocatedSizeNotOwned) \
|
||||
macro(CallocOverflow) \
|
||||
macro(ReallocArrayOverflow) \
|
||||
macro(PvallocOverflow) \
|
||||
macro(InvalidAllocationAlignment) \
|
||||
macro(InvalidAlignedAllocAlignment) \
|
||||
@ -389,8 +404,10 @@ struct ErrorGeneric : ErrorBase {
|
||||
|
||||
#define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
|
||||
#define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
|
||||
#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
|
||||
ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
|
||||
#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
|
||||
ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \
|
||||
internal_memcpy(&name, &e, sizeof(name)); \
|
||||
}
|
||||
#define ASAN_ERROR_DESCRIPTION_PRINT(name) \
|
||||
case kErrorKind##name: \
|
||||
return name.Print();
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_fake_stack.cc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_fake_stack.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_flags.cc -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -121,12 +120,12 @@ void InitializeFlags() {
|
||||
#endif
|
||||
|
||||
// Override from command line.
|
||||
asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
|
||||
asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
|
||||
#if CAN_SANITIZE_LEAKS
|
||||
lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
|
||||
lsan_parser.ParseStringFromEnv("LSAN_OPTIONS");
|
||||
#endif
|
||||
#if CAN_SANITIZE_UB
|
||||
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
|
||||
ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
|
||||
#endif
|
||||
|
||||
InitializeCommonFlags();
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_flags.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_flags.inc ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -159,3 +158,5 @@ ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true,
|
||||
ASAN_FLAG(bool, verify_asan_link_order, true,
|
||||
"Check position of ASan runtime in library list (needs to be disabled"
|
||||
" when other library has to be preloaded system-wide)")
|
||||
ASAN_FLAG(bool, windows_hook_rtl_allocators, false,
|
||||
"(Windows only) enable hooking of Rtl(Allocate|Free|Size|ReAllocate)Heap.")
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_fuchsia.cc --------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
//
|
||||
@ -179,7 +178,7 @@ static void ThreadStartHook(void *hook, uptr os_id) {
|
||||
SetCurrentThread(thread);
|
||||
|
||||
// In lieu of AsanThread::ThreadStart.
|
||||
asanThreadRegistry().StartThread(thread->tid(), os_id, /*workerthread*/ false,
|
||||
asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_globals.cc ---------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -116,11 +115,12 @@ int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
|
||||
if (flags()->report_globals >= 2)
|
||||
ReportGlobal(g, "Search");
|
||||
if (IsAddressNearGlobal(addr, g)) {
|
||||
globals[res] = g;
|
||||
internal_memcpy(&globals[res], &g, sizeof(g));
|
||||
if (reg_sites)
|
||||
reg_sites[res] = FindRegistrationSite(&g);
|
||||
res++;
|
||||
if (res == max_globals) break;
|
||||
if (res == max_globals)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_globals_win.cc -----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_init_version.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interceptors.cc ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -580,6 +579,11 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
|
||||
}
|
||||
#endif // ASAN_INTERCEPT___CXA_ATEXIT
|
||||
|
||||
#if ASAN_INTERCEPT_VFORK
|
||||
DEFINE_REAL(int, vfork)
|
||||
DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork)
|
||||
#endif
|
||||
|
||||
// ---------------------- InitializeAsanInterceptors ---------------- {{{1
|
||||
namespace __asan {
|
||||
void InitializeAsanInterceptors() {
|
||||
@ -657,6 +661,10 @@ void InitializeAsanInterceptors() {
|
||||
ASAN_INTERCEPT_FUNC(__cxa_atexit);
|
||||
#endif
|
||||
|
||||
#if ASAN_INTERCEPT_VFORK
|
||||
ASAN_INTERCEPT_FUNC(vfork);
|
||||
#endif
|
||||
|
||||
InitializePlatformInterceptors();
|
||||
|
||||
VReport(1, "AddressSanitizer: libc interceptors initialized\n");
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interceptors.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -106,6 +105,13 @@ void InitializePlatformInterceptors();
|
||||
# define ASAN_INTERCEPT___STRDUP 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__) || \
|
||||
defined(__i386__) || defined(__x86_64__))
|
||||
# define ASAN_INTERCEPT_VFORK 1
|
||||
#else
|
||||
# define ASAN_INTERCEPT_VFORK 0
|
||||
#endif
|
||||
|
||||
DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
|
||||
DECLARE_REAL(char*, strchr, const char *str, int c)
|
||||
DECLARE_REAL(SIZE_T, strlen, const char *s)
|
||||
@ -114,16 +120,16 @@ DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)
|
||||
DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
|
||||
|
||||
#if !SANITIZER_MAC
|
||||
#define ASAN_INTERCEPT_FUNC(name) \
|
||||
do { \
|
||||
if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \
|
||||
VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
|
||||
#define ASAN_INTERCEPT_FUNC(name) \
|
||||
do { \
|
||||
if (!INTERCEPT_FUNCTION(name)) \
|
||||
VReport(1, "AddressSanitizer: failed to intercept '%s'\n'", #name); \
|
||||
} while (0)
|
||||
#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
|
||||
do { \
|
||||
if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \
|
||||
VReport( \
|
||||
1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
|
||||
#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
|
||||
do { \
|
||||
if (!INTERCEPT_FUNCTION_VER(name, ver)) \
|
||||
VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", #name, \
|
||||
#ver); \
|
||||
} while (0)
|
||||
#else
|
||||
// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interceptors_memintrinsics.cc --------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interceptors_memintrinsics.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
//
|
||||
|
12
lib/asan/asan_interceptors_vfork.S
Normal file
12
lib/asan/asan_interceptors_vfork.S
Normal file
@ -0,0 +1,12 @@
|
||||
#include "sanitizer_common/sanitizer_asm.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#define COMMON_INTERCEPTOR_SPILL_AREA __asan_extra_spill_area
|
||||
#define COMMON_INTERCEPTOR_HANDLE_VFORK __asan_handle_vfork
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S"
|
||||
#endif
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interface.inc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Asan interface list.
|
||||
@ -39,6 +38,7 @@ INTERFACE_FUNCTION(__asan_get_report_pc)
|
||||
INTERFACE_FUNCTION(__asan_get_report_sp)
|
||||
INTERFACE_FUNCTION(__asan_get_shadow_mapping)
|
||||
INTERFACE_FUNCTION(__asan_handle_no_return)
|
||||
INTERFACE_FUNCTION(__asan_handle_vfork)
|
||||
INTERFACE_FUNCTION(__asan_init)
|
||||
INTERFACE_FUNCTION(__asan_load_cxx_array_cookie)
|
||||
INTERFACE_FUNCTION(__asan_load1)
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interface_internal.h -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -250,6 +249,8 @@ extern "C" {
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
|
||||
const char* __asan_default_suppressions();
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp);
|
||||
} // extern "C"
|
||||
|
||||
#endif // ASAN_INTERFACE_INTERNAL_H
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_internal.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_linux.cc -----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_mac.cc -------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -182,8 +181,8 @@ void asan_register_worker_thread(int parent_tid, StackTrace *stack) {
|
||||
t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,
|
||||
parent_tid, stack, /* detached */ true);
|
||||
t->Init();
|
||||
asanThreadRegistry().StartThread(t->tid(), GetTid(),
|
||||
/* workerthread */ true, 0);
|
||||
asanThreadRegistry().StartThread(t->tid(), GetTid(), ThreadType::Worker,
|
||||
nullptr);
|
||||
SetCurrentThread(t);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_malloc_linux.cc ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -166,6 +165,14 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
|
||||
return asan_realloc(ptr, size, &stack);
|
||||
}
|
||||
|
||||
#if SANITIZER_INTERCEPT_REALLOCARRAY
|
||||
INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
|
||||
ENSURE_ASAN_INITED();
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
return asan_reallocarray(ptr, nmemb, size, &stack);
|
||||
}
|
||||
#endif // SANITIZER_INTERCEPT_REALLOCARRAY
|
||||
|
||||
#if SANITIZER_INTERCEPT_MEMALIGN
|
||||
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_malloc_local.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -18,25 +17,34 @@
|
||||
#include "sanitizer_common/sanitizer_platform.h"
|
||||
#include "asan_internal.h"
|
||||
|
||||
// On RTEMS, we use the local pool to handle memory allocation when the ASan
|
||||
// run-time is not up.
|
||||
static INLINE bool EarlyMalloc() {
|
||||
return SANITIZER_RTEMS && (!__asan::asan_inited ||
|
||||
__asan::asan_init_is_running);
|
||||
return SANITIZER_RTEMS &&
|
||||
(!__asan::asan_inited || __asan::asan_init_is_running);
|
||||
}
|
||||
|
||||
void* MemalignFromLocalPool(uptr alignment, uptr size);
|
||||
|
||||
#if SANITIZER_RTEMS
|
||||
|
||||
bool IsFromLocalPool(const void *ptr);
|
||||
void *MemalignFromLocalPool(uptr alignment, uptr size);
|
||||
|
||||
// On RTEMS, we use the local pool to handle memory allocation when the ASan
|
||||
// run-time is not up. This macro is expanded in the context of the operator new
|
||||
// implementation.
|
||||
#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow) \
|
||||
do { \
|
||||
if (UNLIKELY(EarlyMalloc())) { \
|
||||
void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size); \
|
||||
if (!nothrow) \
|
||||
CHECK(res); \
|
||||
return res; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ALLOCATE_FROM_LOCAL_POOL UNLIKELY(EarlyMalloc())
|
||||
#define IS_FROM_LOCAL_POOL(ptr) UNLIKELY(IsFromLocalPool(ptr))
|
||||
|
||||
#else // SANITIZER_RTEMS
|
||||
|
||||
#define ALLOCATE_FROM_LOCAL_POOL 0
|
||||
#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow)
|
||||
#define IS_FROM_LOCAL_POOL(ptr) 0
|
||||
|
||||
#endif // SANITIZER_RTEMS
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_malloc_mac.cc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -19,6 +18,7 @@
|
||||
#include "asan_report.h"
|
||||
#include "asan_stack.h"
|
||||
#include "asan_stats.h"
|
||||
#include "lsan/lsan_common.h"
|
||||
|
||||
using namespace __asan;
|
||||
#define COMMON_MALLOC_ZONE_NAME "asan"
|
||||
@ -58,10 +58,13 @@ using namespace __asan;
|
||||
GET_STACK_TRACE_FREE; \
|
||||
ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
|
||||
#define COMMON_MALLOC_NAMESPACE __asan
|
||||
#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
|
||||
#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 1
|
||||
|
||||
#include "sanitizer_common/sanitizer_malloc_mac.inc"
|
||||
|
||||
namespace COMMON_MALLOC_NAMESPACE {
|
||||
|
||||
bool HandleDlopenInit() {
|
||||
static_assert(SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
|
||||
"Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be true");
|
||||
@ -82,4 +85,18 @@ bool HandleDlopenInit() {
|
||||
}
|
||||
} // namespace COMMON_MALLOC_NAMESPACE
|
||||
|
||||
namespace {
|
||||
|
||||
void mi_extra_init(sanitizer_malloc_introspection_t *mi) {
|
||||
uptr last_byte_plus_one = 0;
|
||||
mi->allocator_ptr = 0;
|
||||
// Range is [begin_ptr, end_ptr)
|
||||
__lsan::GetAllocatorGlobalRange(&(mi->allocator_ptr), &last_byte_plus_one);
|
||||
CHECK_NE(mi->allocator_ptr, 0);
|
||||
CHECK_GT(last_byte_plus_one, mi->allocator_ptr);
|
||||
mi->allocator_size = last_byte_plus_one - (mi->allocator_ptr);
|
||||
CHECK_GT(mi->allocator_size, 0);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_malloc_win.cc ------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -12,8 +11,16 @@
|
||||
// Windows-specific malloc interception.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_common/sanitizer_allocator_interface.h"
|
||||
#include "sanitizer_common/sanitizer_platform.h"
|
||||
#if SANITIZER_WINDOWS
|
||||
#include "asan_allocator.h"
|
||||
#include "asan_interceptors.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_stack.h"
|
||||
#include "interception/interception.h"
|
||||
#include <stddef.h>
|
||||
|
||||
// Intentionally not including windows.h here, to avoid the risk of
|
||||
// pulling in conflicting declarations of these functions. (With mingw-w64,
|
||||
// there's a risk of windows.h pulling in stdint.h.)
|
||||
@ -22,17 +29,30 @@ typedef void *HANDLE;
|
||||
typedef const void *LPCVOID;
|
||||
typedef void *LPVOID;
|
||||
|
||||
#define HEAP_ZERO_MEMORY 0x00000008
|
||||
#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
|
||||
typedef unsigned long DWORD;
|
||||
constexpr unsigned long HEAP_ZERO_MEMORY = 0x00000008;
|
||||
constexpr unsigned long HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
|
||||
constexpr unsigned long HEAP_ALLOCATE_SUPPORTED_FLAGS = (HEAP_ZERO_MEMORY);
|
||||
constexpr unsigned long HEAP_ALLOCATE_UNSUPPORTED_FLAGS =
|
||||
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
|
||||
constexpr unsigned long HEAP_FREE_SUPPORTED_FLAGS = (0);
|
||||
constexpr unsigned long HEAP_FREE_UNSUPPORTED_FLAGS =
|
||||
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
|
||||
constexpr unsigned long HEAP_REALLOC_SUPPORTED_FLAGS =
|
||||
(HEAP_REALLOC_IN_PLACE_ONLY | HEAP_ZERO_MEMORY);
|
||||
constexpr unsigned long HEAP_REALLOC_UNSUPPORTED_FLAGS =
|
||||
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
|
||||
|
||||
|
||||
#include "asan_allocator.h"
|
||||
#include "asan_interceptors.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_stack.h"
|
||||
#include "interception/interception.h"
|
||||
extern "C" {
|
||||
LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, size_t dwBytes);
|
||||
LPVOID WINAPI HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem,
|
||||
size_t dwBytes);
|
||||
BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
|
||||
size_t WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
|
||||
|
||||
#include <stddef.h>
|
||||
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
|
||||
}
|
||||
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
@ -48,6 +68,18 @@ using namespace __asan; // NOLINT
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
size_t _msize(void *ptr) {
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
return asan_malloc_usable_size(ptr, pc, bp);
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
size_t _msize_base(void *ptr) {
|
||||
return _msize(ptr);
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
void free(void *ptr) {
|
||||
GET_STACK_TRACE_FREE;
|
||||
@ -125,7 +157,16 @@ void *_recalloc(void *p, size_t n, size_t elem_size) {
|
||||
const size_t size = n * elem_size;
|
||||
if (elem_size != 0 && size / elem_size != n)
|
||||
return 0;
|
||||
return realloc(p, size);
|
||||
|
||||
size_t old_size = _msize(p);
|
||||
void *new_alloc = malloc(size);
|
||||
if (new_alloc) {
|
||||
REAL(memcpy)(new_alloc, p, Min<size_t>(size, old_size));
|
||||
if (old_size < size)
|
||||
REAL(memset)(((u8 *)new_alloc) + old_size, 0, size - old_size);
|
||||
free(p);
|
||||
}
|
||||
return new_alloc;
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
@ -133,18 +174,6 @@ void *_recalloc_base(void *p, size_t n, size_t elem_size) {
|
||||
return _recalloc(p, n, elem_size);
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
size_t _msize(void *ptr) {
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
return asan_malloc_usable_size(ptr, pc, bp);
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
size_t _msize_base(void *ptr) {
|
||||
return _msize(ptr);
|
||||
}
|
||||
|
||||
ALLOCATION_FUNCTION_ATTRIBUTE
|
||||
void *_expand(void *memblock, size_t size) {
|
||||
// _expand is used in realloc-like functions to resize the buffer if possible.
|
||||
@ -175,43 +204,280 @@ int _CrtSetReportMode(int, int) {
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
#define OWNED_BY_RTL(heap, memory) \
|
||||
(!__sanitizer_get_ownership(memory) && HeapValidate(heap, 0, memory))
|
||||
|
||||
INTERCEPTOR_WINAPI(size_t, HeapSize, HANDLE hHeap, DWORD dwFlags,
|
||||
LPCVOID lpMem) {
|
||||
// If the RTL allocators are hooked we need to check whether the ASAN
|
||||
// allocator owns the pointer we're about to use. Allocations occur before
|
||||
// interception takes place, so if it is not owned by the RTL heap we can
|
||||
// pass it to the ASAN heap for inspection.
|
||||
if (flags()->windows_hook_rtl_allocators) {
|
||||
if (!asan_inited || OWNED_BY_RTL(hHeap, lpMem))
|
||||
return REAL(HeapSize)(hHeap, dwFlags, lpMem);
|
||||
} else {
|
||||
CHECK(dwFlags == 0 && "unsupported heap flags");
|
||||
}
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
return asan_malloc_usable_size(lpMem, pc, bp);
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags,
|
||||
SIZE_T dwBytes) {
|
||||
size_t dwBytes) {
|
||||
// If the ASAN runtime is not initialized, or we encounter an unsupported
|
||||
// flag, fall back to the original allocator.
|
||||
if (flags()->windows_hook_rtl_allocators) {
|
||||
if (UNLIKELY(!asan_inited ||
|
||||
(dwFlags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) {
|
||||
return REAL(HeapAlloc)(hHeap, dwFlags, dwBytes);
|
||||
}
|
||||
} else {
|
||||
// In the case that we don't hook the rtl allocators,
|
||||
// this becomes an assert since there is no failover to the original
|
||||
// allocator.
|
||||
CHECK((HEAP_ALLOCATE_UNSUPPORTED_FLAGS & dwFlags) != 0 &&
|
||||
"unsupported flags");
|
||||
}
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
void *p = asan_malloc(dwBytes, &stack);
|
||||
// Reading MSDN suggests that the *entire* usable allocation is zeroed out.
|
||||
// Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
|
||||
// https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
|
||||
if (dwFlags == HEAP_ZERO_MEMORY)
|
||||
internal_memset(p, 0, asan_mz_size(p));
|
||||
else
|
||||
CHECK(dwFlags == 0 && "unsupported heap flags");
|
||||
if (p && (dwFlags & HEAP_ZERO_MEMORY)) {
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
auto usable_size = asan_malloc_usable_size(p, pc, bp);
|
||||
internal_memset(p, 0, usable_size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
|
||||
CHECK(dwFlags == 0 && "unsupported heap flags");
|
||||
// Heap allocations happen before this function is hooked, so we must fall
|
||||
// back to the original function if the pointer is not from the ASAN heap,
|
||||
// or unsupported flags are provided.
|
||||
if (flags()->windows_hook_rtl_allocators) {
|
||||
if (OWNED_BY_RTL(hHeap, lpMem))
|
||||
return REAL(HeapFree)(hHeap, dwFlags, lpMem);
|
||||
} else {
|
||||
CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags");
|
||||
}
|
||||
GET_STACK_TRACE_FREE;
|
||||
asan_free(lpMem, &stack, FROM_MALLOC);
|
||||
return true;
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags,
|
||||
LPVOID lpMem, SIZE_T dwBytes) {
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
// Realloc should never reallocate in place.
|
||||
if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
|
||||
return nullptr;
|
||||
CHECK(dwFlags == 0 && "unsupported heap flags");
|
||||
return asan_realloc(lpMem, dwBytes, &stack);
|
||||
}
|
||||
namespace __asan {
|
||||
using AllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, size_t);
|
||||
using ReAllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, LPVOID, size_t);
|
||||
using SizeFunction = size_t(WINAPI *)(HANDLE, DWORD, LPVOID);
|
||||
using FreeFunction = BOOL(WINAPI *)(HANDLE, DWORD, LPVOID);
|
||||
|
||||
INTERCEPTOR_WINAPI(SIZE_T, HeapSize, HANDLE hHeap, DWORD dwFlags,
|
||||
LPCVOID lpMem) {
|
||||
CHECK(dwFlags == 0 && "unsupported heap flags");
|
||||
void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
|
||||
FreeFunction freeFunc, AllocFunction allocFunc,
|
||||
HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, size_t dwBytes) {
|
||||
CHECK(reallocFunc && heapSizeFunc && freeFunc && allocFunc);
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
return asan_malloc_usable_size(lpMem, pc, bp);
|
||||
if (flags()->windows_hook_rtl_allocators) {
|
||||
enum AllocationOwnership { NEITHER = 0, ASAN = 1, RTL = 2 };
|
||||
AllocationOwnership ownershipState;
|
||||
bool owned_rtlalloc = false;
|
||||
bool owned_asan = __sanitizer_get_ownership(lpMem);
|
||||
|
||||
if (!owned_asan)
|
||||
owned_rtlalloc = HeapValidate(hHeap, 0, lpMem);
|
||||
|
||||
if (owned_asan && !owned_rtlalloc)
|
||||
ownershipState = ASAN;
|
||||
else if (!owned_asan && owned_rtlalloc)
|
||||
ownershipState = RTL;
|
||||
else if (!owned_asan && !owned_rtlalloc)
|
||||
ownershipState = NEITHER;
|
||||
|
||||
// If this heap block which was allocated before the ASAN
|
||||
// runtime came up, use the real HeapFree function.
|
||||
if (UNLIKELY(!asan_inited)) {
|
||||
return reallocFunc(hHeap, dwFlags, lpMem, dwBytes);
|
||||
}
|
||||
bool only_asan_supported_flags =
|
||||
(HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) == 0;
|
||||
|
||||
if (ownershipState == RTL ||
|
||||
(ownershipState == NEITHER && !only_asan_supported_flags)) {
|
||||
if (only_asan_supported_flags) {
|
||||
// if this is a conversion to ASAN upported flags, transfer this
|
||||
// allocation to the ASAN allocator
|
||||
void *replacement_alloc;
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
replacement_alloc = asan_calloc(1, dwBytes, &stack);
|
||||
else
|
||||
replacement_alloc = asan_malloc(dwBytes, &stack);
|
||||
if (replacement_alloc) {
|
||||
size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem);
|
||||
if (old_size == ((size_t)0) - 1) {
|
||||
asan_free(replacement_alloc, &stack, FROM_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
REAL(memcpy)(replacement_alloc, lpMem, old_size);
|
||||
freeFunc(hHeap, dwFlags, lpMem);
|
||||
}
|
||||
return replacement_alloc;
|
||||
} else {
|
||||
// owned by rtl or neither with unsupported ASAN flags,
|
||||
// just pass back to original allocator
|
||||
CHECK(ownershipState == RTL || ownershipState == NEITHER);
|
||||
CHECK(!only_asan_supported_flags);
|
||||
return reallocFunc(hHeap, dwFlags, lpMem, dwBytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (ownershipState == ASAN && !only_asan_supported_flags) {
|
||||
// Conversion to unsupported flags allocation,
|
||||
// transfer this allocation back to the original allocator.
|
||||
void *replacement_alloc = allocFunc(hHeap, dwFlags, dwBytes);
|
||||
size_t old_usable_size = 0;
|
||||
if (replacement_alloc) {
|
||||
old_usable_size = asan_malloc_usable_size(lpMem, pc, bp);
|
||||
REAL(memcpy)(replacement_alloc, lpMem,
|
||||
Min<size_t>(dwBytes, old_usable_size));
|
||||
asan_free(lpMem, &stack, FROM_MALLOC);
|
||||
}
|
||||
return replacement_alloc;
|
||||
}
|
||||
|
||||
CHECK((ownershipState == ASAN || ownershipState == NEITHER) &&
|
||||
only_asan_supported_flags);
|
||||
// At this point we should either be ASAN owned with ASAN supported flags
|
||||
// or we owned by neither and have supported flags.
|
||||
// Pass through even when it's neither since this could be a null realloc or
|
||||
// UAF that ASAN needs to catch.
|
||||
} else {
|
||||
CHECK((HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) != 0 &&
|
||||
"unsupported flags");
|
||||
}
|
||||
// asan_realloc will never reallocate in place, so for now this flag is
|
||||
// unsupported until we figure out a way to fake this.
|
||||
if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
|
||||
return nullptr;
|
||||
|
||||
// HeapReAlloc and HeapAlloc both happily accept 0 sized allocations.
|
||||
// passing a 0 size into asan_realloc will free the allocation.
|
||||
// To avoid this and keep behavior consistent, fudge the size if 0.
|
||||
// (asan_malloc already does this)
|
||||
if (dwBytes == 0)
|
||||
dwBytes = 1;
|
||||
|
||||
size_t old_size;
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
old_size = asan_malloc_usable_size(lpMem, pc, bp);
|
||||
|
||||
void *ptr = asan_realloc(lpMem, dwBytes, &stack);
|
||||
if (ptr == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (dwFlags & HEAP_ZERO_MEMORY) {
|
||||
size_t new_size = asan_malloc_usable_size(ptr, pc, bp);
|
||||
if (old_size < new_size)
|
||||
REAL(memset)(((u8 *)ptr) + old_size, 0, new_size - old_size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
} // namespace __asan
|
||||
|
||||
INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags,
|
||||
LPVOID lpMem, size_t dwBytes) {
|
||||
return SharedReAlloc(REAL(HeapReAlloc), (SizeFunction)REAL(HeapSize),
|
||||
REAL(HeapFree), REAL(HeapAlloc), hHeap, dwFlags, lpMem,
|
||||
dwBytes);
|
||||
}
|
||||
|
||||
// The following functions are undocumented and subject to change.
|
||||
// However, hooking them is necessary to hook Windows heap
|
||||
// allocations with detours and their definitions are unlikely to change.
|
||||
// Comments in /minkernel/ntos/rtl/heappublic.c indicate that these functions
|
||||
// are part of the heap's public interface.
|
||||
typedef unsigned long LOGICAL;
|
||||
|
||||
// This function is documented as part of the Driver Development Kit but *not*
|
||||
// the Windows Development Kit.
|
||||
LOGICAL RtlFreeHeap(void* HeapHandle, DWORD Flags,
|
||||
void* BaseAddress);
|
||||
|
||||
// This function is documented as part of the Driver Development Kit but *not*
|
||||
// the Windows Development Kit.
|
||||
void* RtlAllocateHeap(void* HeapHandle, DWORD Flags, size_t Size);
|
||||
|
||||
// This function is completely undocumented.
|
||||
void*
|
||||
RtlReAllocateHeap(void* HeapHandle, DWORD Flags, void* BaseAddress,
|
||||
size_t Size);
|
||||
|
||||
// This function is completely undocumented.
|
||||
size_t RtlSizeHeap(void* HeapHandle, DWORD Flags, void* BaseAddress);
|
||||
|
||||
INTERCEPTOR_WINAPI(size_t, RtlSizeHeap, HANDLE HeapHandle, DWORD Flags,
|
||||
void* BaseAddress) {
|
||||
if (!flags()->windows_hook_rtl_allocators ||
|
||||
UNLIKELY(!asan_inited || OWNED_BY_RTL(HeapHandle, BaseAddress))) {
|
||||
return REAL(RtlSizeHeap)(HeapHandle, Flags, BaseAddress);
|
||||
}
|
||||
GET_CURRENT_PC_BP_SP;
|
||||
(void)sp;
|
||||
return asan_malloc_usable_size(BaseAddress, pc, bp);
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags,
|
||||
void* BaseAddress) {
|
||||
// Heap allocations happen before this function is hooked, so we must fall
|
||||
// back to the original function if the pointer is not from the ASAN heap, or
|
||||
// unsupported flags are provided.
|
||||
if (!flags()->windows_hook_rtl_allocators ||
|
||||
UNLIKELY((HEAP_FREE_UNSUPPORTED_FLAGS & Flags) != 0 ||
|
||||
OWNED_BY_RTL(HeapHandle, BaseAddress))) {
|
||||
return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress);
|
||||
}
|
||||
GET_STACK_TRACE_FREE;
|
||||
asan_free(BaseAddress, &stack, FROM_MALLOC);
|
||||
return true;
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(void*, RtlAllocateHeap, HANDLE HeapHandle, DWORD Flags,
|
||||
size_t Size) {
|
||||
// If the ASAN runtime is not initialized, or we encounter an unsupported
|
||||
// flag, fall back to the original allocator.
|
||||
if (!flags()->windows_hook_rtl_allocators ||
|
||||
UNLIKELY(!asan_inited ||
|
||||
(Flags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) {
|
||||
return REAL(RtlAllocateHeap)(HeapHandle, Flags, Size);
|
||||
}
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
void *p;
|
||||
// Reading MSDN suggests that the *entire* usable allocation is zeroed out.
|
||||
// Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
|
||||
// https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
|
||||
if (Flags & HEAP_ZERO_MEMORY) {
|
||||
p = asan_calloc(Size, 1, &stack);
|
||||
} else {
|
||||
p = asan_malloc(Size, &stack);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(void*, RtlReAllocateHeap, HANDLE HeapHandle, DWORD Flags,
|
||||
void* BaseAddress, size_t Size) {
|
||||
// If it's actually a heap block which was allocated before the ASAN runtime
|
||||
// came up, use the real RtlFreeHeap function.
|
||||
if (!flags()->windows_hook_rtl_allocators)
|
||||
return REAL(RtlReAllocateHeap)(HeapHandle, Flags, BaseAddress, Size);
|
||||
|
||||
return SharedReAlloc(REAL(RtlReAllocateHeap), REAL(RtlSizeHeap),
|
||||
REAL(RtlFreeHeap), REAL(RtlAllocateHeap), HeapHandle,
|
||||
Flags, BaseAddress, Size);
|
||||
}
|
||||
|
||||
namespace __asan {
|
||||
@ -244,6 +510,34 @@ void ReplaceSystemMalloc() {
|
||||
TryToOverrideFunction("_expand", (uptr)_expand);
|
||||
TryToOverrideFunction("_expand_base", (uptr)_expand);
|
||||
|
||||
if (flags()->windows_hook_rtl_allocators) {
|
||||
INTERCEPT_FUNCTION(HeapSize);
|
||||
INTERCEPT_FUNCTION(HeapFree);
|
||||
INTERCEPT_FUNCTION(HeapReAlloc);
|
||||
INTERCEPT_FUNCTION(HeapAlloc);
|
||||
|
||||
// Undocumented functions must be intercepted by name, not by symbol.
|
||||
__interception::OverrideFunction("RtlSizeHeap", (uptr)WRAP(RtlSizeHeap),
|
||||
(uptr *)&REAL(RtlSizeHeap));
|
||||
__interception::OverrideFunction("RtlFreeHeap", (uptr)WRAP(RtlFreeHeap),
|
||||
(uptr *)&REAL(RtlFreeHeap));
|
||||
__interception::OverrideFunction("RtlReAllocateHeap",
|
||||
(uptr)WRAP(RtlReAllocateHeap),
|
||||
(uptr *)&REAL(RtlReAllocateHeap));
|
||||
__interception::OverrideFunction("RtlAllocateHeap",
|
||||
(uptr)WRAP(RtlAllocateHeap),
|
||||
(uptr *)&REAL(RtlAllocateHeap));
|
||||
} else {
|
||||
#define INTERCEPT_UCRT_FUNCTION(func) \
|
||||
if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \
|
||||
"api-ms-win-core-heap-l1-1-0.dll", func)) \
|
||||
VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapAlloc);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapFree);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapReAlloc);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapSize);
|
||||
#undef INTERCEPT_UCRT_FUNCTION
|
||||
}
|
||||
// Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which
|
||||
// enable cross-module inlining. This means our _malloc_base hook won't catch
|
||||
// all CRT allocations. This code here patches the import table of
|
||||
@ -251,16 +545,8 @@ void ReplaceSystemMalloc() {
|
||||
// allocation API will be directed to ASan's heap. We don't currently
|
||||
// intercept all calls to HeapAlloc. If we did, we would have to check on
|
||||
// HeapFree whether the pointer came from ASan of from the system.
|
||||
#define INTERCEPT_UCRT_FUNCTION(func) \
|
||||
if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \
|
||||
"api-ms-win-core-heap-l1-1-0.dll", func)) \
|
||||
VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapAlloc);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapFree);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapReAlloc);
|
||||
INTERCEPT_UCRT_FUNCTION(HeapSize);
|
||||
#undef INTERCEPT_UCRT_FUNCTION
|
||||
#endif
|
||||
|
||||
#endif // defined(ASAN_DYNAMIC)
|
||||
}
|
||||
} // namespace __asan
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -101,6 +100,13 @@
|
||||
// || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow ||
|
||||
// || `[0x00000000000000, 0x0fffffffffffff]` || LowMem ||
|
||||
//
|
||||
// Default Linux/SPARC64 (52-bit VMA) mapping:
|
||||
// || `[0x8000000000000, 0xfffffffffffff]` || HighMem ||
|
||||
// || `[0x1080000000000, 0x207ffffffffff]` || HighShadow ||
|
||||
// || `[0x0090000000000, 0x107ffffffffff]` || ShadowGap ||
|
||||
// || `[0x0080000000000, 0x008ffffffffff]` || LowShadow ||
|
||||
// || `[0x0000000000000, 0x007ffffffffff]` || LowMem ||
|
||||
//
|
||||
// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
|
||||
// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
|
||||
// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
|
||||
@ -154,15 +160,12 @@ static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000
|
||||
static const u64 kDefaultShadowOffset64 = 1ULL << 44;
|
||||
static const u64 kDefaultShort64bitShadowOffset =
|
||||
0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G.
|
||||
static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
|
||||
static const u64 kIosShadowOffset64 = 0x120200000;
|
||||
static const u64 kIosSimShadowOffset32 = 1ULL << 30;
|
||||
static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
|
||||
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
|
||||
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
|
||||
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
|
||||
static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
|
||||
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
|
||||
static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000
|
||||
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
|
||||
static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
|
||||
static const u64 kNetBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
|
||||
@ -194,11 +197,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
|
||||
# elif SANITIZER_WINDOWS
|
||||
# define SHADOW_OFFSET kWindowsShadowOffset32
|
||||
# elif SANITIZER_IOS
|
||||
# if SANITIZER_IOSSIM
|
||||
# define SHADOW_OFFSET kIosSimShadowOffset32
|
||||
# else
|
||||
# define SHADOW_OFFSET kIosShadowOffset32
|
||||
# endif
|
||||
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
|
||||
# elif SANITIZER_MYRIAD2
|
||||
# define SHADOW_OFFSET kMyriadShadowOffset32
|
||||
# else
|
||||
@ -206,11 +205,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
|
||||
# endif
|
||||
#else
|
||||
# if SANITIZER_IOS
|
||||
# if SANITIZER_IOSSIM
|
||||
# define SHADOW_OFFSET kIosSimShadowOffset64
|
||||
# else
|
||||
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
|
||||
# endif
|
||||
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
|
||||
# elif defined(__aarch64__)
|
||||
# define SHADOW_OFFSET kAArch64_ShadowOffset64
|
||||
# elif defined(__powerpc64__)
|
||||
@ -225,6 +220,8 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
|
||||
# define SHADOW_OFFSET kDefaultShadowOffset64
|
||||
# elif defined(__mips64)
|
||||
# define SHADOW_OFFSET kMIPS64_ShadowOffset64
|
||||
#elif defined(__sparc__)
|
||||
#define SHADOW_OFFSET kSPARC64_ShadowOffset64
|
||||
# elif SANITIZER_WINDOWS64
|
||||
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
|
||||
# else
|
||||
@ -271,6 +268,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
|
||||
|
||||
#if SANITIZER_MYRIAD2
|
||||
#include "asan_mapping_myriad.h"
|
||||
#elif defined(__sparc__) && SANITIZER_WORDSIZE == 64
|
||||
#include "asan_mapping_sparc64.h"
|
||||
#else
|
||||
#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_mapping_myriad.h -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
101
lib/asan/asan_mapping_sparc64.h
Normal file
101
lib/asan/asan_mapping_sparc64.h
Normal file
@ -0,0 +1,101 @@
|
||||
//===-- asan_mapping_sparc64.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// SPARC64-specific definitions for ASan memory mapping.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef ASAN_MAPPING_SPARC64_H
|
||||
#define ASAN_MAPPING_SPARC64_H
|
||||
|
||||
// This is tailored to the 52-bit VM layout on SPARC-T4 and later.
|
||||
// The VM space is split into two 51-bit halves at both ends: the low part
|
||||
// has all the bits above the 51st cleared, while the high part has them set.
|
||||
// 0xfff8000000000000 - 0xffffffffffffffff
|
||||
// 0x0000000000000000 - 0x0007ffffffffffff
|
||||
|
||||
#define VMA_BITS 52
|
||||
#define HIGH_BITS (64 - VMA_BITS)
|
||||
|
||||
// The idea is to chop the high bits before doing the scaling, so the two
|
||||
// parts become contiguous again and the usual scheme can be applied.
|
||||
|
||||
#define MEM_TO_SHADOW(mem) \
|
||||
((((mem) << HIGH_BITS) >> (HIGH_BITS + (SHADOW_SCALE))) + (SHADOW_OFFSET))
|
||||
|
||||
#define kLowMemBeg 0
|
||||
#define kLowMemEnd (SHADOW_OFFSET - 1)
|
||||
|
||||
#define kLowShadowBeg SHADOW_OFFSET
|
||||
#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
|
||||
|
||||
// But of course there is the huge hole between the high shadow memory,
|
||||
// which is in the low part, and the beginning of the high part.
|
||||
|
||||
#define kHighMemBeg (-(1ULL << (VMA_BITS - 1)))
|
||||
|
||||
#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
|
||||
#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
|
||||
|
||||
#define kMidShadowBeg 0
|
||||
#define kMidShadowEnd 0
|
||||
|
||||
// With the zero shadow base we can not actually map pages starting from 0.
|
||||
// This constant is somewhat arbitrary.
|
||||
#define kZeroBaseShadowStart 0
|
||||
#define kZeroBaseMaxShadowStart (1 << 18)
|
||||
|
||||
#define kShadowGapBeg (kLowShadowEnd + 1)
|
||||
#define kShadowGapEnd (kHighShadowBeg - 1)
|
||||
|
||||
#define kShadowGap2Beg 0
|
||||
#define kShadowGap2End 0
|
||||
|
||||
#define kShadowGap3Beg 0
|
||||
#define kShadowGap3End 0
|
||||
|
||||
namespace __asan {
|
||||
|
||||
static inline bool AddrIsInLowMem(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return a <= kLowMemEnd;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInLowShadow(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return a >= kLowShadowBeg && a <= kLowShadowEnd;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInMidMem(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInMidShadow(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInHighMem(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInHighShadow(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
|
||||
}
|
||||
|
||||
static inline bool AddrIsInShadowGap(uptr a) {
|
||||
PROFILE_ASAN_MAPPING();
|
||||
return a >= kShadowGapBeg && a <= kShadowGapEnd;
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
#endif // ASAN_MAPPING_SPARC64_H
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_memory_profile.cc.cc -----------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_interceptors.cc ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -72,25 +71,19 @@ enum class align_val_t: size_t {};
|
||||
// TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM.
|
||||
// For local pool allocation, align to SHADOW_GRANULARITY to match asan
|
||||
// allocator behavior.
|
||||
#define OPERATOR_NEW_BODY(type, nothrow) \
|
||||
if (ALLOCATE_FROM_LOCAL_POOL) {\
|
||||
void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size);\
|
||||
if (!nothrow) CHECK(res);\
|
||||
return res;\
|
||||
}\
|
||||
GET_STACK_TRACE_MALLOC;\
|
||||
void *res = asan_memalign(0, size, &stack, type);\
|
||||
if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
|
||||
#define OPERATOR_NEW_BODY(type, nothrow) \
|
||||
MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \
|
||||
GET_STACK_TRACE_MALLOC; \
|
||||
void *res = asan_memalign(0, size, &stack, type); \
|
||||
if (!nothrow && UNLIKELY(!res)) \
|
||||
ReportOutOfMemory(size, &stack); \
|
||||
return res;
|
||||
#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
|
||||
if (ALLOCATE_FROM_LOCAL_POOL) {\
|
||||
void *res = MemalignFromLocalPool((uptr)align, size);\
|
||||
if (!nothrow) CHECK(res);\
|
||||
return res;\
|
||||
}\
|
||||
GET_STACK_TRACE_MALLOC;\
|
||||
void *res = asan_memalign((uptr)align, size, &stack, type);\
|
||||
if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
|
||||
#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
|
||||
MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \
|
||||
GET_STACK_TRACE_MALLOC; \
|
||||
void *res = asan_memalign((uptr)align, size, &stack, type); \
|
||||
if (!nothrow && UNLIKELY(!res)) \
|
||||
ReportOutOfMemory(size, &stack); \
|
||||
return res;
|
||||
|
||||
// On OS X it's not enough to just provide our own 'operator new' and
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_poisoning.cc -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_poisoning.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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,6 +15,7 @@
|
||||
#include "asan_internal.h"
|
||||
#include "asan_mapping.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_platform.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
@ -39,6 +39,10 @@ void PoisonShadowPartialRightRedzone(uptr addr,
|
||||
ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
|
||||
u8 value) {
|
||||
DCHECK(!value || CanPoisonMemory());
|
||||
#if SANITIZER_FUCHSIA
|
||||
__sanitizer_fill_shadow(aligned_beg, aligned_size, value,
|
||||
common_flags()->clear_shadow_mmap_threshold);
|
||||
#else
|
||||
uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);
|
||||
uptr shadow_end = MEM_TO_SHADOW(
|
||||
aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;
|
||||
@ -47,10 +51,6 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
|
||||
// probably provide higher-level interface for these operations.
|
||||
// For now, just memset on Windows.
|
||||
if (value || SANITIZER_WINDOWS == 1 ||
|
||||
// TODO(mcgrathr): Fuchsia doesn't allow the shadow mapping to be
|
||||
// changed at all. It doesn't currently have an efficient means
|
||||
// to zero a bunch of pages, but maybe we should add one.
|
||||
SANITIZER_FUCHSIA == 1 ||
|
||||
// RTEMS doesn't have have pages, let alone a fast way to zero
|
||||
// them, so default to memset.
|
||||
SANITIZER_RTEMS == 1 ||
|
||||
@ -73,6 +73,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
|
||||
ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
|
||||
}
|
||||
}
|
||||
#endif // SANITIZER_FUCHSIA
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_posix.cc -----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_preinit.cc ---------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_premap_shadow.cc ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_report.cc ----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -191,7 +190,7 @@ class ScopedInErrorReport {
|
||||
void ReportError(const ErrorDescription &description) {
|
||||
// Can only report one error per ScopedInErrorReport.
|
||||
CHECK_EQ(current_error_.kind, kErrorKindInvalid);
|
||||
current_error_ = description;
|
||||
internal_memcpy(¤t_error_, &description, sizeof(current_error_));
|
||||
}
|
||||
|
||||
static ErrorDescription &CurrentError() {
|
||||
@ -264,6 +263,13 @@ void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack) {
|
||||
in_report.ReportError(error);
|
||||
}
|
||||
|
||||
void ReportReallocArrayOverflow(uptr count, uptr size,
|
||||
BufferedStackTrace *stack) {
|
||||
ScopedInErrorReport in_report(/*fatal*/ true);
|
||||
ErrorReallocArrayOverflow error(GetCurrentTidOrInvalid(), stack, count, size);
|
||||
in_report.ReportError(error);
|
||||
}
|
||||
|
||||
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack) {
|
||||
ScopedInErrorReport in_report(/*fatal*/ true);
|
||||
ErrorPvallocOverflow error(GetCurrentTidOrInvalid(), stack, size);
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_report.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -62,6 +61,8 @@ void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
|
||||
void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack);
|
||||
void ReportReallocArrayOverflow(uptr count, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack);
|
||||
void ReportInvalidAllocationAlignment(uptr alignment,
|
||||
BufferedStackTrace *stack);
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_rtems.cc -----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -184,8 +183,8 @@ static void ThreadStartHook(void *hook, uptr os_id) {
|
||||
// Determine whether we are starting or restarting the thread.
|
||||
if (status == ThreadStatusCreated)
|
||||
// In lieu of AsanThread::ThreadStart.
|
||||
asanThreadRegistry().StartThread(thread->tid(), os_id,
|
||||
/*workerthread*/ false, nullptr);
|
||||
asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular,
|
||||
nullptr);
|
||||
else {
|
||||
// In a thread restart, a thread may resume execution at an
|
||||
// arbitrary function entry point, with its stack and TLS state
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_rtl.cc -------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -598,6 +597,19 @@ void NOINLINE __asan_handle_no_return() {
|
||||
curr_thread->fake_stack()->HandleNoReturn();
|
||||
}
|
||||
|
||||
extern "C" void *__asan_extra_spill_area() {
|
||||
AsanThread *t = GetCurrentThread();
|
||||
CHECK(t);
|
||||
return t->extra_spill_area();
|
||||
}
|
||||
|
||||
void __asan_handle_vfork(void *sp) {
|
||||
AsanThread *t = GetCurrentThread();
|
||||
CHECK(t);
|
||||
uptr bottom = t->stack_bottom();
|
||||
PoisonShadow(bottom, (uptr)sp - bottom, 0);
|
||||
}
|
||||
|
||||
void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
|
||||
SetUserDieCallback(callback);
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_scariness_score.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_shadow_setup.cc ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_stack.cc -----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -27,8 +26,57 @@ u32 GetMallocContextSize() {
|
||||
return atomic_load(&malloc_context_size, memory_order_acquire);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// ScopedUnwinding is a scope for stacktracing member of a context
|
||||
class ScopedUnwinding {
|
||||
public:
|
||||
explicit ScopedUnwinding(AsanThread *t) : thread(t) {
|
||||
if (thread) {
|
||||
can_unwind = !thread->isUnwinding();
|
||||
thread->setUnwinding(true);
|
||||
}
|
||||
}
|
||||
~ScopedUnwinding() {
|
||||
if (thread)
|
||||
thread->setUnwinding(false);
|
||||
}
|
||||
|
||||
bool CanUnwind() const { return can_unwind; }
|
||||
|
||||
private:
|
||||
AsanThread *thread = nullptr;
|
||||
bool can_unwind = true;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
void __sanitizer::BufferedStackTrace::UnwindImpl(
|
||||
uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
|
||||
using namespace __asan;
|
||||
size = 0;
|
||||
if (UNLIKELY(!asan_inited))
|
||||
return;
|
||||
request_fast = StackTrace::WillUseFastUnwind(request_fast);
|
||||
AsanThread *t = GetCurrentThread();
|
||||
ScopedUnwinding unwind_scope(t);
|
||||
if (!unwind_scope.CanUnwind())
|
||||
return;
|
||||
if (request_fast) {
|
||||
if (t) {
|
||||
Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
|
||||
true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (SANITIZER_MIPS && t &&
|
||||
!IsValidFrame(bp, t->stack_top(), t->stack_bottom()))
|
||||
return;
|
||||
Unwind(max_depth, pc, bp, context, 0, 0, false);
|
||||
}
|
||||
|
||||
// ------------------ Interface -------------- {{{1
|
||||
|
||||
extern "C" {
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_stack.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -27,34 +26,6 @@ static const u32 kDefaultMallocContextSize = 30;
|
||||
void SetMallocContextSize(u32 size);
|
||||
u32 GetMallocContextSize();
|
||||
|
||||
// Get the stack trace with the given pc and bp.
|
||||
// The pc will be in the position 0 of the resulting stack trace.
|
||||
// The bp may refer to the current frame or to the caller's frame.
|
||||
ALWAYS_INLINE
|
||||
void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
|
||||
void *context, bool fast) {
|
||||
#if SANITIZER_WINDOWS
|
||||
stack->Unwind(max_depth, pc, bp, context, 0, 0, fast);
|
||||
#else
|
||||
AsanThread *t;
|
||||
stack->size = 0;
|
||||
if (LIKELY(asan_inited)) {
|
||||
if ((t = GetCurrentThread()) && !t->isUnwinding()) {
|
||||
uptr stack_top = t->stack_top();
|
||||
uptr stack_bottom = t->stack_bottom();
|
||||
ScopedUnwinding unwind_scope(t);
|
||||
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
|
||||
stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom,
|
||||
fast);
|
||||
}
|
||||
} else if (!t && !fast) {
|
||||
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
|
||||
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
|
||||
}
|
||||
}
|
||||
#endif // SANITIZER_WINDOWS
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors
|
||||
@ -71,19 +42,19 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
|
||||
if (max_size > 1) stack.trace_buffer[1] = GET_CALLER_PC(); \
|
||||
} \
|
||||
} else { \
|
||||
GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \
|
||||
GET_CURRENT_FRAME(), 0, fast); \
|
||||
stack.Unwind(StackTrace::GetCurrentPc(), \
|
||||
GET_CURRENT_FRAME(), nullptr, fast, max_size); \
|
||||
}
|
||||
|
||||
#define GET_STACK_TRACE_FATAL(pc, bp) \
|
||||
BufferedStackTrace stack; \
|
||||
GetStackTrace(&stack, kStackTraceMax, pc, bp, 0, \
|
||||
common_flags()->fast_unwind_on_fatal)
|
||||
stack.Unwind(pc, bp, nullptr, \
|
||||
common_flags()->fast_unwind_on_fatal)
|
||||
|
||||
#define GET_STACK_TRACE_SIGNAL(sig) \
|
||||
BufferedStackTrace stack; \
|
||||
GetStackTrace(&stack, kStackTraceMax, (sig).pc, (sig).bp, (sig).context, \
|
||||
common_flags()->fast_unwind_on_fatal)
|
||||
stack.Unwind((sig).pc, (sig).bp, (sig).context, \
|
||||
common_flags()->fast_unwind_on_fatal)
|
||||
|
||||
#define GET_STACK_TRACE_FATAL_HERE \
|
||||
GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_stats.cc -----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_stats.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_suppressions.cc ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_suppressions.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_thread.cc ----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -246,8 +245,7 @@ void AsanThread::Init(const InitOptions *options) {
|
||||
thread_return_t AsanThread::ThreadStart(
|
||||
tid_t os_id, atomic_uintptr_t *signal_thread_is_registered) {
|
||||
Init();
|
||||
asanThreadRegistry().StartThread(tid(), os_id, /*workerthread*/ false,
|
||||
nullptr);
|
||||
asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);
|
||||
if (signal_thread_is_registered)
|
||||
atomic_store(signal_thread_is_registered, 1, memory_order_release);
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_thread.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -131,6 +130,8 @@ class AsanThread {
|
||||
AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
|
||||
AsanStats &stats() { return stats_; }
|
||||
|
||||
void *extra_spill_area() { return &extra_spill_area_; }
|
||||
|
||||
private:
|
||||
// NOTE: There is no AsanThread constructor. It is allocated
|
||||
// via mmap() and *must* be valid in zero-initialized state.
|
||||
@ -166,18 +167,7 @@ class AsanThread {
|
||||
AsanThreadLocalMallocStorage malloc_storage_;
|
||||
AsanStats stats_;
|
||||
bool unwinding_;
|
||||
};
|
||||
|
||||
// ScopedUnwinding is a scope for stacktracing member of a context
|
||||
class ScopedUnwinding {
|
||||
public:
|
||||
explicit ScopedUnwinding(AsanThread *t) : thread(t) {
|
||||
t->setUnwinding(true);
|
||||
}
|
||||
~ScopedUnwinding() { thread->setUnwinding(false); }
|
||||
|
||||
private:
|
||||
AsanThread *thread;
|
||||
uptr extra_spill_area_;
|
||||
};
|
||||
|
||||
// Returns a single instance of registry.
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_win.cc -------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -21,10 +20,10 @@
|
||||
|
||||
#include "asan_interceptors.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_mapping.h"
|
||||
#include "asan_report.h"
|
||||
#include "asan_stack.h"
|
||||
#include "asan_thread.h"
|
||||
#include "asan_mapping.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "sanitizer_common/sanitizer_mutex.h"
|
||||
#include "sanitizer_common/sanitizer_win.h"
|
||||
@ -78,7 +77,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(LPTOP_LEVEL_EXCEPTION_FILTER, SetUnhandledExceptionFilter,
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
|
||||
CHECK(REAL(SetUnhandledExceptionFilter));
|
||||
if (ExceptionFilter == &SEHHandler)
|
||||
return REAL(SetUnhandledExceptionFilter)(ExceptionFilter);
|
||||
@ -105,7 +104,9 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
INTERCEPTOR_WINAPI(int, __C_specific_handler, void *a, void *b, void *c, void *d) { // NOLINT
|
||||
INTERCEPTOR_WINAPI(EXCEPTION_DISPOSITION, __C_specific_handler,
|
||||
_EXCEPTION_RECORD *a, void *b, _CONTEXT *c,
|
||||
_DISPATCHER_CONTEXT *d) { // NOLINT
|
||||
CHECK(REAL(__C_specific_handler));
|
||||
__asan_handle_no_return();
|
||||
return REAL(__C_specific_handler)(a, b, c, d);
|
||||
@ -131,15 +132,14 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
|
||||
#endif
|
||||
|
||||
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
||||
AsanThread *t = (AsanThread*)arg;
|
||||
AsanThread *t = (AsanThread *)arg;
|
||||
SetCurrentThread(t);
|
||||
return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
|
||||
}
|
||||
|
||||
INTERCEPTOR_WINAPI(DWORD, CreateThread,
|
||||
void* security, uptr stack_size,
|
||||
DWORD (__stdcall *start_routine)(void*), void* arg,
|
||||
DWORD thr_flags, void* tid) {
|
||||
INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
|
||||
SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine,
|
||||
void *arg, DWORD thr_flags, DWORD *tid) {
|
||||
// Strict init-order checking is thread-hostile.
|
||||
if (flags()->strict_init_order)
|
||||
StopInitOrderChecking();
|
||||
@ -149,9 +149,9 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread,
|
||||
bool detached = false; // FIXME: how can we determine it on Windows?
|
||||
u32 current_tid = GetCurrentTidOrInvalid();
|
||||
AsanThread *t =
|
||||
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
|
||||
return REAL(CreateThread)(security, stack_size,
|
||||
asan_thread_start, t, thr_flags, tid);
|
||||
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
|
||||
return REAL(CreateThread)(security, stack_size, asan_thread_start, t,
|
||||
thr_flags, tid);
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -162,10 +162,9 @@ void InitializePlatformInterceptors() {
|
||||
// The interceptors were not designed to be removable, so we have to keep this
|
||||
// module alive for the life of the process.
|
||||
HMODULE pinned;
|
||||
CHECK(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_PIN,
|
||||
(LPCWSTR)&InitializePlatformInterceptors,
|
||||
&pinned));
|
||||
CHECK(GetModuleHandleExW(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
|
||||
(LPCWSTR)&InitializePlatformInterceptors, &pinned));
|
||||
|
||||
ASAN_INTERCEPT_FUNC(CreateThread);
|
||||
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
|
||||
@ -197,6 +196,30 @@ static bool tsd_key_inited = false;
|
||||
|
||||
static __declspec(thread) void *fake_tsd = 0;
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winternl/ns-winternl-_teb
|
||||
// "[This structure may be altered in future versions of Windows. Applications
|
||||
// should use the alternate functions listed in this topic.]"
|
||||
typedef struct _TEB {
|
||||
PVOID Reserved1[12];
|
||||
// PVOID ThreadLocalStoragePointer; is here, at the last field in Reserved1.
|
||||
PVOID ProcessEnvironmentBlock;
|
||||
PVOID Reserved2[399];
|
||||
BYTE Reserved3[1952];
|
||||
PVOID TlsSlots[64];
|
||||
BYTE Reserved4[8];
|
||||
PVOID Reserved5[26];
|
||||
PVOID ReservedForOle;
|
||||
PVOID Reserved6[4];
|
||||
PVOID TlsExpansionSlots;
|
||||
} TEB, *PTEB;
|
||||
|
||||
constexpr size_t TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET = 11;
|
||||
BOOL IsTlsInitialized() {
|
||||
PTEB teb = (PTEB)NtCurrentTeb();
|
||||
return teb->Reserved1[TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET] !=
|
||||
nullptr;
|
||||
}
|
||||
|
||||
void AsanTSDInit(void (*destructor)(void *tsd)) {
|
||||
// FIXME: we're ignoring the destructor for now.
|
||||
tsd_key_inited = true;
|
||||
@ -204,7 +227,7 @@ void AsanTSDInit(void (*destructor)(void *tsd)) {
|
||||
|
||||
void *AsanTSDGet() {
|
||||
CHECK(tsd_key_inited);
|
||||
return fake_tsd;
|
||||
return IsTlsInitialized() ? fake_tsd : nullptr;
|
||||
}
|
||||
|
||||
void AsanTSDSet(void *tsd) {
|
||||
@ -212,9 +235,7 @@ void AsanTSDSet(void *tsd) {
|
||||
fake_tsd = tsd;
|
||||
}
|
||||
|
||||
void PlatformTSDDtor(void *tsd) {
|
||||
AsanThread::TSDDtor(tsd);
|
||||
}
|
||||
void PlatformTSDDtor(void *tsd) { AsanThread::TSDDtor(tsd); }
|
||||
// }}}
|
||||
|
||||
// ---------------------- Various stuff ---------------- {{{
|
||||
@ -245,9 +266,7 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void AsanOnDeadlySignal(int, void *siginfo, void *context) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); }
|
||||
|
||||
#if SANITIZER_WINDOWS64
|
||||
// Exception handler for dealing with shadow memory.
|
||||
@ -256,7 +275,9 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
|
||||
uptr page_size = GetPageSizeCached();
|
||||
// Only handle access violations.
|
||||
if (exception_pointers->ExceptionRecord->ExceptionCode !=
|
||||
EXCEPTION_ACCESS_VIOLATION) {
|
||||
EXCEPTION_ACCESS_VIOLATION ||
|
||||
exception_pointers->ExceptionRecord->NumberParameters < 2) {
|
||||
__asan_handle_no_return();
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
@ -265,7 +286,10 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
|
||||
(uptr)(exception_pointers->ExceptionRecord->ExceptionInformation[1]);
|
||||
|
||||
// Check valid shadow range.
|
||||
if (!AddrIsInShadow(addr)) return EXCEPTION_CONTINUE_SEARCH;
|
||||
if (!AddrIsInShadow(addr)) {
|
||||
__asan_handle_no_return();
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// This is an access violation while trying to read from the shadow. Commit
|
||||
// the relevant page and let execution continue.
|
||||
@ -276,7 +300,8 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
|
||||
// Commit the page.
|
||||
uptr result =
|
||||
(uptr)::VirtualAlloc((LPVOID)page, page_size, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (result != page) return EXCEPTION_CONTINUE_SEARCH;
|
||||
if (result != page)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
// The page mapping succeeded, so continue execution as usual.
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
@ -293,7 +318,7 @@ void InitializePlatformExceptionHandlers() {
|
||||
}
|
||||
|
||||
bool IsSystemHeapAddress(uptr addr) {
|
||||
return ::HeapValidate(GetProcessHeap(), 0, (void*)addr) != FALSE;
|
||||
return ::HeapValidate(GetProcessHeap(), 0, (void *)addr) != FALSE;
|
||||
}
|
||||
|
||||
// We want to install our own exception handler (EH) to print helpful reports
|
||||
@ -312,8 +337,7 @@ bool IsSystemHeapAddress(uptr addr) {
|
||||
// asan_dynamic_runtime_thunk.lib to all the modules, thus __asan_set_seh_filter
|
||||
// will be called for each instrumented module. This ensures that at least one
|
||||
// __asan_set_seh_filter call happens after the .exe module CRT is initialized.
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
int __asan_set_seh_filter() {
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE int __asan_set_seh_filter() {
|
||||
// We should only store the previous handler if it's not our own handler in
|
||||
// order to avoid loops in the EH chain.
|
||||
auto prev_seh_handler = SetUnhandledExceptionFilter(SEHHandler);
|
||||
@ -347,14 +371,28 @@ __declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() =
|
||||
// which run before the CRT. Users also add code to .CRT$XLC, so it's important
|
||||
// to run our initializers first.
|
||||
static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) {
|
||||
if (reason == DLL_PROCESS_ATTACH) __asan_init();
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
__asan_init();
|
||||
}
|
||||
|
||||
#pragma section(".CRT$XLAB", long, read) // NOLINT
|
||||
__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
|
||||
unsigned long, void *) = asan_thread_init;
|
||||
__declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
|
||||
void *, unsigned long, void *) = asan_thread_init;
|
||||
#endif
|
||||
|
||||
static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
|
||||
if (reason == DLL_THREAD_DETACH) {
|
||||
// Unpoison the thread's stack because the memory may be re-used.
|
||||
NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
|
||||
uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
|
||||
__asan_unpoison_memory_region(tib->StackLimit, stackSize);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma section(".CRT$XLY", long, read) // NOLINT
|
||||
__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
|
||||
void *, unsigned long, void *) = asan_thread_exit;
|
||||
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
// }}}
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_win_dll_thunk.cc ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_win_dynamic_runtime_thunk.cc ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- asan_win_weak_interception.cc -------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This module should be included in Address Sanitizer when it is implemented as
|
||||
|
@ -1,5 +1,6 @@
|
||||
// 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
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
|
@ -1,29 +1,25 @@
|
||||
/*===-- absvdi2.c - Implement __absvdi2 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __absvdi2 for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- absvdi2.c - Implement __absvdi2 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __absvdi2 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: absolute value */
|
||||
// Returns: absolute value
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
// Effects: aborts if abs(x) < 0
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__absvdi2(di_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(di_int) * CHAR_BIT);
|
||||
if (a == ((di_int)1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const di_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
COMPILER_RT_ABI di_int __absvdi2(di_int a) {
|
||||
const int N = (int)(sizeof(di_int) * CHAR_BIT);
|
||||
if (a == ((di_int)1 << (N - 1)))
|
||||
compilerrt_abort();
|
||||
const di_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
}
|
||||
|
@ -1,29 +1,25 @@
|
||||
/* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __absvsi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- absvsi2.c - Implement __absvsi2 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __absvsi2 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: absolute value */
|
||||
// Returns: absolute value
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
// Effects: aborts if abs(x) < 0
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__absvsi2(si_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(si_int) * CHAR_BIT);
|
||||
if (a == (1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const si_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
COMPILER_RT_ABI si_int __absvsi2(si_int a) {
|
||||
const int N = (int)(sizeof(si_int) * CHAR_BIT);
|
||||
if (a == (1 << (N - 1)))
|
||||
compilerrt_abort();
|
||||
const si_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
}
|
||||
|
@ -1,34 +1,29 @@
|
||||
/* ===-- absvti2.c - Implement __absvdi2 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __absvti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- absvti2.c - Implement __absvdi2 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __absvti2 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: absolute value */
|
||||
// Returns: absolute value
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
// Effects: aborts if abs(x) < 0
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__absvti2(ti_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
|
||||
if (a == ((ti_int)1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const ti_int s = a >> (N - 1);
|
||||
return (a ^ s) - s;
|
||||
COMPILER_RT_ABI ti_int __absvti2(ti_int a) {
|
||||
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
|
||||
if (a == ((ti_int)1 << (N - 1)))
|
||||
compilerrt_abort();
|
||||
const ti_int s = a >> (N - 1);
|
||||
return (a ^ s) - s;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
||||
#endif // CRT_HAS_128BIT
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- lib/adddf3.c - Double-precision addition ------------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -15,16 +14,12 @@
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_add_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI double __adddf3(double a, double b){
|
||||
return __addXf3__(a, b);
|
||||
}
|
||||
COMPILER_RT_ABI double __adddf3(double a, double b) { return __addXf3__(a, b); }
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI double __aeabi_dadd(double a, double b) {
|
||||
return __adddf3(a, b);
|
||||
}
|
||||
AEABI_RTABI double __aeabi_dadd(double a, double b) { return __adddf3(a, b); }
|
||||
#else
|
||||
AEABI_RTABI double __aeabi_dadd(double a, double b) COMPILER_RT_ALIAS(__adddf3);
|
||||
COMPILER_RT_ALIAS(__adddf3, __aeabi_dadd)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- lib/addsf3.c - Single-precision addition ------------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -15,16 +14,12 @@
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_add_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI float __addsf3(float a, float b) {
|
||||
return __addXf3__(a, b);
|
||||
}
|
||||
COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); }
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI float __aeabi_fadd(float a, float b) {
|
||||
return __addsf3(a, b);
|
||||
}
|
||||
AEABI_RTABI float __aeabi_fadd(float a, float b) { return __addsf3(a, b); }
|
||||
#else
|
||||
AEABI_RTABI float __aeabi_fadd(float a, float b) COMPILER_RT_ALIAS(__addsf3);
|
||||
COMPILER_RT_ALIAS(__addsf3, __aeabi_fadd)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- lib/addtf3.c - Quad-precision addition --------------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@ -18,8 +17,8 @@
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
#include "fp_add_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __addtf3(long double a, long double b){
|
||||
return __addXf3__(a, b);
|
||||
COMPILER_RT_ABI long double __addtf3(long double a, long double b) {
|
||||
return __addXf3__(a, b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,36 +1,29 @@
|
||||
/* ===-- addvdi3.c - Implement __addvdi3 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __addvdi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- addvdi3.c - Implement __addvdi3 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __addvdi3 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: a + b */
|
||||
// Returns: a + b
|
||||
|
||||
/* Effects: aborts if a + b overflows */
|
||||
// Effects: aborts if a + b overflows
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__addvdi3(di_int a, di_int b)
|
||||
{
|
||||
di_int s = (du_int) a + (du_int) b;
|
||||
if (b >= 0)
|
||||
{
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
COMPILER_RT_ABI di_int __addvdi3(di_int a, di_int b) {
|
||||
di_int s = (du_int)a + (du_int)b;
|
||||
if (b >= 0) {
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
} else {
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -1,36 +1,29 @@
|
||||
/* ===-- addvsi3.c - Implement __addvsi3 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __addvsi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- addvsi3.c - Implement __addvsi3 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __addvsi3 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: a + b */
|
||||
// Returns: a + b
|
||||
|
||||
/* Effects: aborts if a + b overflows */
|
||||
// Effects: aborts if a + b overflows
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__addvsi3(si_int a, si_int b)
|
||||
{
|
||||
si_int s = (su_int) a + (su_int) b;
|
||||
if (b >= 0)
|
||||
{
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
COMPILER_RT_ABI si_int __addvsi3(si_int a, si_int b) {
|
||||
si_int s = (su_int)a + (su_int)b;
|
||||
if (b >= 0) {
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
} else {
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -1,40 +1,33 @@
|
||||
/* ===-- addvti3.c - Implement __addvti3 -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __addvti3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- addvti3.c - Implement __addvti3 -----------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements __addvti3 for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: a + b */
|
||||
// Returns: a + b
|
||||
|
||||
/* Effects: aborts if a + b overflows */
|
||||
// Effects: aborts if a + b overflows
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__addvti3(ti_int a, ti_int b)
|
||||
{
|
||||
ti_int s = (tu_int) a + (tu_int) b;
|
||||
if (b >= 0)
|
||||
{
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
COMPILER_RT_ABI ti_int __addvti3(ti_int a, ti_int b) {
|
||||
ti_int s = (tu_int)a + (tu_int)b;
|
||||
if (b >= 0) {
|
||||
if (s < a)
|
||||
compilerrt_abort();
|
||||
} else {
|
||||
if (s >= a)
|
||||
compilerrt_abort();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
#endif // CRT_HAS_128BIT
|
||||
|
@ -1,47 +1,42 @@
|
||||
/* ===-- apple_versioning.c - Adds versioning symbols for ld ---------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
//===-- apple_versioning.c - Adds versioning symbols for ld ---------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if __APPLE__
|
||||
#include <Availability.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#define NOT_HERE_BEFORE_10_6(sym)
|
||||
#define NOT_HERE_IN_10_8_AND_EARLIER(sym) \
|
||||
extern const char sym##_tmp61 __asm("$ld$hide$os6.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp61 = 0; \
|
||||
extern const char sym##_tmp60 __asm("$ld$hide$os6.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp60 = 0; \
|
||||
extern const char sym##_tmp51 __asm("$ld$hide$os5.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp51 = 0; \
|
||||
extern const char sym##_tmp50 __asm("$ld$hide$os5.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp50 = 0;
|
||||
#else
|
||||
#define NOT_HERE_BEFORE_10_6(sym) \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0;
|
||||
#define NOT_HERE_IN_10_8_AND_EARLIER(sym) \
|
||||
extern const char sym##_tmp8 __asm("$ld$hide$os10.8$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp8 = 0; \
|
||||
extern const char sym##_tmp7 __asm("$ld$hide$os10.7$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp7 = 0; \
|
||||
extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp6 = 0;
|
||||
#endif
|
||||
#include <Availability.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#define NOT_HERE_BEFORE_10_6(sym)
|
||||
#define NOT_HERE_IN_10_8_AND_EARLIER(sym) \
|
||||
extern const char sym##_tmp61 __asm("$ld$hide$os6.1$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp61 = 0; \
|
||||
extern const char sym##_tmp60 __asm("$ld$hide$os6.0$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp60 = 0; \
|
||||
extern const char sym##_tmp51 __asm("$ld$hide$os5.1$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp51 = 0; \
|
||||
extern const char sym##_tmp50 __asm("$ld$hide$os5.0$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp50 = 0;
|
||||
#else
|
||||
#define NOT_HERE_BEFORE_10_6(sym) \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0;
|
||||
#define NOT_HERE_IN_10_8_AND_EARLIER(sym) \
|
||||
extern const char sym##_tmp8 __asm("$ld$hide$os10.8$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp8 = 0; \
|
||||
extern const char sym##_tmp7 __asm("$ld$hide$os10.7$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp7 = 0; \
|
||||
extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp6 = 0;
|
||||
#endif
|
||||
|
||||
/* Symbols in libSystem.dylib in 10.6 and later,
|
||||
* but are in libgcc_s.dylib in earlier versions
|
||||
*/
|
||||
// Symbols in libSystem.dylib in 10.6 and later,
|
||||
// but are in libgcc_s.dylib in earlier versions
|
||||
|
||||
NOT_HERE_BEFORE_10_6(__absvdi2)
|
||||
NOT_HERE_BEFORE_10_6(__absvsi2)
|
||||
@ -143,14 +138,13 @@ NOT_HERE_BEFORE_10_6(__udivti3)
|
||||
NOT_HERE_BEFORE_10_6(__umoddi3)
|
||||
NOT_HERE_BEFORE_10_6(__umodti3)
|
||||
|
||||
|
||||
#if __ppc__
|
||||
NOT_HERE_BEFORE_10_6(__gcc_qadd)
|
||||
NOT_HERE_BEFORE_10_6(__gcc_qdiv)
|
||||
NOT_HERE_BEFORE_10_6(__gcc_qmul)
|
||||
NOT_HERE_BEFORE_10_6(__gcc_qsub)
|
||||
NOT_HERE_BEFORE_10_6(__trampoline_setup)
|
||||
#endif /* __ppc__ */
|
||||
#endif // __ppc__
|
||||
|
||||
NOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange)
|
||||
NOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange_1)
|
||||
@ -201,24 +195,23 @@ NOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_2)
|
||||
NOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_4)
|
||||
NOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_8)
|
||||
|
||||
|
||||
#if __arm__ && __DYNAMIC__
|
||||
#define NOT_HERE_UNTIL_AFTER_4_3(sym) \
|
||||
extern const char sym##_tmp1 __asm("$ld$hide$os3.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp1 = 0; \
|
||||
extern const char sym##_tmp2 __asm("$ld$hide$os3.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp2 = 0; \
|
||||
extern const char sym##_tmp3 __asm("$ld$hide$os3.2$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os4.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os4.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
|
||||
extern const char sym##_tmp6 __asm("$ld$hide$os4.2$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp6 = 0; \
|
||||
extern const char sym##_tmp7 __asm("$ld$hide$os4.3$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp7 = 0;
|
||||
|
||||
#define NOT_HERE_UNTIL_AFTER_4_3(sym) \
|
||||
extern const char sym##_tmp1 __asm("$ld$hide$os3.0$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp1 = 0; \
|
||||
extern const char sym##_tmp2 __asm("$ld$hide$os3.1$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp2 = 0; \
|
||||
extern const char sym##_tmp3 __asm("$ld$hide$os3.2$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os4.0$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os4.1$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
|
||||
extern const char sym##_tmp6 __asm("$ld$hide$os4.2$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp6 = 0; \
|
||||
extern const char sym##_tmp7 __asm("$ld$hide$os4.3$_" #sym); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp7 = 0;
|
||||
|
||||
NOT_HERE_UNTIL_AFTER_4_3(__absvdi2)
|
||||
NOT_HERE_UNTIL_AFTER_4_3(__absvsi2)
|
||||
NOT_HERE_UNTIL_AFTER_4_3(__adddf3)
|
||||
@ -339,12 +332,8 @@ NOT_HERE_UNTIL_AFTER_4_3(__divmodsi4)
|
||||
NOT_HERE_UNTIL_AFTER_4_3(__udivmodsi4)
|
||||
#endif // __arm__ && __DYNAMIC__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else /* !__APPLE__ */
|
||||
#else // !__APPLE__
|
||||
|
||||
extern int avoid_empty_file;
|
||||
|
||||
#endif /* !__APPLE__*/
|
||||
#endif // !__APPLE__
|
||||
|
@ -1,20 +1,18 @@
|
||||
//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// double __adddf3vfp(double a, double b) { return a + b; }
|
||||
//
|
||||
// Adds two double precision floating point numbers using the Darwin
|
||||
// calling convention where double arguments are passsed in GPR pairs
|
||||
//
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
@ -23,7 +21,7 @@ DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
#else
|
||||
vmov d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
vmov d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
vadd.f64 d6, d6, d7
|
||||
vadd.f64 d6, d6, d7
|
||||
vmov r0, r1, d6 // move result back to r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
|
@ -1,17 +1,16 @@
|
||||
/*===-- addsf3.S - Adds two single precision floating pointer numbers-----===//
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===//
|
||||
*
|
||||
* This file implements the __addsf3 (single precision floating pointer number
|
||||
* addition with the IEEE-754 default rounding (to nearest, ties to even)
|
||||
* function for the ARM Thumb1 ISA.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
//===-- addsf3.S - Adds two single precision floating pointer numbers-----===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the __addsf3 (single precision floating pointer number
|
||||
// addition with the IEEE-754 default rounding (to nearest, ties to even)
|
||||
// function for the ARM Thumb1 ISA.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
#define significandBits 23
|
||||
@ -29,9 +28,9 @@ DEFINE_COMPILERRT_THUMB_FUNCTION(__addsf3)
|
||||
// Get the absolute value of a and b.
|
||||
lsls r2, r0, #1
|
||||
lsls r3, r1, #1
|
||||
lsrs r2, r2, #1 /* aAbs */
|
||||
lsrs r2, r2, #1 // aAbs
|
||||
beq LOCAL_LABEL(a_zero_nan_inf)
|
||||
lsrs r3, r3, #1 /* bAbs */
|
||||
lsrs r3, r3, #1 // bAbs
|
||||
beq LOCAL_LABEL(zero_nan_inf)
|
||||
|
||||
// Detect if a or b is infinity or Nan.
|
||||
@ -55,9 +54,9 @@ LOCAL_LABEL(no_swap):
|
||||
|
||||
// Get the significands and shift them to give us round, guard and sticky.
|
||||
lsls r4, r0, #(typeWidth - significandBits)
|
||||
lsrs r4, r4, #(typeWidth - significandBits - 3) /* aSignificand << 3 */
|
||||
lsrs r4, r4, #(typeWidth - significandBits - 3) // aSignificand << 3
|
||||
lsls r5, r1, #(typeWidth - significandBits)
|
||||
lsrs r5, r5, #(typeWidth - significandBits - 3) /* bSignificand << 3 */
|
||||
lsrs r5, r5, #(typeWidth - significandBits - 3) // bSignificand << 3
|
||||
|
||||
// Get the implicitBit.
|
||||
movs r6, #1
|
||||
@ -199,7 +198,7 @@ LOCAL_LABEL(do_substraction):
|
||||
beq 1f
|
||||
movs r7, #1
|
||||
1:
|
||||
lsrs r4, r6 /* aSignificand >> shift */
|
||||
lsrs r4, r6 // aSignificand >> shift
|
||||
orrs r4, r7
|
||||
b LOCAL_LABEL(form_result)
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- aeabi_cdcmp.S - EABI cdcmp* implementation ------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
//===-- lib/arm/aeabi_cdcmpeq_helper.c - Helper for cdcmpeq ---------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../int_lib.h"
|
||||
#include <stdint.h>
|
||||
|
||||
AEABI_RTABI __attribute__((visibility("hidden")))
|
||||
int __aeabi_cdcmpeq_check_nan(double a, double b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
AEABI_RTABI __attribute__((visibility("hidden"))) int
|
||||
__aeabi_cdcmpeq_check_nan(double a, double b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- aeabi_cfcmp.S - EABI cfcmp* implementation ------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
//===-- lib/arm/aeabi_cfcmpeq_helper.c - Helper for cdcmpeq ---------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../int_lib.h"
|
||||
#include <stdint.h>
|
||||
|
||||
AEABI_RTABI __attribute__((visibility("hidden")))
|
||||
int __aeabi_cfcmpeq_check_nan(float a, float b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
AEABI_RTABI __attribute__((visibility("hidden"))) int
|
||||
__aeabi_cfcmpeq_check_nan(float a, float b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
//===-- aeabi_dcmp.S - EABI dcmp* implementation ---------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -1,34 +1,30 @@
|
||||
/* ===-- aeabi_div0.c - ARM Runtime ABI support routines for compiler-rt ---===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements the division by zero helper routines as specified by the
|
||||
* Run-time ABI for the ARM Architecture.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
//===-- aeabi_div0.c - ARM Runtime ABI support routines for compiler-rt ---===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the division by zero helper routines as specified by the
|
||||
// Run-time ABI for the ARM Architecture.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/*
|
||||
* RTABI 4.3.2 - Division by zero
|
||||
*
|
||||
* The *div0 functions:
|
||||
* - Return the value passed to them as a parameter
|
||||
* - Or, return a fixed value defined by the execution environment (such as 0)
|
||||
* - Or, raise a signal (often SIGFPE) or throw an exception, and do not return
|
||||
*
|
||||
* An application may provide its own implementations of the *div0 functions to
|
||||
* for a particular behaviour from the *div and *divmod functions called out of
|
||||
* line.
|
||||
*/
|
||||
// RTABI 4.3.2 - Division by zero
|
||||
//
|
||||
// The *div0 functions:
|
||||
// - Return the value passed to them as a parameter
|
||||
// - Or, return a fixed value defined by the execution environment (such as 0)
|
||||
// - Or, raise a signal (often SIGFPE) or throw an exception, and do not return
|
||||
//
|
||||
// An application may provide its own implementations of the *div0 functions to
|
||||
// for a particular behaviour from the *div and *divmod functions called out of
|
||||
// line.
|
||||
|
||||
#include "../int_lib.h"
|
||||
|
||||
/* provide an unused declaration to pacify pendantic compilation */
|
||||
// provide an unused declaration to pacify pendantic compilation
|
||||
extern unsigned char declaration;
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
@ -37,9 +33,8 @@ __aeabi_idiv0(int return_value) {
|
||||
return return_value;
|
||||
}
|
||||
|
||||
AEABI_RTABI long long __attribute__((weak)) __attribute__((visibility("hidden")))
|
||||
__aeabi_ldiv0(long long return_value) {
|
||||
AEABI_RTABI long long __attribute__((weak))
|
||||
__attribute__((visibility("hidden"))) __aeabi_ldiv0(long long return_value) {
|
||||
return return_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user